上篇文章通过一个实例简要说明了如何用requests库和re库批量爬取图片,本篇文章将用另外一个实例说明如何爬取知乎上的回答并进行整理。
(一):引入相关库import re
import requests
(二):改写headers伪装浏览器
# 知乎有反爬虫,加入http headers伪装浏览器
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
"Connection": "keep-alive",
"Accept": "text/html,application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8"}
伪装头部是最基本的反反爬虫方法,如果不进行伪装,对方网站可以直接通过headers中的"User-Agent"信息判断出我是通过python的requests库对网页进行请求访问的。
(三):相关参数设置question_id = 38485891
interval = 20
offset = 0
rank = 100
novels_count = dict()
p = re.compile(r'《.+?》') # 正则匹配被《》括起来的电影名
question_id很好理解:每个知乎问题都有一个独一无二的id用来区分
interver为间隔:这里设为20,意味着每次爬取某一个问题的20个回答
offset为偏移量,初始为0,意味着从第一个答案进行爬取
rank为打印数量,在后续打印排名时才会用到
novels_count初始设为一个空字典,用来存储所获取的电影信息
p为正则表达式,匹配被书名号括起来的电影名
while True:
print(f'答案数 {offset} 到 {offset + interval}')
# 知乎获取回答分页API
url = f'https://www.zhihu.com/api/v4/questions/{question_id}/answers?include=content&limit={interval}&offset={offset}&sort_by=default'
html = requests.get(url, headers=headers)
answers = html.json()['data']
if len(answers) == 0:
break
for answer in answers:
results = set(re.findall(p, answer['content'])) # 结果去重,过滤掉同一个回答里的多次提及导致的重复统计
for novel_name in results:
if novel_name in novels_count:
novels_count[novel_name] += 1
else:
novels_count[novel_name] = 1
offset += interval
这段代码有一些值得注意的地方:
(1)python的print字符串前面加f表示格式化字符串,加f后可以在字符串里面使用用花括号括起来的变量和表达式,对url的赋值同理。
(2)set() 函数创建一个无序不重复元素集,删去同一个答案中的重复电影名称
# 把结果按提名次数从高到低排序
novels_rank_list = sorted(novels_count.items(), key=lambda x: x[1], reverse=True)
print(f'提名电影总数:{len(novels_rank_list)}')
(1)items() 方法的遍历:items() 方法把字典中每对 key 和 value 组成一个元组,并把这些元组放在列表中返回。
(2)lambda是一个隐函数,是固定写法,不要写成别的单词;x表示列表中的一个元素,在这里,表示一个元组,x只是临时起的一个名字,你可以使用任意的名字;x[0]表示元组里的第一个元素
# 打印前50
for i, novel in enumerate(novels_rank_list):
if i > rank - 1:
break
name = novel[0]
num = novel[1]
print(f'{i + 1}.{name}提名{num}次')
(1)enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
我将这个问题答案进行了整理并将整理后的内容写在了知乎这一问题下,现给出原文链接,有兴趣的朋友可以看一看~~
https://www.zhihu.com/question/38485891/answer/1017573264