简介
知乎用户信息是非常大的,本文是一个scrapy实战:怎样抓取所有知乎用户信息。
爬取的思路如下图所示:
![](https://img.haomeiwen.com/i14326004/8d9b98d0ebbf714d.png)
- 选择一个知乎用户作为根节点
- 每个用户都会有关注列表
-
选择每一个用户的关注列表,进行递归爬取知乎用户信息
站点分析
本文以轮子哥为根节点(根节点可以随便选择),打开轮子哥的关注列表,并翻页查看关注列表:
![](https://img.haomeiwen.com/i14326004/51c198d3e777c75c.png)
翻页是一个AJAX请求,每页20个关注用户,并且有一些简要的用户信息
其中有一个是url-token,它是用来标识一个用户的,在上面截图中那个用户的主页url为:https://www.zhihu.com/people/liu-yan-ting-19/activities
其中就有url-token
项目实战
创建项目
- scrapy startproject zhihuuser
- cd zhihuuser
- scrapy genspider zhihu www.zhihu.com
另外,在setting配置文件中有一个属性
ROBOTSTXT_OBEY = False
我们把它改为false,为true可能受限于robottxt规则,致使一些网页不能爬取,一般设置为false
注意
访问知乎时需要加useragent请求头,否则会返回500状态码,这个的配置在setting文件中:
思路分析
获取用户信息
首先需要获取用户的基本信息,这个基本信息可以通过请求类似下面的url获得:
https://www.zhihu.com/people/{url_token}/following
而url_token可以在用户的关注列表中获取,上面url的页面类似于这个
![](https://img.haomeiwen.com/i14326004/2baa131a45cc2d84.png)
另外,还有右侧获得赞同、被收藏、感谢的次数
从上述url获取用户基本信息后,接下来就是获取当前用户的关注列表:
获取用户的关注列表
这个列表存在翻页,经过分析得知关注列表的翻页是通过AJAX请求实现的,获取某页关注列表url如下所示:
https://www.zhihu.com/api/v4/members/Talyer-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=0&limit=20
提取一下规律:
https://www.zhihu.com/api/v4/members/{url-token}/followees?include={include}&offset={offset}&limit=2{limit}
其中include为:
data[*].answer_count,articles_count,gender,follower_count,is_followed,is_following,badge[?(type=best_answerer)].topics
上面url返回时一个json,该json中包含了20个关注者,response数据如下图所示:
![](https://img.haomeiwen.com/i14326004/1a3aeb862e7bb405.png)
对于一个关注者,我们只需要获取该用户的url-token,通过url-token即可拼接出该用户的主页,也就可以获得该用户的基本信息,以及关注者列表等。
获取到url-token后,我们需要判断有没有下一页,如果有则进行翻页,在上图的后半部分还有一个字段:
![](https://img.haomeiwen.com/i14326004/ad84db95e53df5f9.png)
翻到当前的最后一页,该字段如下图所示:
![](https://img.haomeiwen.com/i14326004/d79fad127d49e73b.png)
因此依据is_end字段就可以判断是否下一页关注者了,使用next字段的值即可获取下一页关注者的列表了。
思路整理
- 首先访问一个知乎大V的主页,并解析该大V的基本信息(parse_user);
- 之后,获取该大V第一页关注者列表(parse_follows)
- 依次获取该页关注者列表的url_token,进一步解析出列表中的所有关注者的基本信息
- 解析完当前页的关注者基本信息后,进行分页的判断和处理:即获取next字段的值,然后请求下一页url,并回调当前函数进行解析
- 这样做完后,我们即完成了当前知乎大V的所有关注者基本信息的爬取,但是这样做还完全不够,只解析了一个用户的关注者,也就是我们还要改解析当前用户所有关注者的关注者的基本信息,这样才能把知乎用户连接起来,形成一个网。怎么才能实现呢?
- 在parse_user中我们解析到了当前用户的基本信息,每解析一个关注者基本信息后,此还应该解析该用户关注者列表,也就是在parse_user中也需要获取url_token,没有该值我们就获取不到用户的关注列表。那么如何在parse_user时获取用户的url_token呢?
- 实际上url_token在parse_user的response中已经包含了:即通过response获得当前页面的url,当前页面的url中就包含了当前用户的url_token
所以呢?在解析用户基本信息的同时,我们可以拿到用户的url_token,进一步我们也就可以拿到该用户的关注者列表,如此递爬取,基本可获得所有知乎用户的所有基本信息。
- 另外,需要考虑去重问题:递归爬取不去重的话会造成死循环。去重最简单的使用set:将解析过用户的url_token放入到set中,在解析一个用户基本信息前先判断该用户之前有没有被解析过。可以使用分布式redis去重,单击可能造成内存溢出,比较知乎用户数量庞大
- 最后,为了防止请求过多而被知乎封禁ip,可以使用之前介绍的ip代理池,具体可以看先前的文章
pipline设置 -
数据的存储通过pipline设置即可
本次爬取的item数据结果如下图所示:
本次的pipline设置为:
源码和爬取的部分数据:
爬取的部分知乎用户数据
![](https://img.haomeiwen.com/i14326004/7d21f2a1ac5e9d39.png)
源码
爬取知乎用户的思路已经在文章介绍了,思路理好后,实现比较块。
主要是源码有点长,这里就不全贴出来了。需要源码的同学可以通过文末方式获取
扫描下方二维码,公众号菜鸟名企梦
后台发送关键词“知乎”即可获取本文的完整源码和详细程序注释
![](https://img.haomeiwen.com/i14326004/6e2e1a12ac02844d.jpg)
公众号菜鸟名企梦
专注:互联网求职面经、java、python、爬虫、大数据等技术、海量资料分享:
公众号菜鸟名企梦
后台发送“csdn文库下载”即可免费领取【csdn】和【百度文库】下载服务;
公众号菜鸟名企梦
后台发送“资料”:即可领取5T精品学习资料、java面试考点和java面经总结,以及几十个java、大数据项目,资料很全,你想找的几乎都有
网友评论