1-6 浏览器抓包及headers设置(案例一:抓取知乎)

2018-06-23  本文已影响44人  pnjoe

任务:爬取知乎大V 张佳玮关注了哪些人

实战:

通过谷歌浏览器自带的工具(按F12)可以轻松找到请求URL

有了请求URL那就用requests先写吧,摸石头过河

import requests
url = "https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=20&limit=20"
r = requests.get(url)
print (r)

#运行结果
<Response [400]>

400,请求错误了。
估计是知乎网站做了反爬处理。
那我们就模拟(伪装成)浏览器发出请求试一下。


把这一段复制下来
import requests

headers = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36"}

url = "https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=20&limit=20"
r = requests.get(url,headers=headers)
print (r)

#运行结果
<Response [200]>

状态码200,成功了。往下一步走。


点击“Preview”,我们可以看到返回的数据是json格式

那我们就把json数据爬取下来吧。代码改为:

import requests

headers = {"user-agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36"}

url = "https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=20&limit=20"
r = requests.get(url,headers=headers).json()['data']

import pandas as pd
df = pd.DataFrame.from_dict(r)
df.to_csv('followees.csv',encoding='utf-8-sig')

爬到的输出结果

通过与网页上的实际数据对比。发现我们爬取到的是网页上第2页上的数据

我们成功地爬取到了一页数据,那么接下来试着把多页数据一并爬取下来吧。

下一页,查看一下谷歌工具抓取到新增的请求地址是什么。
新增的请求URL:https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=40&limit=20
再点下一页,查看一下谷歌工具抓取到新增的请求地址是什么。
新增的请求URL:
https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=60&limit=20
通过这3次请求的URL地址对比。我们发现了。倒数第二个字段offset有规律的变化。再根据保存下来的那一页数据对比实际网页上的数据,我们可以推断出offset字段与实际页数的关系。

字段offset的值 实际页面数据
0 第1页数据
第1次 20 第2页数据
第2次 40 第3页数据
第3次 60 第4页数据
... ... ...

有了上表offset字段与页数的关系图,我们来完善一下代码,让代码自动翻页抓取所有页面。

张佳玮关注了95人
每一页数据显示20人。那么95人,需要5个页面才能展示完。那我们就可以在代码里设置连续翻5页。
import requests
import pandas as pd
import time

headers = {
   'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36',
} #伪装成浏览器正常访问。加了这个请求头

user_data =[]
def get_user_data(page):
   for i in range(page):
       url = "https://www.zhihu.com/api/v4/members/zhang-jia-wei/followees?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset={}&limit=20".format(i*20)
       response = requests.get(url,headers=headers).json()['data']
       user_data.extend(response)
       print("正在爬取第%s页" % str(i+1))
       time.sleep(1)  #每爬1页,休息1秒钟,减轻服务器压力,以免自己被封。

if __name__== '__main__':
   get_user_data(5)
   df = pd.DataFrame.from_dict(user_data)
   df.to_csv('followees.csv',encoding='utf-8-sig')
运行界面
输出结果

大功告成


相关阅读
如何简单地理解Python中的 if __name__ == '__main__'

上一篇下一篇

猜你喜欢

热点阅读