1.抓取索引页内容

利用requests请求目标站点,得到索引网页HTML代码,返回结果。

2.抓取详情页内容

解析返回结果,得到详情页的链接,并进一步抓取详情页的信息。

3.下载图片与保存数据库

将图片下载到本地,并把页面信息及图片URL保存到MongDB。

4.开启循环及多线程

对多页内容遍历,开启多线程提高抓取速度。

1.抓取索引页

  1. from urllib.parse import urlencode
  2. from requests.exceptions import RequestException
  3. import requests
  4. def get_page_index(offset, keyword):
  5. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  6. data = {
  7. 'format': 'json',
  8. 'offset': offset,
  9. 'keyword': keyword,
  10. 'autoload': 'true',
  11. 'count': 20,
  12. 'cur_tab': 1,
  13. 'from': 'search_tab',
  14. 'pd': 'synthesis',
  15. }
  16. url = 'https://www.toutiao.com/search_content/?' + urlencode(data)
  17. response = requests.get(url, headers=headers);
  18. try:
  19. if response.status_code == 200:
  20. return response.text
  21. return None
  22. except RequestException:
  23. print('请求索引页失败')
  24. return None
  25. def main():
  26. html = get_page_index(0,'街拍')
  27. print(html)
  28. if __name__=='__main__':
  29. main()

2.抓取详情页内容

获取页面网址:

  1. def parse_page_index(html):
  2. data = json.loads(html)
  3. if data and 'data' in data.keys():
  4. for item in data.get('data'):
  5. yield item.get('article_url')

单个页面代码:

  1. def get_page_detail(url):
  2. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  3. try:
  4. response = requests.get(url, headers=headers)
  5. if response.status_code == 200:
  6. return response.text
  7. return None
  8. except RequestException:
  9. print('请求详情页页失败')
  10. return None

图片地址

  1. def parse_page_detail(html,url):
  2. soup = BeautifulSoup(html,'lxml')
  3. title = soup.select('title')[0].get_text()
  4. images_pattern = re.compile('gallery: JSON.parse\((.*?)\)', re.S)
  5. result = re.search(images_pattern, html)
  6. if result:
  7. data = json.loads(result.group(1))
  8. data = json.loads(data) #将字符串转为dict,因为报错了
  9. if data and 'sub_images' in data.keys():
  10. sub_images = data.get('sub_images')
  11. images = [item.get('url') for item in sub_images]
  12. for image in images: download_image(image)
  13. return {
  14. 'title': title,
  15. 'images':images,
  16. 'url':url
  17. }

3.下载图片与保存数据库

  1. # 存到数据库
  2. def save_to_mongo(result):
  3. if db[MONGO_TABLE].insert(result):
  4. print('存储到MongoDb成功', result)
  5. return True
  6. return False
  7. # 下载图片
  8. def download_image(url):
  9. print('正在下载',url)
  10. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537. 36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  11. try:
  12. response = requests.get(url, headers=headers)
  13. if response.status_code == 200:
  14. save_image(response.content)
  15. return None
  16. except RequestException:
  17. print('请求图片失败', url)
  18. return None
  19. def save_image(content):
  20. file_path = '{0}/{1}.{2}'.format(os.getcwd(),md5(content).hexdigest(),'jpg')
  21. if not os.path.exists(file_path):
  22. with open(file_path,'wb') as f:
  23. f.write(content)

4.开启循环及多线程

  1. groups = [x*20 for x in range(GROUP_START, GROUP_END+1)]
  2. pool = Pool()
  3. pool.map(main,groups)

完整代码:spider.py

  1. from urllib.parse import urlencode
  2. from requests.exceptions import RequestException
  3. from bs4 import BeautifulSoup
  4. from hashlib import md5
  5. from multiprocessing import Pool
  6. from config import *
  7. import pymongo
  8. import requests
  9. import json
  10. import re
  11. import os
  12. client = pymongo.MongoClient(MONGO_URL)
  13. db = client[MONGO_DB]
  14. def get_page_index(offset, keyword):
  15. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  16. data = { 'format': 'json','offset': offset,'keyword': keyword,'autoload': 'true','count': 20,'cur_tab': 1,'from': 'search_tab','pd': 'synthesis' }
  17. url = 'https://www.toutiao.com/search_content/?' + urlencode(data)
  18. try:
  19. response = requests.get(url, headers=headers)
  20. if response.status_code == 200:
  21. return response.text
  22. return None
  23. except RequestException:
  24. print('请求索引页失败')
  25. return None
  26. def parse_page_index(html):
  27. data = json.loads(html)
  28. if data and 'data' in data.keys():
  29. for item in data.get('data'):
  30. yield item.get('article_url')
  31. def get_page_detail(url):
  32. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  33. try:
  34. response = requests.get(url, headers=headers)
  35. if response.status_code == 200:
  36. return response.text
  37. return None
  38. except RequestException:
  39. print('请求详情页页失败')
  40. return None
  41. def parse_page_detail(html,url):
  42. soup = BeautifulSoup(html,'lxml')
  43. title = soup.select('title')[0].get_text()
  44. images_pattern = re.compile('gallery: JSON.parse\((.*?)\)', re.S)
  45. result = re.search(images_pattern, html)
  46. if result:
  47. data = json.loads(result.group(1))
  48. data = json.loads(data) #将字符串转为dict,因为报错了
  49. if data and 'sub_images' in data.keys():
  50. sub_images = data.get('sub_images')
  51. images = [item.get('url') for item in sub_images]
  52. for image in images: download_image(image)
  53. return {
  54. 'title': title,
  55. 'images':images,
  56. 'url':url
  57. }
  58. def save_to_mongo(result):
  59. if db[MONGO_TABLE].insert(result):
  60. print('存储到MongoDb成功', result)
  61. return True
  62. return False
  63. def download_image(url):
  64. print('正在下载',url)
  65. headers = { 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537. 36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' }
  66. try:
  67. response = requests.get(url, headers=headers)
  68. if response.status_code == 200:
  69. save_image(response.content)
  70. return None
  71. except RequestException:
  72. print('请求图片失败', url)
  73. return None
  74. def save_image(content):
  75. file_path = '{0}/{1}.{2}'.format(os.getcwd(),md5(content).hexdigest(),'jpg')
  76. if not os.path.exists(file_path):
  77. with open(file_path,'wb') as f:
  78. f.write(content)
  79. def main(offset):
  80. html = get_page_index(offset,KEYWORD)
  81. for url in parse_page_index(html):
  82. html = get_page_detail(url)
  83. if html:
  84. result = parse_page_detail(html,url)
  85. if isinstance(result,dict):
  86. save_to_mongo(result)
  87. if __name__=='__main__':
  88. groups = [x*20 for x in range(GROUP_START, GROUP_END+1)]
  89. pool = Pool()
  90. pool.map(main,groups)

config.py

  1. MONGO_URL = 'localhost'
  2. MONGO_DB = 'toutiao'
  3. MONGO_TABLE = 'jiepai'
  4. GROUP_START = 1
  5. GROUP_END = 20
  6. KEYWORD = '街拍'
  7. ~

Python爬虫系列-分析Ajax请求并抓取今日头条街拍图片的更多相关文章

  1. 【Python爬虫案例学习】分析Ajax请求并抓取今日头条街拍图片

    1.抓取索引页内容 利用requests请求目标站点,得到索引网页HTML代码,返回结果. from urllib.parse import urlencode from requests.excep ...

  2. 分析Ajax请求并抓取今日头条街拍美图

    项目说明 本项目以今日头条为例,通过分析Ajax请求来抓取网页数据. 有些网页请求得到的HTML代码里面并没有我们在浏览器中看到的内容.这是因为这些信息是通过Ajax加载并且通过JavaScript渲 ...

  3. 分析 ajax 请求并抓取今日头条街拍美图

    首先分析街拍图集的网页请求头部: 在 preview 选项卡我们可以找到 json 文件,分析 data 选项,找到我们要找到的图集地址 article_url: 选中其中一张图片,分析 json 请 ...

  4. 2.分析Ajax请求并抓取今日头条街拍美图

    import requests from urllib.parse import urlencode # 引入异常类 from requests.exceptions import RequestEx ...

  5. python爬虫知识点总结(十)分析Ajax请求并抓取今日头条街拍美图

    一.流程框架

  6. 15-分析Ajax请求并抓取今日头条街拍美图

    流程框架: 抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码,返回结果. 抓取详情页内容:解析返回结果,得到详情页的链接,并进一步抓取详情页的信息. 下载图片与保存数据库:将 ...

  7. 分析 ajax 请求并抓取 “今日头条的街拍图”

    今日头条抓取页面: 分析街拍页面的 ajax 请求: 通过在 XHR 中查看内容,获取 url 链接,params 参数信息,将两者进行拼接后取得完整 url 地址.data 中的 article_u ...

  8. python爬虫之分析Ajax请求抓取抓取今日头条街拍美图(七)

    python爬虫之分析Ajax请求抓取抓取今日头条街拍美图 一.分析网站 1.进入浏览器,搜索今日头条,在搜索栏搜索街拍,然后选择图集这一栏. 2.按F12打开开发者工具,刷新网页,这时网页回弹到综合 ...

  9. PYTHON 爬虫笔记九:利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集(实战项目二)

    利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集 目标站点分析 今日头条这类的网站制作,从数据形式,CSS样式都是通过数据接口的样式来决定的,所以它的抓取方法和其他网页的抓取方 ...

随机推荐

  1. Vue中登录模块

  2. shell中变量内容的删除,替代

    删除 ${varname#strMatch} // 在varname中从头匹配strMatch,然后删除从头到第一次匹配到的位置 ${varname##strMatch} // 在varname中从头 ...

  3. Linux —— gcc编译文件

    编译过程 预处理: 作用: 负责展开在源文件重定义的宏 操作: g++ -E 源文件.c -o 目标文件.i 汇编: 作用: 将目标文件生成汇编代码文件 操作: g++ -S 目标文件.i -o 汇编 ...

  4. UVa1471

    保留有价值的数字的做法,实际上这道题因为n只有1e5,所以不需要这种优化. #include<bits/stdc++.h> #define inf 0x3f3f3f3f ; using n ...

  5. NET Core 2.1 Preview 1

    NET Core 2.1 Preview 1 [翻译] .NET Core 2.1 Preview 1 发布 原文: Announcing .NET Core 2.1 Preview 1 今天,我们宣 ...

  6. NET Core应用中实现与第三方IoC/DI框架的整合?

    NET Core应用中实现与第三方IoC/DI框架的整合? 我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供 ...

  7. 062 Unique Paths 不同路径

    机器人位于一个 m x n 网格的左上角, 在下图中标记为“Start” (开始).机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角,在下图中标记为“Finish”(结束).问有多少条不 ...

  8. IO扩展芯片

    PCF8574:一个I2C接口+INT中断引脚口扩展出一个可输出输出的并口P0~P7,INT可以用于中断响应

  9. HDU 1027 G - Can you answer these queries?

    http://acm.hdu.edu.cn/showproblem.php?pid=4027 Can you answer these queries? Time Limit: 4000/2000 M ...

  10. java join 方法的使用

    在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据 ...