众所周知,动态网站通常使用例如ajax等异步加载技术来加载网页,相比于静态网页,动态网页通常包含多个请求,且数据往往并不存在于网页源码中,我们便需要通过抓包来寻找数据所在的请求并分析,编写响应的爬虫代码。动态网站的爬取包含下以下三个步骤:抓包,分析参数,提取数据。(以下使用爬取b站评论来作为讲解案例)
一、抓包
抓包有很多方式,比较常见的有用例如fiddle这种抓包软件以及浏览器自带的开发者调试工具(即f12),这里只介绍chrome的f12。
f12里有许多的菜单,这里我们只需要用到network,下面是我们会经常用到的功能





二、分析参数
异步数据包不像网页一样有着独一无二的uri,作为传递数据的api,网站通常只会使用一个api来传递一类的数据,并通过包内的参数来通知服务器后台应该传回什么数据,而我们需要分析的参数便是这些影响后台的关键数据。
点开我们已经定位到的包,选中header,可以看到有几个下拉栏
其中有三个栏目是我们需要关注的:
1.Respuest Headers
请求头,在我们爬静态网站的时候也同样会用到的一组参数,例如user-agent,referer等字段,有些网站会在请求头内传递一些数据来通知后台,主要还是为了反爬,除了user-agent和referer之外其他的字段很少用到,具体情况具体分析,爬的时候注意即可。
2.Form data
请求体,只存在于POST请求,也同样是一组需要分析的参数,因为我们很少会爬到POST请求的api,所以不展开说。
3.Query String Parameters
这是最重要的一组参数,存在于url当中,url链接问号后面的那一串字符串就是用来传这组参数的,不过在f12中我们可以直观的看到,如下图
接下来我们需要开始分析这些参数,找出哪些是有用的,哪些是不需要传的,哪些又是没用但是需要传的。这里没有一个很万金油的方法,无非就是用删改参数后访问并检查传过来的数据,或者寻找使用同一api的事件,对比有什么不同,我们可以用python shell或者写个python脚本用来测试,例如
import requests header = { 'referer': 'https://www.bilibili.com/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36' } query = { 'callback': 'jQuery172015271738099074472_1610803920156', 'jsonp': 'jsonp', 'pn': 1, 'type': 1, 'oid': 412935552, 'sort': 2, '_': 1610804916511 } url = 'https://api.bilibili.com/x/v2/reply?callback={}&jsonp={}&pn={}&type={}&oid={}&sort={}&_={}' print(requests.get(url.format(query['callback'],query['jsonp'],query['pn'],query['type'],query['oid'],query['sort'],query['_']),headers=header).text)
测试完后我们可知参数callback、jsonp、_是不需要的,type是需要但无意义的,pn表示页数,sort表示排序方式(即热度排序和最新排序),oid指定唯一一个视频(但不是av号),因此我们便可以通过循环pn来把所有的评论都给爬到。
三、提取数据
api大部分采用json数据格式传输数据,当然也有直接将参数加到网页url里传回html的情况(用bs解析即可),解析json我们需要用到json库,这里不再详细讲关于json的知识(需要的话去百度查
如图所示,我们要找的路径即为root -> data -> replies。每一条评论的内容、作者、时间等都在这里
四、总结
关于动态网站的爬取主要还是在于对异步加载这类前端技术的认识程度,以及对于web开发的理解,虽然作为爬虫工具人,但前后端的技术学习那是一个没落下,甚至于某些网站用js来反爬,难度又能上一级。不过对于数据挖掘来说这种基本的爬虫技术已经够用,网路上90%的数据爬取都是没问题的。