不知道你是否像我一样,有一个基于hexo的博客,同时还在知乎上比较活跃,有一些自己的答案。如果是,可以继续看下去了,这个小工具是可以将你的知乎答案以hexo博客模板的md文件形式备份到本地,方便了你对你自己知乎答案的利用,避免了重复的复制粘贴。
git clone https://github.com/zhangolve/zhihu-answer-convert-to-md-by-node
进入zhihu-answer-convert-to-md-by-node文件夹内,
npm install
将config.example.js文件重命名为config.js,也就是去掉中间的.example
,打开重命名后的config.js文件,修改配置。
首先得到cookie,方法是:
打开已经登录的知乎,在Chrome控制台输入
document.cookie
将得到的字符串粘贴到对应的位置。
zhihuId 为你想要的知乎用户的知乎Id,由于这个项目是为了得到自己的知乎答案方便导出到hexo博客或其他用处,因此,建议填写自己的知乎Id,找知乎id的方法是找到自己的知乎主页,比如我的知乎主页是:
https://www.zhihu.com/people/zhang-hai-26/activities
则我的知乎Id就是zhang-hai-26,将它复制粘贴到对应的位置即可。
至于authorization的获取,方法是使用Chrome浏览器,打开你的知乎主页,比如我的知乎主页是:https://www.zhihu.com/people/zhang-hai-26/activities ,然后按F12或者右键选择检查,切换到Network(网络)标签,刷新页面,这个时候选择一个activity或者answer开头的文件,点击它,然后将右面Request headers里面的authorization 对应的字符串复制下来。粘贴到config.js 对应的位置。
执行
npm start
如果config.js的配置没有问题的话,那么执行该脚本之后将会在接下来的一分钟以内,下载最多最近的1000个答案,如果您的知乎答案少于1000个,将下载到您的所有答案。
如果你已经完成了md文件的写入,这个时候,你会在项目文件夹下得到两个目录,一个是以你的知乎Id命名的文件夹,用于存放最原始的答案json数据,另外一个文件夹则是用来存放md文件的,打开它之后我们就能够看到所有的答案了。
他们的规范都是hexo博客规范,因此可以直接将你想要放到博客中的文件放到博客文章目录之下,也可以对生成的markdown文件进行再编辑,也可以向我一样,把整个生成的markdown文件夹放到博客的一个子目录下,总之,材料就在那里,怎样用其实很灵活。
可以看我的博客: http://hktkdy.com/categories/%E7%9F%A5%E4%B9%8E/
我的博客的知乎category里面放的就是我用爬虫爬到的所有答案,实际情况是,对文字支持较理想,对图片资源的利用目前还没解决,致使目前所有文章都属于无图状态,因此不建议答案中含有多图的答主使用该工具。
这个小项目是我练习node爬虫的一个小作品,目前实现的功能还比较简单,可扩展性还很高。
- 异常情况的处理,如cookie错误,知乎id错误等
- 更高的要求,部署到服务器上面
- 每一个readme文件名字可以就是爬取到的知乎问题题目。
- 每个md文件都应该符合hexo的规则。
- 将每个回答单独放到一个md文件里面。
- 自动化node importjson.js 和node json.js
- 将手动的循环api变为自动的
- for循环长度的判断
- 最多能够下载最新的1000个答案。以张佳伟的知乎答案作为测试。
- 修改了原来由于双引号不能出现在文件命名中而引起的错误。
- 还应该找到原始的回答链接,并且放到正文结尾处。
- 测试直接放上去rss是否有更新,只要日期在当前最新文章日期之前,RSS就不会有更新,很友好。
- md文件中不规则的<>标签应该去除掉,使用正则表达式
- 优化日志结构
文件的读取和写入 fs 模块的使用 参考文章:http://www.jianshu.com/p/5683c8a93511
request模块的使用
做这个项目的技术难点总结起来有这样几点:
- 获取数据
我最初的考虑是直接获取网页的数据,然后通过组织筛选html文件中的部分来得到符合条件的数据 ,后来在抓包的过程中发现,即便是知乎官方,针对展示数据这一块也依然是通过调用后台服务的方式来获取数据,那么我需要做的其实就是模拟浏览器获取数据,这个时候,我用到了node.js 的第三方库 request.js,通过自定义请求头,我就能够很顺利地得到所有的数据了。
- 输入输出
知乎对于每个api都有答案条目的数量限制,每调用一次api,是能够获得20条答案。我将每一次调用api得到的json文件都通过node写入到本地文件中,方便以后进行处理。而写入完毕之后,我又通过node读取这些文件,这个时候为了更好的性能要求,我也使用了async库进行了异步控制,使整个过程更加快速。
- 输出的转换
我最终需要的是markdown文件,因此我又引入了node第三方库markdown,该库支持将html文件转换为md文件,效果还算不错。
这也就是我此次爬虫的几个关键点了,当然我也做过其他的爬虫项目,共同点总结来说是:
- 异步控制
- 错误处理
爬虫要求频繁地请求数据和处理数据,这时候为了性能要求,我们也就很自然地要使用node.js的异步控制,但是如果使用传统的callback,就很容易陷入到callback hell(回调地狱)之中,这个时候可以考虑使用Promose,也可以使用别人封装的第三方库,比如async等。
错误处理也是很让人头疼的事情,在我的另外一个爬虫实验当中,我爬取我个人微博,结果发现爬虫速度过快,被微博官方的反爬虫机制中伤,导致ip地址被封,这也导致不仅爬虫无法使用了,而且我本人的微博帐号也在一定时间段内无法登陆了。这个时候,我能够做的,就是修改async的请求速度。