知乎数据的抓取

本文详细介绍了如何使用Scrapy框架抓取知乎上的用户分类、基本信息、回答问题数据和个人主页信息,通过伪装请求头和利用Ajax请求获取数据,最后将数据存储到MongoDB中进行分析。

本篇文章主要简述知乎相关数据的抓取,抓取数据为科学研究使用

思路分析:

  1. 获取所有答主的分类
  2. 获取分类下所有用户的基本信息
  3. 获取用户的值乎页面的信息
  4. 获取用户回答问题的数据
  5. 获取用户个人主页信息

一成功访问知乎并获得数据

开始之前,我们必须保证我们能够访问知乎,并获取数据。如果你不做任何设置,而直接爬取的话,一般会爆一个500 Internet Server Error的错误,因为服务器已经识别出你是一个爬虫而不是一个用户请求,所以服务器拒绝服务。

因此我们要伪装一下,在settings.py文件中加入默认请求头,把爬虫伪装成一个浏览器访问,当然还需authorization,经过观察,所有访问页面的authorization都一样,所以我们就做如下添加:

DEFAULT_REQUEST_HEADERS = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',

'authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20',

}

经过伪装,我们就可以正常的访问知乎页面并拿到数据了。

二获取所有答主的分类

首先构造知乎所有分类信息的url

既然已经能够成功访问知乎,那我就可以开始爬虫的具体实现了。经过解析知乎分类页面得到获取分类信息的json文件的url为:

url=https://www.zhihu.com/zhi/infinity/topics?limit={limit}&offset={offset}.

通过不断改变偏移地址offest可获取所有分类信息(这困扰我良久,因为我一直用paging作为结束判断标志,next_page作为下一次爬取的链接,但是一直404,之后才发现,请求json的url与Ajax的url不同,所以就改用offest递增爬取替换next_page)。

此处,我获取了分类的id及其他信息。经分析发现,分类中,获取用户列表的ajax请求如下:

user_list_url = 'https://www.zhihu.com/zhi/infinity/topics/{id}/answerers?limit={limit}&offset={offset}'

通过该url可获取用户信息的json文件,接下来就是构造用户的值乎url和获取用户信息的url了。

三获取用户值乎行为数据

我们首先打开任意一个用户的值乎页面,发现获取用户行为信息的url是有规律可循的,他们的基本构造一样,且都是返回一个json文件。

zhi_url = 'https://www.zhihu.com/zhi/infinity/{id}'

由此可获取用户值乎页面的行为数据。

四获取值乎问题数据

打开值乎也页面,我发现用户回答的问题列表为ajax请求的方式显示,然后我检查其请求的url发现,url构造如下:

start_qas_url = 'https://www.zhihu.com/zhi/infinity/{id}/qas?'

由此可获取用户值乎页面问题数据。

五获取用户个人信息

我们把鼠标放在用户的头像上,就会出现一个ajax请求,请求的url为:

user_url = 'https://www.zhihu.com/api/v4/members/{user}?include={include}'

我们只需要加入相应的user=url_token,include=user_query即可请求到用户的个人信息。

url_token在用户的知乎主页里,需要用字符串截取的方式获取,user_query只需解析用户的请求url就可获得。

 

综上,我们获取到了所有想获取的数据,然后将数据存在mongdb中,官方文档有相应的设置教程,这里就不赘述了。

使用mongdb主要是写出mongopipline和设置信息。下面是主要函数:

#去重插入处理函数

def process_item(self, item, spider):

if isinstance(item,UserItem):

self.db['user'].update({'url_token': item['url_token']}, dict(item), True)

if isinstance(item,ZhiItem):

self.db['zhi'].update({'id': item['id']}, dict(item), True)

if isinstance(item,QuestionItem):

self.db['question'].update({'id': item['id']}, dict(item), True)

return item

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值