最近几个月有用爬虫去爬一些内容的需求,所以调查了许多爬虫框架然后实现了一些爬虫内容,这里做个笔记。首先是语言和框架的选择,最开始尝试了java的jsoup拿来做DOM以及htmlunit

最近几个月有用爬虫去爬一些内容的需求,所以调查了许多爬虫框架然后实现了一些爬虫内容,这里做个笔记。

首先是语言和框架的选择,最开始尝试了java的jsoup拿来做DOM以及htmlunit拿来执行js之类的,试了一下发现htmlunit对js的支持不完整。举个例子,普通的discuz的bbs的登录界面有部分js处理,这里htmlunit就无法正确处理js导致登录失败。其实我目前的任务并不需要做登录操作的,因为我直接在chrome登录好,然后导出cookie拿给爬虫用就OK了。不过这只是比较简单的情况,如果任务多了就可能被反爬虫而且需要自动登录,所以我想尝试一下。我认为爬虫的根本在于完全模拟浏览器的操作,一部分人去分析反爬虫机制中的关键js代码或者post的数据,我认为这是得不偿失的。既然htmlunit对js的支持很差,于是我又尝试了一下selenium2,用了一下效果很好,这里记录一下。

selenium2有各种语言的绑定以及浏览器绑定,我由于可能最终代码需要部署在vps上,所以选择了facebook维护的php的绑定,也就是php-webdriver。php-webdriver老实说文档比较匮乏,不过好在里面的API和selenium2原生的比较像,而且eclipse有自动补全所以用起来还是比较顺利的。浏览器端我主要试了firefox和phantomjs,用下来一个感受就是selenium2的确是反反爬虫的利器,不用去分析js机制,浏览器怎么操作我就怎么模拟,而且很方便bebug,因为发生了什么你浏览器看的一清二楚。但是缺点就是因为加载了包括html、图片、js、css在内的所有资源,所以速度比较慢、占带块、吃cpu吃内存,不过好在有headless的浏览器phantomjs在。我试了一下phantomjs,内存和cpu消耗小了很多,而且headless的浏览器完全可以部署在linux系统的vps上,特别适合生产环境。

那么接下来再谈谈Goutte这个php框架吧,其实这个框架是对HttpGuzzle和symphony框架下dom相关组件的轻封装,同样缺乏文档,但是在stackoverflow上是很流行的php爬虫框架。当然了作为纯的php框架肯定是不支持js执行的,我要爬的内容并没有做太多反爬虫所以就已经够用了。因为很多内容需要登录但是用php去实现登录是比较困难的,所以我选择了在chrome里面登录然后导出cookie给爬虫来直接登录。具体用php写爬虫业务没什么好写的,这里我只写一些我遇到的坑:

首先,就是所有的爬虫的过程都要用try包含起来处理异常,因为爬得过程也好,处理返回的html的dom操作获取html元素内容也好,总是会遇到各种异常,往往我们都不希望出现这种情况。

第二个因为php执行有命令行和浏览器访问2种方式,一般写爬虫都会做一个页面然后填一些参数post到对应的php爬虫页面执行,而爬的过程又是很长的,所以基本大家都会在任务开始的时候加上:set_time_limit ( 0 );我也是这样的,但是慢慢的就发现有时候我的爬虫任务还是莫名其妙的停止执行了。去php-fpm的log里面也没有看到停止执行的error log,查了半天发现原来如果用户浏览器和服务器连接中断或者停止访问了,那么正在执行的php脚本也会退出,所以加上:ignore_user_abort(true);这样就可以完全无视用户独立爬了。

第三个就是,php脚本输出的内容不会立即刷新到页面,而是会缓存的自己的缓冲区,我们可以通过ob_implicit_flush ( true );ob_start ();ob_flush ();几个函数来刷新缓冲区,实际上我本地XAMPP开发环境工作的很好,但是我部署到vps上的时候就不行了。因为nginx服务器也有自己的缓冲区,但是你php脚本是无法去控制nginx的缓冲区的。怎么办呢,只要输出很多空白字符来填满nginx的缓冲区,试了一下我的vps大约没5000个字节的输出就会被nginx返回到浏览器。

第四个就是,很多时候浏览器和服务器的连接可能断开,这个时候爬虫还是在执行可以你却无法得到输出,当然了可以把输出放到数据库里面再写个脚本去读数据库内容,不过我只是简单的把输出定向到一个txt,通过访问txt就能知道目前爬虫的进度如何。嘛,不是办法的办法。

第五个就是Deprecate问题了,php在升级版本的过程中许多函数弃用了,比如php5.5开始就把preg_replace的/e特性作为Deprecate的了,我原本的代码用太多的这个特性,改了一段时间发现实在改不过来,于是直接关闭error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);

第六个就是Goutte去爬的数据的时候的假死问题,有时候浏览器去打开一张图如果网络不好可能下载了一半就死了。这个对于爬虫来说就相当于永远的卡在这里了,所以Goutte里面的HttpGuzzle客户端去下载资源的时候最好设置一个timeout,因为超时会抛出异常所以注意catch起来。另外去下载资源的时候,加上原网站的referer是个好习惯,很多资源是cdn发布的只认原站点的referer才行,我也是stackoverflow上问一下才搞明白。

最后一个就是我有一些数据需要持久化,但是又没必要放进数据库里面,所以把这部分数据做成json存入文件是最好的。但是php的json_encode函数接口有个特性就是,这个接口默认会把数组里面用数字做key的转化成json里的list,然后字符串做key的转化成json里的object,这并没有问题。但是json_decode就会把object转化成php里的对象也就是StdClass,把list转化成数组。我一个php数组json_encode再json_decode回来就有了StdClass,导致原来处理数组的逻辑去处理StdClass出错。我原本是很小心让数组的key不是字符串,然后发现json_decode第二个参数就是全部decode成数组的,本来好好读文档就解决的问题浪费了许多时间。

来源 http://qsalg.com/?p=294

最新资讯
特斯拉缩减董事会成员 马斯克的三个盟友将离开

特斯拉缩减董事会成员

特斯拉表示,将在今明两年把董事会从11名董事缩减至7名,
欧洲消费者组织敦促监管机构对Facebook展开联合审查

欧洲消费者组织敦促监

欧洲消费者组织BEUC敦促欧盟反垄断监管机构和隐私保护
名不见经传的Zoom为什么比独角兽Pinterest表现惊艳

名不见经传的Zoom为什

直到最近,除了各公司的IT部门,很少有人听说过Zoom Video
三星手机重返“中国战场” 在全球重建“护城河”

三星手机重返“中国战

在线下渠道商话语权越来越重的背景下,本就存在渠道问题
涉嫌隐瞒事实 苹果又吃官司连库克都成被告

涉嫌隐瞒事实 苹果又

库克与苹果首席财务官卢卡·马埃斯特里也被列为这项集
美图退出手机江湖台前幕后 独立小众品牌的宿命?

美图退出手机江湖台前

是时候说再见了。这让业界唏嘘,在酷派淡出、金立破产、
最新文章
HTML5 WebSocket技术使用详解

HTML5 WebSocket技术

本文为大家详细介绍了WebSocket技术使用方法,WebSocke
详解XSS 和 CSRF简述及预防措施

详解XSS 和 CSRF简述

这篇文章主要介绍了XSS 和 CSRF简述及预防措施,小编觉
详解WEB攻击之CSRF攻击与防护

详解WEB攻击之CSRF攻

这篇文章主要介绍了详解WEB攻击之CSRF攻击与防护,小编
分析攻击IP来源地与防御IP攻击的应对策略

分析攻击IP来源地与防

今天小编就为大家分享一篇关于分析攻击IP来源地并画出
文本数据的机器学习自动分类方法(下)

文本数据的机器学习自

本文为第二部分,着重介绍特征向量权重的影响因素以及样
文本数据的机器学习自动分类方法(上)

文本数据的机器学习自

本文为第一部分,着重介绍文本预处理以及特征抽取的方