分析Ajax抓取今日头条街拍美图
声明:此篇文章主要是观看静觅教学视频后做的笔记,原教程地址https://cuiqingcai.com/
实现流程介绍
1.抓取索引页内容:利用requests请求目标站点,得到索引网页HTML代码,返回结果
2.抓取详情页内容:解析返回结果,得到详情页的链接,并进一步抓取详情页信息
3.下载图片与保存数据库:将图片下载到本地,并把页面信息及图片URL保存至MongoDB
4.开启循环及多线程:对多页内容遍历,开启多线程提高抓取速度
具体实现
1. 首先访问今日头条网站输入关键字来到索引页,我们需要通过分析网站来拿到进入详细页的url
经过观察可以发现每次滑动鼠标滚轮,新的标题链接就会被显示,所以可以发现其后台为Ajax请求,通过浏览器Network选项卡的XHR可以找到Ajax的链接,其为一个json数据,以搜索词街拍为例,其链接地址如下:
https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E8%A1%97%E6%8B%8D&autoload=true&count=20&cur_tab=1&from=search_tab
2.通过点击查看Query String Parameters中的内容,可以看到一些类似字典的数据,所以这是一会需要通过urlencode来转码拼接成最终访问的地址
offset: 0
format: json
keyword: 街拍
autoload: true
count: 20
cur_tab: 1
from: search_tab
3.随着向下滑动滚动条显示更多的图片索引,会发现刷出了很多新的ajax请求,通过这个我们可以知道我们之后可以通过改变offset参数来获取不同的拿到不同的索引界面,从而获得不同的图集详细页url。开始只需实现一个offset参数的爬取,最后通过进程池Pool来创建实现多进程爬取不同offset参数的URL,加快爬取速度
4.接下来就是分析查找图集详细页的代码,来找到图片的url,这个图片url隐藏的比较深,都在JS代码中,所以不能使用BeautifulSoup和PyQuery来解析了,只能通过正则解析,使用正则解析要注意匹配规则一定要写对。刷新页面后,自己基础比较差,找了好久换了火狐浏览器,又换回谷歌,最后在Network选项卡的Doc发现下面这个链接,而图片地址就藏在gallery: JSON.parse里
https://www.toutiao.com/a6585311263927042573/
5.代码实现
代码直接进行展示吧,需要的注释我已经写在代码里了,先编辑一个config.py的文件,里面设置了代码中用到的变量
MONGO_URL = 'localhost'
MONGO_DB = 'toutiao'
MONGO_TABLE = 'toutiao'GROUP_START = 1
GROUP_END = 20
KEYWORD='街拍'
#!/usr/bin/env python
# coding=utf-8from urllib.parse import urlencode
from requests.exceptions import ConnectionError
from bs4 import BeautifulSoup
from json.decoder import JSONDecodeError
from hashlib import md5
from config import *
from multiprocessing import Pool
import requests
import json
import re
import os
import pymongoclient = pymongo.MongoClient(MONGO_URL, connect=False)
db = client[MONGO_DB]def get_page_index(url, headers):"""作用:返回页面源码url:请求地址headers:请求头信息"""try:response = requests.get(url, headers=headers)# 判断是否访问成功if response.status_code == 200:return response.textexcept ConnectionError:print('Erroe occured')return Nonedef parse_page_index(html):"""作用:解析出标题URL地址html:网页源码"""try:# 将数据转为json格式data = json.loads(html)# print(data)# 判断data是否为空,以及data字典中是否有data这个键if data and 'data' in data.keys():for item in data.get('data'):if item.get('article_url'):yield item.get('article_url')except JSONDecodeError:passdef get_page_detail(url, headers):"""作用:返回标题URL网页源码url:标题URL地址headers:请求头信息"""try:response = requests.get(url, headers=headers)# 判断是否访问成功if response.status_code == 200:return response.textexcept ConnectionError:print('Error occured')return Nonedef parse_page_detail(html, url):"""作用:解析标题URL地址的每个图片链接html:标题URL网页源码url:标题URL地址"""# 利用BeautifulSoup找到title的文本soup = BeautifulSoup(html, 'lxml') title = soup.title.text# 利用正则找到每个下载图片的地址images_pattern = re.compile('gallery: JSON.parse\("(.*)"\)', re.S)result = images_pattern.search(html)# print(result)if result:data = json.loads(result.group(1).replace('\\', ''))# 提取出sub_images键的键值if data and 'sub_images' in data.keys():sub_images = data.get('sub_images')# 使用列表生成式拿到每个图片URLimages = [item.get('url') for item in sub_images]for image in images: # 下载图片download_image(image)# 将return的结果保存至MongoDB中return {'title': title,'url': url,'images': images}def download_image(url):"""作用:返回图片URL源码url:图片URL地址"""print('Downloading', url)try:response = requests.get(url)# 判断是否访问成功if response.status_code == 200:save_image(response.content)return Noneexcept ConnectionError:return Nonedef save_image(content):"""作用:保存图像文件content:图像二进制数据"""# 使用md5加密内容,生成图像名称file_path = '{0}/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg')print(file_path)# 判断该文件名是否存在if not os.path.exists(file_path):with open(file_path, 'wb') as f:f.write(content)f.close()def save_to_mongo(result):"""作用:保存数据至MongoDB数据库result:包括图片标题,请求地址,图像地址"""if db[MONGO_TABLE].insert(result):print('Successfully Saved to Mongo', result)return Truereturn Falsedef jiepai_Spider(offset):"""作用:整个爬虫调度器offset:位置参数"""headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}data = {"offset": offset,"format": "json","keyword": "街拍","autoload": "true","count": "20","cur_tab": "1","from": "search_tab"}# 通过urlencode构造请求URLurl = 'https://www.toutiao.com/search_content/' + '?' + urlencode(data)# 测试url# print(url)# 获取页面源码html = get_page_index(url, headers)# 解析HTML,获得链接地址for url in parse_page_index(html):# print(url)# 获得每个链接地址的HTMLhtml = get_page_detail(url, headers)result = parse_page_detail(html, url)# 判断result是否为空,保存至MongoDB数据库中if result: save_to_mongo(result)if __name__ == "__main__":# 创建进程池pool = Pool()groups = ([x * 20 for x in range(GROUP_START, GROUP_END + 1)])pool.map(jiepai_Spider, groups)pool.close()# 等待pool中所有子进程执行完成,必须放在close语句之后pool.join()
总结思考
1.在利用正则进行匹配的时候如果原文有‘(“ ”)',这类符号时那么你在进行正则表达式书写的时候应该在前面加'\'。按理应该也可以使用原始字符串r,可是我用完最后在匹配的时候返回的是None,留个疑问
pattern = re.compile('gallery: JSON\.parse\("(.*?)"\),', re.S)
2. db = client[MONGO_DB]这里应该是方括号而不是 ( ),否则无法正常访问数据库
3. 在Google浏览器中找不到图片url,然后使用的是火狐浏览器来回查看
4.完整源码地址:https://github.com/XiaoFei-97/toutiao_Spider-Ajax
分析Ajax抓取今日头条街拍美图相关推荐
- [Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图
[Python3网络爬虫开发实战] --分析Ajax爬取今日头条街拍美图 学习笔记--爬取今日头条街拍美图 准备工作 抓取分析 实战演练 学习笔记–爬取今日头条街拍美图 尝试通过分析Ajax请求来抓取 ...
- python爬取今日头条_Python3网络爬虫实战-36、分析Ajax爬取今日头条街拍美图
本节我们以今日头条为例来尝试通过分析 Ajax 请求来抓取网页数据的方法,我们这次要抓取的目标是今日头条的街拍美图,抓取完成之后将每组图片分文件夹下载到本地保存下来. 1. 准备工作 在本节开始之前请 ...
- Python3网络爬虫开发实战分析Ajax爬取今日头条街拍美图
本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 很多人学习pyt ...
- php抓取今日头条,分析Ajax来抓取今日头条街拍美图
一.介绍 还是根据崔大大的视频来码的文章,不得不说,抓取文件并下载下来比抓取网页内容信息复杂多了 二.流程 目标站点分析 用浏览器打开今日头条输入'街拍',打开审查元素,点击'图集' 1.首先我们要找 ...
- 转:【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图
[摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...
- 【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图
[摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...
- python爬虫今日头条街拍美图开发背景_【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图...
[摘要] 本节中,我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法.这次要抓取的目标是今日头条的街拍美图,抓取完成之后,将每组图片分文件夹下载到本地并保存下来. 1. 准备工作 在本节 ...
- 2.分析Ajax请求并抓取今日头条街拍美图
import requests from urllib.parse import urlencode # 引入异常类 from requests.exceptions import RequestEx ...
- 分析Ajax请求并抓取今日头条街拍美图
1.抓取索引页内容 利用requests请求目标站点,得到索引网页HTML代码,返回结果 2.抓取详情页内容 解析返回结果,得到详情的链接,并进一步抓取详情页的信息 3.下载图片与保存数据库 将图片下 ...
最新文章
- yolov5 代码版,去掉配置文件
- Back button implementation in Text reuse component GSTEXT
- thunderbird html签名,Thunderbird中配置签名
- linux-buff/cache过大导致内存不足-程序异常
- 第一个Netty应用
- 游戏筑基开发之二进制文件操作的那点事儿(C语言)
- Python语言实现用于动物分类的产生式系统
- 模拟实现strlen
- php三D立体模拟,CSS3使用3D环境实现立体魔方效果的实例代码分享
- 由国内媒体的“非典”报道看信息生态问题-引文
- SpringBoot 前后端分离 实现验证码操作
- 寻求路径问题————动态规划的思想
- 2021-05-22 黑板异或游戏
- model.evaluate 和 model.predict
- 在微型计算机中硬件和软件的关系是_,计算机的硬件系统和软件系统的关系是什么?...
- RPGMAKER游戏引擎基于JavaScript的插件制作(二)——如何理解插件,以及编写代码时的注意事项
- 词云python_词-经典诗词宋词语大全
- 【Antv/Vue3】vue项目中使用antv/L7制作地图
- Java设计模式面试题总结
- 微信视频上传服务器失败,用SDK接口方法UploadForeverVideo上传视频文件报40113(unsupported file type)错误...