爬取获得知乎“轮子哥”——vczh所有的关注对象:
(本案例来源DC学院的爬虫课程)
1.由于知乎的反爬措施,向服务器请求信息的时候需要提交user agent的信息。通过谷歌浏览器开发者工具找到user agent的信息,具体方法为:用谷歌浏览器打开网页,右键“审查元素”,点击“network”,刷新页面,点击第一个文件“following”,右侧下拉到“request headers”目录下找到user agent 信息;复制该信息并保存到headers变量中(注意这里是用字典保存);
2.解析页面
如果在返回的html文件中找我们要的资料会比较麻烦,在所有响应的文件中找到我们所需要的信息在哪里,只抓取这一个文件比较方便,所以我们试着在Network中查看每一个响应文件,最终找到一个followee的文件,里面包含了该页所有关注者的信息(图1),而这些信息是通过直接请求知乎API 得到的(图2),我们就可以通过对这个URL请求从而过滤掉其他们无用的数据,只获取我们需要的信息
图1
图2:
进一步对图2中的URL 进行解析
第一页关注者的URL:
https://www.zhihu.com/api/v4/members/excited-vczh/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
第二页关注着的URL
https://www.zhihu.com/api/v4/members/excited-vczh/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
比较发现最后offset=40&limit=20是决定页面变化的参数,以20一页为限制,offset为0时显示第一页,20显示第二页,以此类推,所以要爬取每一页的信息只要把这个参数改成变量,写一个for循环即可;
for i in range(2): #这里只爬去前两页
print("当前正在爬去第{}页".format(i+1))
url_2 = 'https://www.zhihu.com/api/v4/members/excited-vczh/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_2, headers=headers)
这样我们基本就已经获取到我们想要的信息了,接下来是对获取数据的格式做处理,先用jason.load把爬取下来的数据转变成字典,
data = json.loads(response.text)
注意这里的字典是嵌套式字典,字典中还有字典或者列表(如图3),我们其实只需要键“data”下面的value就够了
user_data.extend(data['data'])
图3
最后再把所有数据通过pandas导出成excel就完成了
df = pd.DataFrame.from_dict(user_data)
df.to_excel('user_data.xlsx')
附完整代码
import requests
import json
import pandas as pd
import time
user_data = []
headers = {'user-agent': '输入各自的user—agent信息'}
for i in range(2):
print("当前正在爬去第{}页".format(i+1))
url_2 = 'https://www.zhihu.com/api/v4/members/excited-vczh/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_2, headers=headers)
data = json.loads(response.text) # 转成字典·
user_data.extend(data['data']) #注意append和extend方法的区别
time.sleep(1)
df = pd.DataFrame.from_dict(user_data)
df.to_excel('user_data.xlsx')
Q1:为什么我浏览的是第一页关注人的信息,但是响应文件followee中显示的是第二页关注人的信息?
Q2:什么是API?
A:API是应用程序接口,是不同软件之间,功能交换和数据传输的接口,在爬虫中,访问API 和访问URL是一样的,区别在于通过API得到的数据是针对机器格式化的。访问API抓取到的数据比通过请求URL 再用xpath或beautifulsoup抓取到的数据更有针对性,少了很多无用的信息,并且容易提取数据
Q3:extend方法和append方法有什么区别?
A:extend 会把列表中的元素拆分开合并:
Q4.为什么headers 要用字典保存?
Q5.保存为csv文件乱码?
A:设置参数 encoding='utf_8_sig’
1.如何用正则表达式爬取同样的信息?