标签: 爬虫 casperjs phantomjs
编 写:袁 亮
时 间:2016-08-30
说 明:如何使用CasperJs抓取商品数据
一、目的
抓取天猫、淘宝、京东的相应商品数据
抓取商品名、价格、轮播图、详情、产品属性等数据
二、方案选择
1、情况分析
1.1 对应的页面数据很多都是后加载的
1.2 页面请求很多,想找到其对应的ajax请求比较麻烦
1.3 ajax请求的地址是服务端生成的,不能通过简单的拼接来生成
1.4 对正则水平要求较高,很多请求地址是写在js里的
2、可选方案
2.1 php等语言,直接发钱http请求,然后通过正则匹配等方式,找到响应数据源
curl、phpquery、Snopy等等
2.2 使用浏览器实际访问,然后获取浏览器的最终结果数据
phantomJS
casperJS + phantomJS
python + selenium + phantomJS
3、选用方案 casperJS + phantomJS
3.1 纯JS,方便前后端使用
3.2 Casper封装的比较友好、文档齐全,比较好用
特别是针对后加载的元素,之间waitForSelector的方法非常方便
可以引入jquery等自己的js文件,方便dom操作
3.3 获取数据,只需要在浏览器打开的时候,找到对应的节点选择器即可
3.4 安装部署方便
三、简单例子
var casper = require('casper').create();
casper.start('http://casperjs.org/', function() {
this.echo(this.getTitle());
});
casper.thenOpen('http://phantomjs.org', function() {
this.echo(this.getTitle());
});
casper.run();
四、环境部署 (非源码安装)
1、安装phantomjs
1.1 下载安装
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
1.2 解压
tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2
1.3 做软连接,放在环境变量里,比如(注意权限问题,如果需要apache调用,更要注意)
ln -s /opt/ci123/phantomjs/bin/phantomjs /usr/local/sbin/
1.4 测试运行
phantomjs --version
2、安装casperjs
2.1 选择相应版本下载
wget https://github.com/casperjs/casperjs/archive/1.1.3.zip
2.2 解压
unzip 1.1.3.zip
2.3 做软连接,放在环境变量里,比如(注意权限问题,如果需要apache调用,更要注意)
ln -s /opt/ci123/casper/bin/casperjs /usr/bin/casperjs
2.4 测试是否正常
casperjs --version
五、实际使用
1、apache调用php
2、php根据url调用不同的CasperJS,传入要抓取的url
3、Casper输出json数据
4、php使用exec调用,并获取casper的输出
5、php将相应的json输出返回apache或者存入数据库等等
演示代码:
192.168.0.249
/opt/ci123/www/html/yuanliang/casper/fetch
六、踩过的坑
1、抓取https的时候,249上一直失败
原因:
249上的ssl配置应该问题,导致抓取部分https网站的时候,一直报错
解决办法:
a:CasperJS需要较高版本才能用
casperjs --ignore-ssl-errors=yes --ssl-protocol=any xxx.js
phantomjs --ssl-protocol=any xxx.js
b:升级249上的ca证书或者openssl版本
2、抓取速度太慢
原因:
这个工具本质是一个无界面的浏览器,因此里面的所有资源都跟浏览器一样,会去加载,图片等资源较多的时候会卡
解决办法:
设置不加载图片 loadImages:false
3、clientScripts 注入远程jquery文件无效
原因:
只能加载本地的js文件,不能加载远程的js文件
解决办法:
可以下载到本地,或者使用remoteScripts来加载,这个可以使用远程文件
不过使用本地文件比较好,少一次http请求,速度会快很多
4、淘宝的后加载数据一直获取不到
原因:
之前https的出问题的时候,以为是ua有问题,所以设置了一个chrome的ua,但是实际上内核不一样
导致淘宝本身的js执行失败,数据加载不出来
解决办法:
去掉ua设置即可
5、天猫的后加载数据(详情)一直加载不出来,报语法错误
原因:
天猫的代码中,如何屏幕大小超过1260,会执行一段JS,这段JS会出错
解决办法:
设置屏幕宽度小于1260即可
6、waitForSelector获取某个数据,超时,导致后面都不执行了
原因:
默认的timeout处理函数,会直接将整个进程中止,后面的所有代码都不执行
解决办法:
如果可以接受部分字段抓取不到,则可以在waitForSelector中自行设置timeout处理函数,不中止
如果需要全部抓取才算结束,可以在timeout的时候触发一个报警等来通知
7、根据浏览器的元素定位,返回不了相应的数据
原因:
浏览器最终呈现的元素,有些跟phantomJs返回的不一样
比如图片后加载,这是在页面滚动到一定位置之后才会触发的
解决办法:
如图片后加载这种,数据其实已经返回了,只是存在其他地方,可以返回对应的html,然后看数据存储在哪个字段上
如果有些是点击、滚动等之后,从服务端获取的数据,那就需要模拟浏览器的点击滚动等事件,然后获取,比较少见
8、执行获取页面数据的时候,失败报错
原因:
页面代码执行在不同的沙箱中,在CasperJS本身是读取不到的
解决办法:
均在this.evaluate函数中执行,在内部可用操作所有的DOM,跟页面执行JS效果一样
9、天猫商品详情图片一直抓取不对
原因:
图片本身是后加载的,之前数据是放在data-ks-lazyload中,后加载执行之后,这个data被干掉了
直接取src也会有问题,因为有的时候取数据的时候,后加载js还没执行到
所以导致一会好一会坏
解决办法:
先取data-ks-lazyload,如果没有,则去src数据
七、注意事项
1、debug的时候,可用通过将当前页面截图出来,方便查看加载到什么情况了
也可以将完整的html输出到文件里查看
2、打印json数据,方便跟php等交互
打印数据
casper.then(function(){
require('utils').dump(data);
});
3、注意很多异步操作,很多时候,执行效果会跟预期不一样
4、当Casper运行结果跟预期不一样的时候,可以考虑直接写相应的phantomJs做对应小块功能来调试
5、淘宝url等在命令行传参会出错,需要用单引号包含起来
八、参考资料
1、CasperJS 官方文档
http://docs.casperjs.org/en/latest/index.html
2、phantomJS 文档
http://phantomjs.org/documentation/
3、PhantomJS基础及示例
http://imweb.io/topic/560b402ac2317a8c3e08621c
4、casperjs模拟登陆https页面获取当前面地址后发现为about:blank问题排查
http://www.bubuko.com/infodetail-1018663.html
5、 Linux使用curl访问https站点时报错汇总
http://www.ipcpu.com/2014/12/curl-https-error/