关闭

为什么casperjs比phantomjs好

2176人阅读 评论(0) 收藏 举报
分类:

本文翻译自这篇文章


页面浏览

用CasperJS浏览页面比用PhantomJS更加方便和直观。
例如,先后打开webpage A,然后webpage B
用CasperJS的话,你可以这样写:

casper.start('URL of website A', function(){
    console.log('Started');
});
casper.thenOpen('URL of website B', function(){
    console.log('Started');
});
casper.then(function(){
    this.evaluate(function(){
        //Your code here
    })
})
casper.run();

所以,用CasperJS可以非常简单地打开A站点,然后B站点。
关键在于这样写之后,网站B不会在网站A完全加载完成前打开。
这是个很好的功能,而且并没有在PhantomJS中实现。
如果你使用PhantomJS,你必须通过监听内容加载相关的事件来处理。
我们可以看下,如果用PhantomJS来完成同样功能需要怎么实现:

var steps=[];
var testindex = 0;
var loadInProgress = false;//This is set to true when a page is still loading
var clientRequests = new DRequest();

console.log("Initialization successful");
steps=[
    function (){//Step 1 - Load Code Epicenter
        console.log("Request a website and wait for website to load");
        clientRequests.sendRequest("http://photo-epicenter.com");
    },
    function(){//STEP 2 - After page load, parse results. DO NOT CALL readResponse() IN STEP ONE, because our RESULT might be empty
        console.log("Website loaded, read response");
        clientRequests.readResponse();
        var fs = require("fs");
        console.log("Write data to file");
        fs.write("website.html",clientRequests.getResponse(),"w");
    }
];
//Start interval to read website content
interval = setInterval(executeRequestsStepByStep,2000);

function executeRequestsStepByStep(){
    if (loadInProgress == false && typeof steps[testindex] == "function") {
        console.log("step " + (testindex + 1));
        steps[testindex]();
        testindex++;
    }
    if (typeof steps[testindex] != "function") {
        console.log("test complete!");
        phantom.exit();
    }
}

/**
* These listeners are very important in order to phantom work properly. Using these listeners, we control loadInProgress marker which controls, weather a page is fully loaded.
* Without this, we will get content of the page, even a page is not fully loaded.
*/
clientRequests.phantomPage.onLoadStarted = function() {
    loadInProgress = true;
    console.log(loadInProgress);
    console.log("Loading started");
};
clientRequests.phantomPage.onLoadFinished = function() {
    loadInProgress = false;
    console.log("Loading finished");
};
clientRequests.phantomPage.onConsoleMessage = function(msg) {
    console.log(msg);
};      

这将需要更多的代码,需要指出的是,这代码是前作者写的。
也许有更好的方案,但是,请相信我,这代码已经近乎优秀。

如果你想做的更多,不只是普通的从A页面到B页面,这代码就会变得更加复杂。并使得代码的维护成为一个噩梦。

两个库都会在发往后续请求时,将已经收到的cookie附加上去。
这一点对于登入之后的页面爬取非常有用。

code maintenance (代码维护)

很明显,CasperJS使用更为直观的语法会让你更加容易的维护你的脚本。同时,CasperJS拥有很多有用的功能,比如函数thenClick,它将元素的xpath作为第一个参数,这一点在你想点击菜单项时非常有用。通过chrome你可以取到元素的xpath值,只需要将它复制给CasperJS脚本。CasperJS脚本会模拟点击事件,你就会被重定向到希望的页面。如果你需要修改脚本让其和其他网站一起工作,你只需要修改xpaths。

在CasperJS中有很非常方便而且在phantomjs中没有实现的函数,参考这些API

File Download(文件下载)

在我们讨论PhantomJS时,这是一个热门话题,只少有20片文章在讨论怎么使用PhantomJS 来下载文件,有两个可行的方法:
* 在你的evaluate函数里调用ajax 请求下载,然后编码你的文件,然后你再将内容返回给PhantomJS脚本。
* 你可以使用在GitHut上没有编译的PhantomJS代码。

这两种办法都不能100%保证文件能正常下载,并且还有一个问题,当你不想保存下载的文件文件系统时(比如你不允许保存下载的数据到你的电脑上),想通过PhantomJS来完成几乎是不可能的。我的建议是,不要使用PhantomJS 来下载文件。

通过CasperJS,文件下载是非常容易的,因为CasperJS 提供下载的函数用来把文件下载到文件系统,或者对你想处理而不想保存的文件湖北续进行base64编码。

下面是base64编码的例子:

casper.start('http://www.google.fr/', function() {
    base64logo = this.base64encode('http://www.google.fr/images/srpr/logo3w.png');
});

casper.run(function() {
    this.echo(base64logo).exit();
});

下面这个例子演示如何通过CasperJS来下载csv文件而不把文件保存到文件系统:
var casper = require(‘casper’).create();

casper.start("http://captaincoffee.com.au/dump/", function() {
    this.echo(this.getTitle())
});
casper.then(function(){
    var url = 'http://captaincoffee.com.au/dump/csv.csv';
    require('utils').dump(this.base64encode(url, 'get'));
});
casper.run();

总结

PhantomJS和CasperJS都能完成不错的工作,但是你如果可以选择两者中的一个,我建议你使用CasperJS,因为你将会得到更好至少同样好的效果而不需要太多的付出。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    文章分类