casperjs爬虫总结 -- (2) casperjs
1. 为什么简单的request请求不够
作为爬虫,估计直接request是第一想法
但是现代的web,有很多数据不是在一个request里就全部包含了,还有很多是通过js和ajax请求来获取的,所以我们需要一个虚拟的浏览器来模拟
2. 简介phantom
官网:
http://phantomjs.org/
phantom是一个可以通过js api来编程的"无头"(headless)浏览器
它就如一个真实的浏览器,但是因为"无头",所以它可以运行的更快
它的应用场景比如:
web测试
抓屏
页面自动化操作
等等...
我们来看一段示例代码:
解释:
自己动手写一个"抓屏新浪主页"的程序
备注:phantom使用js来编程,同时看上去很像nodejs模块,但是它不是
3. casperjs
官网:
http://casperjs.org/
casperjs跟phantom的关系,用一个不恰当的比喻来说,就是jquery跟js的关系
casperjs优化了phantom的api操作,使之操作更加的简单
看个例子:
解释:
1 casper在start的时候,并没有直接就开始去访问页面了,所有的运行都必须用run方法来开启
2 thenOpen这样的方法,保证了异步调用的秩序.
在这里,casper的动作秩序如下
访问'http://casperjs.org/'
在回调中echo(打印)出页面的title
再访问'http://phantomjs.org'
再在回调中echo(打印)出页面的title
4. 重要概念沙箱
先看phantom官方代码:
来源->http://phantomjs.org/api/webpage/method/evaluate.html
解释:
当我们的phantom实例page访问了一个url,从而得到"填充"了的page
我们想对page中的元素进行梳理,返回信息等等操作,从源头上说,都是通过evaluate这个方法
evaluate构建了一个"沙箱",从而隔离出了一个新的js环境,导致外部的变量是不能在"沙箱"中访问的
如果要访问,则必须在evaluate函数的后面参数上挂上实参
如上例中,就把'title'传给了evaluate函数的s形参
官方原文对这个传入的实参的要求说的很清楚:
(原文)
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
简单原始的对象可以被传入,怎么样才算"简单原始"呢,就是可以json化
反过来说,"闭包","函数","dom节点"这样是不能工作的
在最后,官方也介绍了另一种可以从沙箱中获取消息的方式,就是使用事件
沙箱里,在控制台输出信息,沙箱外可以通过监听控制台来获取信息
1. 为什么简单的request请求不够
作为爬虫,估计直接request是第一想法
但是现代的web,有很多数据不是在一个request里就全部包含了,还有很多是通过js和ajax请求来获取的,所以我们需要一个虚拟的浏览器来模拟
2. 简介phantom
官网:
http://phantomjs.org/
phantom是一个可以通过js api来编程的"无头"(headless)浏览器
它就如一个真实的浏览器,但是因为"无头",所以它可以运行的更快
它的应用场景比如:
web测试
抓屏
页面自动化操作
等等...
我们来看一段示例代码:
console.log('Loading a web page');
var page = require('webpage').create();
var url = 'http://phantomjs.org/';
page.open(url, function (status) {
//Page is loaded!
phantom.exit();
});
解释:
var page = require('webpage').create();
生成一个webpage的实例,你可以理解为一个"浏览器"
page.open(url, function (status) {
});
打开一个url,后面的function是其回调
phantom.exit();
退出phantom
自己动手写一个"抓屏新浪主页"的程序
var page = require("webpage").create();
page.open("http://www.sina.com.cn",function(){
page.render('sinaThumb.png');
phantom.exit();
});
使用了render方法,因为新浪首页内容很多,所以比较耗时
方法结束后,会有一个png图出现在当前文件夹备注:phantom使用js来编程,同时看上去很像nodejs模块,但是它不是
3. casperjs
官网:
http://casperjs.org/
casperjs跟phantom的关系,用一个不恰当的比喻来说,就是jquery跟js的关系
casperjs优化了phantom的api操作,使之操作更加的简单
看个例子:
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 casper在start的时候,并没有直接就开始去访问页面了,所有的运行都必须用run方法来开启
2 thenOpen这样的方法,保证了异步调用的秩序.
在这里,casper的动作秩序如下
访问'http://casperjs.org/'
在回调中echo(打印)出页面的title
再访问'http://phantomjs.org'
再在回调中echo(打印)出页面的title
4. 重要概念沙箱
先看phantom官方代码:
来源->http://phantomjs.org/api/webpage/method/evaluate.html
page.open('http://m.bing.com', function(status) {
var title = page.evaluate(function(s) {
return document.querySelector(s).innerText;
}, 'title');
console.log(title);
phantom.exit();
});
解释:
当我们的phantom实例page访问了一个url,从而得到"填充"了的page
我们想对page中的元素进行梳理,返回信息等等操作,从源头上说,都是通过evaluate这个方法
evaluate构建了一个"沙箱",从而隔离出了一个新的js环境,导致外部的变量是不能在"沙箱"中访问的
如果要访问,则必须在evaluate函数的后面参数上挂上实参
如上例中,就把'title'传给了evaluate函数的s形参
官方原文对这个传入的实参的要求说的很清楚:
(原文)
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
简单原始的对象可以被传入,怎么样才算"简单原始"呢,就是可以json化
反过来说,"闭包","函数","dom节点"这样是不能工作的
在最后,官方也介绍了另一种可以从沙箱中获取消息的方式,就是使用事件
var webPage = require('webpage');
var page = webPage.create();
page.onConsoleMessage = function(msg) {
console.log(msg);
}
page.open('http://m.bing.com', function(status) {
page.evaluate(function() {
console.log(document.title);
});
phantom.exit();
});
沙箱里,在控制台输出信息,沙箱外可以通过监听控制台来获取信息
以上虽然在说phantom,但是因为casper基于它,所以道理是互通的
最后附图抓取新浪的截图: