【scrapy实战】抓取知乎用户信息

简介

知乎用户信息是很是大的,本文是一个scrapy实战:怎样抓取全部知乎用户信息。 爬取的思路以下图所示: java

  • 选择一个知乎用户做为根节点
  • 每一个用户都会有关注列表
  • 选择每个用户的关注列表,进行递归爬取知乎用户信息

站点分析

本文以轮子哥为根节点(根节点能够随便选择),打开轮子哥的关注列表,并翻页查看关注列表: python

翻页是一个AJAX请求,每页20个关注用户,而且有一些简要的用户信息 其中有一个是url-token,它是用来标识一个用户的,在上面截图中那个用户的主页url为:www.zhihu.com/people/liu-… 其中就有url-token面试

项目实战

建立项目redis

  • scrapy startproject zhihuuser
  • cd zhihuuser
  • scrapy genspider zhihu www.zhihu.com 另外,在setting配置文件中有一个属性 ROBOTSTXT_OBEY = False 咱们把它改成false,为true可能受限于robottxt规则,导致一些网页不能爬取,通常设置为false 注意 访问知乎时须要加useragent请求头,不然会返回500状态码,这个的配置在setting文件中:

思路分析

获取用户信息 首先须要获取用户的基本信息,这个基本信息能够经过请求相似下面的url得到: www.zhihu.com/people/{url… 而url_token能够在用户的关注列表中获取,上面url的页面相似于这个 json

另外,还有右侧得到赞同、被收藏、感谢的次数 从上述url获取用户基本信息后,接下来就是获取当前用户的关注列表: 获取用户的关注列表 这个列表存在翻页,通过分析得知关注列表的翻页是经过AJAX请求实现的,获取某页关注列表url以下所示: www.zhihu.com/api/v4/memb… 提取一下规律: www.zhihu.com/api/v4/memb…{ 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数据以下图所示:
对于一个关注者,咱们只须要获取该用户的
url-token*,经过url-token便可拼接出该用户的主页,也就能够得到该用户的基本信息,以及关注者列表等。 获取到url-token后,咱们须要判断有没有下一页,若是有则进行翻页,在上图的后半部分还有一个字段:
翻到当前的最后一页,该字段以下图所示:
所以依据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,进一步咱们也就能够拿到该用户的关注者列表,如此递爬取,基本可得到全部知乎用户的全部基本信息。api

  • 另外,须要考虑去重问题:递归爬取不去重的话会形成死循环。去重最简单的使用set:将解析过用户的url_token放入到set中,在解析一个用户基本信息前先判断该用户以前有没有被解析过。可使用分布式redis去重,单击可能形成内存溢出,比较知乎用户数量庞大
  • 最后,为了防止请求过多而被知乎封禁ip,可使用以前介绍的ip代理池,具体能够看先前的文章 pipline设置
  • 数据的存储经过pipline设置便可 本次爬取的item数据结果以下图所示:
    本次的pipline设置为:

源码和爬取的部分数据:

爬取的部分知乎用户数据 scrapy

源码 爬取知乎用户的思路已经在文章介绍了,思路理好后,实现比较块。 主要是源码有点长,这里就不全贴出来了。须要源码的同窗能够经过文末方式获取


扫描下方二维码,发送关键词“知乎”便可获取本文的完整源码和详细程序注释 分布式

扫码关注,及时获取更多精彩内容。(博主今日头条大数据工程师)

资料分享

java学习笔记、10T资料、100多个java项目分享ide


公众号专一:互联网求职面经javapython爬虫大数据等技术分享: 公众号菜鸟名企梦后台发送“csdn”便可免费领取【csdn】和【百度文库】下载服务; 公众号菜鸟名企梦后台发送“资料”:便可领取5T精品学习资料java面试考点java面经总结,以及几十个java、大数据项目资料很全,你想找的几乎都有函数

相关文章
相关标签/搜索