基于Node.js的强大爬虫 能直接发布抓取的文章哦


Posted in Javascript onJanuary 10, 2016

一、环境配置

1)搞一台服务器,什么linux都行,我用的是CentOS 6.5;

2)装个mysql数据库,5.5或5.6均可,图省事可以直接用lnmp或lamp来装,回头还能直接在浏览器看日志;

3)先安个node.js环境,我用的是0.12.7,更靠后的版本没试过;

4)执行npm -g install forever,安装forever好让爬虫在后台跑;

5)把所有代码整到本地(整=git clone);

6)在项目目录下执行npm install安装依赖库;

7)在项目目录下创建json和avatar两个空文件夹;

8)建立一个空mysql数据库和一个有完整权限的用户,先后执行代码里的setup.sql和startusers.sql,创建数据库结构并导入初始种子用户;

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

exports.jsonPath = "./json/";//生成json文件的路径
exports.avatarPath = "./avatar/";//保存头像文件的路径
exports.dbconfig = {
  host: 'localhost',//数据库服务器(必须)
  user: 'dbuser',//数据库用户名(必须)
  password: 'dbpassword',//数据库密码(必须)
  database: 'dbname',//数据库名(必须)
  port: 3306,//数据库服务器端口
  poolSize: 20,
  acquireTimeout: 30000
};
  
exports.urlpre = "https://3water.com/";//脚本网址
exports.urlzhuanlanpre = "https://3water.com/list/index_96.htm/";//脚本网址
  
exports.WPurl = "www.xxx.com";//要发布文章的wordpress网站地址
exports.WPusername = "publishuser";//发布文章的用户名
exports.WPpassword = "publishpassword";//发布文章用户的密码
exports.WPurlavatarpre = "http://www.xxx.com/avatar/";//发布文章中替代原始头像的url地址
  
exports.mailservice = "QQ";//邮件通知服务类型,也可以用Gmail,前提是你访问得了Gmail(必须)
exports.mailuser = "12345@qq.com";//邮箱用户名(必须)
exports.mailpass = "qqpassword";//邮箱密码(必须)
exports.mailfrom = "12345@qq.com";//发送邮件地址(必须,一般与用户名所属邮箱一致)
exports.mailto = "12345@qq.com";//接收通知邮件地址(必须)

保存,然后进入下一步。

二、爬虫用户

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

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

z_c0="LA8kJIJFdDSOA883wkUGJIRE8jVNKSOQfB9430=|1420113988|a6ea18bc1b23ea469e3b5fb2e33c2828439cb";

在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

1)getnewuser的原理是通过对比前后两天快照中用户的关注数量进行指定抓取,所以必须有了至少两次快照之后才能开始,之前就算执行也会自动跳过。

2)快照抓到一半是可以恢复的。如果程序出错崩溃,用forever stop停止它,然后加上参数-i -ng,立即执行并跳过新用户阶段就能从刚才抓到一半的快照继续下去了。

3)不要轻易增加快照抓取时的(伪)线程数,即usersnapshots中的maxthreadcount属性。线程太多会导致429错误,同时抓取回来的大量数据可能会来不及写入数据库造成内存溢出。所以,除非你的数据库搭在SSD上,线程不要超过10个。

4)saveviewfile生成分析结果的工作需要至少近7天的快照才能进行,如果快照内容少于7天会报错并跳过。此前的分析工作可以手动查询数据库进行。

5)考虑到大多数人并不需要复制一个「看知乎」,已经将自动发布wordpress文章函数入口注释掉了。如果你搭建好了wordpress,记得开启xmlrpc,然后设置一个专门用于发布文章的用户,在config.js中配置相应参数并将saveviewfile中的相关代码解除注释。

6)由于知乎对头像做了防盗链处理,我们在抓取用户信息时一并也将头像获取了下来,保存在本地,发布文章时使用的是本地头像地址。需要在http服务器中将url路径指向保存头像的文件夹,或者将保存头像的文件夹直接放到网站目录下。

7)代码可能不太容易读懂。除了node.js的回调结构本身就较混乱之外,还有一部分原因是最初写程序时我刚刚开始接触node.js,有很多不熟悉的地方导致结构混乱没有来得及改正;另一部分是在多次缝缝补补中累加了许多丑陋的判断条件和重试规则,如果全部去掉,代码量可能会下降三分之二。但这是没有办法的事,为了保障一个系统的稳定运行,必须加入这些。

8)本爬虫源码基于WTFPL协议,不对修改和发布做任何限制。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery LigerUI 使用教程表格篇(1)
Jan 18 Javascript
JavaScript起点(严格模式深度了解)
Jan 28 Javascript
js中widow.open()方法使用详解
Jul 30 Javascript
原生javascript实现图片滚动、延时加载功能
Jan 12 Javascript
JavaScript中数组的合并以及排序实现示例
Oct 24 Javascript
JQuery实现简单的服务器轮询效果实例
Mar 31 Javascript
jQuery实现的分页功能示例
Jan 22 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
Jun 21 Javascript
JS FormData上传文件的设置方法
Jul 05 Javascript
基于element-ui组件手动实现单选和上传功能
Dec 06 Javascript
js实现unicode码字符串与utf8字节数据互转详解
Mar 21 Javascript
Vue使用vue-draggable 插件在不同列表之间拖拽功能
Mar 12 Javascript
JavaScript基础知识及常用方法总结
Jan 10 #Javascript
jQuery实现的调整表格行tr上下顺序
Jan 10 #Javascript
javascript实现checkbox复选框实例代码
Jan 10 #Javascript
基于javascript实现彩票随机数生成(升级版)
Apr 17 #Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
Jan 10 #Javascript
理解Angular数据双向绑定
Jan 10 #Javascript
JavaScript表单验证实例之验证表单项是否为空
Jan 10 #Javascript
You might like
第三节--定义一个类
2006/11/16 PHP
PHP文件锁函数flock()详细介绍
2014/11/18 PHP
PHP编写文件多服务器同步程序
2016/07/02 PHP
Yii2.0 RESTful API 基础配置教程详解
2018/12/26 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
浅谈Laravel模板实体转义带来的坑
2019/10/22 PHP
PHP实现页面静态化深入讲解
2021/03/04 PHP
js 函数调用模式小结
2011/12/26 Javascript
JS刷新框架外页面七种实现代码
2013/02/18 Javascript
一个简单的瀑布流效果(主体形式自写)
2013/05/27 Javascript
Javascript实现视频轮播在pc端与移动端均可
2013/09/29 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
一分钟理解js闭包
2016/05/04 Javascript
很棒的js选项卡切换效果
2016/07/15 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
JavaScript实现获取select下拉框中第一个值的方法
2018/02/06 Javascript
JavaScript中字符串的常用操作方法及特殊字符
2018/03/18 Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
2018/08/12 Javascript
JavaScript原型式继承实现方法
2019/11/06 Javascript
javascript实现前端成语点击验证优化
2020/06/24 Javascript
浅谈python和C语言混编的几种方式(推荐)
2017/09/27 Python
用Python一键搭建Http服务器的方法
2018/06/01 Python
Pycharm以root权限运行脚本的方法
2019/01/19 Python
Python3按一定数据位数格式处理bin文件的方法
2019/01/24 Python
Python单元测试工具doctest和unittest使用解析
2019/09/02 Python
Python中xml和dict格式转换的示例代码
2019/11/07 Python
将python安装信息加入注册表的示例
2019/11/20 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
Python Tornado之跨域请求与Options请求方式
2020/03/28 Python
python 实现图片批量压缩的示例
2020/12/18 Python
英国经济型酒店品牌:Travelodge
2019/12/17 全球购物
医学护理毕业生自荐信
2013/11/07 职场文书
试用期转正员工自我评价
2014/09/18 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
干货:企业内部人才推荐奖励方案!
2019/07/09 职场文书
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang