动态列表爬虫教程

我去网上找关于“化学”的专业网站,但是没有找到。只找到两个简陋的论坛,里边都是些一两句话组成的帖子。然后到知乎上问,有什么关于“化学的网站”,还是没找到。我转念一想,直接爬知乎不就行了嘛。

问题下的答案:

以“有哪些绝对不能触摸的化学药品?”为例:

知乎的网页都是动态,你把窗口滑到底部,它就自动加载内容。这样似乎给爬虫造成了难度,实际上造成了巨大的便利。我来说说我是怎么找到他的api 的。

  1. 打开浏览器,按 F12 把浏览器的抓包工具打开(这也叫开发者工具)。点击“网络”
    如图:
    开发者工具
  2. 把窗口一点点往下滑,你会发现这将触发浏览器发出好多请求。把可疑的一个个点开:
    然后你会发现一个长相清奇的请求:
    滑动窗体,看到的请求
    点开它看看吧:
    查看headers
    查看 response
    你会发现,这个请求的 path 上面挂着“api”字样,”?”前边有一个answer;它的响应是一串数据。这一串数据是啥,似乎看不太清。双击这个请求
    双击这个请求

一览无余:
请求的响应信息

这明显是一个json,直接读有一点点难度,写个小程序调试一下,仔细看看它的结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
import json
header = {
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
'x-requested-with': 'fetch'
}

# url 就是刚刚那个请求的地址,我稍稍处理了一下,防止你去点;我想要做的就是用json解析一下响应的内容,试图读懂
url = r"https://www.zhihu.com/api/v4/questions/37073879/answers?*****xxxxx*****s&limit=5&offset=18&platform=desktop&sort_by=default"
resp = requests.get(url, headers=header)
data = json.loads(resp.content)

data结构

  • ad_info 估计跟广告有关
  • data 里边有五条数据,其实就是五条答案,与 url 里边的 limit=5 有关
  • paging 里边竟然有下一个数据块的连接(next)!都不用自己去算了

至于是这五条来自哪里,查看next链接可以发现,只有offset不同。我估计知乎在查询一个数据库,limit 就是SQL里面 limit 的含义;offset就是table里的偏移量。
可以试着把 limit 放大一点点,发现 limit=10 也是能用的,返回10条答案;20 似乎也能用。比20大的就不能用了。我取值 limit=10 ,防止步子迈的太大。

以上就是在问题里面爬取答案的方法。

爬取其他内容

另外,还可以在话题下面爬取问题;爬取精华内容;操作大同小异。
不同的是:爬取问题列表时需要话题 id;爬取答案列表时需要问题id。
而这些 id 都可以从各自api的响应 data 里获取。

以话题下面的问题列表为例:
问题列表

爬虫的整体思路:

先爬取话题下的问题,保存起来
再根据各问题 id 爬取答案列表。把所有答案保存起来。

爬问题和爬答案的api稍有区别,你可以到浏览器上找。

ps: 知乎的 api 返回的内容形式高度一致,为爬虫提供了方便。

吐槽

开多线程的时候,分分钟就被封ip,所以我只好开单线程,企图细水长流。
还好,封IP不是特别频繁,但还是过几个小时封一次。
他总是封我的ip,却没有忘记给我发广告。
广告图

文章作者: Mr. Wang
文章链接: http://blog.zhyu.wang/2020/02/29/%E5%8A%A8%E6%80%81%E5%88%97%E8%A1%A8%E7%88%AC%E8%99%AB%E6%95%99%E7%A8%8B-0/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 蓝玉冰城