网站「看知乎」的爬虫

开源地址:https://github.com/atonasting/zhihuspider

  1. 编辑 config.js,标明(必须)的配置项必须填写或修改,其余项可以暂时不改:

 

爬虫用户

爬虫的原理其实就是模拟一个真正的知乎用户在网站上点来点去并收集数据,所以我们需要有一个真正的知乎用户。 为了测试可以用你自己的账号,但从长远着想,还是专门注册个小号吧,一个就够,目前的爬虫也只支持一个。 我们的模拟过程不必像真的用户那样从首页登录,而是直接借用 cookie 值:

注册激活登录之后,进入自己的主页,使用任何有开发者模式或查看 cookie 插件的浏览器,打开知乎中自己的 cookie。 可能有很复杂的一大串,但我们只需要其中两部分,即「z_c0」、「login」。 复制你自己 cookie 中的 z_c0 和 index 两部分,连等号、引号、分号都不要落下,最后格式大致是这样的:

z_c0=”LA8kJIJFdDSOA883wkUGJIRE8jVNKSOQfB9430=|1420113988|a6ea18bc1b23ea469e3b5fb2e33c2828439cb”;login=”MGYyODU4MTc5ZJ945jio2F2YzA3MY849cvzOWY=|1420113988|bc1b23ea469e3b5fb2e33c28284121fa2f606547″;

在 mysql 数据库的 cookies 表中插入一行记录,其中各字段值分别为:

  • email:爬虫用户的登录邮箱
  • password:爬虫用户的密码
  • name:爬虫用户名
  • hash:爬虫用户的 hash(每个用户不可修改的唯一标识,其实这里用不到,可以暂时留空)
  • cookie:刚才你复制的 cookie

然后就可以正式开始运行了。

如果 cookie 失效或用户被封,直接修改这行记录的 cookie 字段即可。

运行

推荐用 forever 来执行,这样不仅方便后台运行和记录日志,还能在崩溃后自动重启。 示例:

forever -l /var/www/log.txt index.js

其中 – l 后的地址就是记录日志的地方,如果放在 web 服务器目录下,就能在浏览器里通过 http://www.xxx.com/log.txt 来直接查看日志了。

在 index.js 后面加参数(用空格分隔)可以执行不同的爬虫指令:

  1. -i 立即执行,如果不加此参数则默认在下一个指定时间执行,如每天凌晨 0:05 分;
  2. -ng 跳过抓取新用户阶段,即 getnewuser;
  3. -ns 跳过快照阶段,即 usersnapshot;
  4. -nf 跳过生成数据文件阶段,即 saveviewfile;
  5. -db 显示调试日志。

各阶段的功能在下一节介绍。

为了方便运行,可以将这行命令写成 sh 脚本,例如:

#!/bin/bash
cd /usr/zhihuspider
rm -f /var/www/log.txt
forever -l /var/www/log.txt start index.js $*

具体路径请替换成自己的。

这样就能通过./zhihuspider.sh 加参数来开启爬虫了: 比如./zhihuspider.sh -i -ng -nf 就是立即开始任务、跳过新用户和保存文件阶段。

停止爬虫的方法是 forever stopall(或 stop 序号)。

原理概述

看知乎爬虫的入口文件是 index.js。它通过循环方式在每天指定时间执行爬虫任务。

每天顺序执行的任务有三个,分别是:

  1. getnewuser.js:通过当前库内用户关注者列表的对比,抓取新用户信息,依靠此机制可以自动将知乎上值得关注的新人纳入库中;
  2. usersnapshot.js:循环抓取当前库内用户资料和答案列表,并以每日快照形式保存下来。
  3. saveviewfile.js:根据最近一次快照内容,生成用户分析列表,并筛选出昨日、近日和历史精华答案发布到「看知乎」网站。

在以上三个任务执行完毕后,主线程会每隔几分钟刷新一次知乎首页,验证当前 cookie 是否仍然有效,如果失效(跳到未登录页),则会给指定邮箱发送通知邮件,提醒及时更换 cookie。 更换 cookie 的方法和初始化时一致,只需手工登录一次然后取出 cookie 值就行了。

如果对具体代码实现感兴趣可以仔细看里面的注释,调整一些配置,甚至尝试自己重构整个爬虫。

Tips

  • getnewuser 的原理是通过对比前后两天快照中用户的关注数量进行指定抓取,所以必须有了至少两次快照之后才能开始,之前就算执行也会自动跳过。
  • 快照抓到一半是可以恢复的。如果程序出错崩溃,用 forever stop 停止它,然后加上参数 – i -ng,立即执行并跳过新用户阶段就能从刚才抓到一半的快照继续下去了。
  • 不要轻易增加快照抓取时的(伪)线程数,即 usersnapshots 中的 maxthreadcount 属性。线程太多会导致 429 错误,同时抓取回来的大量数据可能会来不及写入数据库造成内存溢出。所以,除非你的数据库搭在 SSD 上,线程不要超过 10 个。
  • saveviewfile 生成分析结果的工作需要至少近 7 天的快照才能进行,如果快照内容少于 7 天会报错并跳过。此前的分析工作可以手动查询数据库进行。
  • 考虑到大多数人并不需要复制一个「看知乎」,已经将自动发布 wordpress 文章函数入口注释掉了。如果你搭建好了 wordpress,记得开启 xmlrpc,然后设置一个专门用于发布文章的用户,在 config.js 中配置相应参数并将 saveviewfile 中的相关代码解除注释。
  • 由于知乎对头像做了防盗链处理,我们在抓取用户信息时一并也将头像获取了下来,保存在本地,发布文章时使用的是本地头像地址。需要在 http 服务器中将 url 路径指向保存头像的文件夹,或者将保存头像的文件夹直接放到网站目录下。
  • 代码可能不太容易读懂。除了 node.js 的回调结构本身就较混乱之外,还有一部分原因是最初写程序时我刚刚开始接触 node.js,有很多不熟悉的地方导致结构混乱没有来得及改正;另一部分是在多次缝缝补补中累加了许多丑陋的判断条件和重试规则,如果全部去掉,代码量可能会下降三分之二。但这是没有办法的事,为了保障一个系统的稳定运行,必须加入这些。
  • 本爬虫源码基于 WTFPL 协议,不对修改和发布做任何限制。
  • 苏莉安很懒,不会及时解答问题和更新版本,作为开发者应该尽量自己解决。

发表评论

电子邮件地址不会被公开。 必填项已用*标注