获取链接网址
DOM 元素的属性和属性是有区别的。如果您有一个位于域http://example.com 上的网站,并且您希望在该页面上获得以下链接的href
<a href="/path/to/stuff">text</a>
如果您使用aElement.getAttribute("href"),您将获得"/path/to/stuff",但如果您使用aElement.href,您将获得计算得到的URL "http://example.com/path/to/stuff"。只有后者是 CasperJS(实际上是 PhantomJS)能够理解的 URL。
我告诉你这一点,因为casper.getElementsAttribute() 在内部使用element.getAttribute() 方法,该方法会生成无法用casper.thenOpen() 打开的URL。
修复很简单:
var urls = casper.evaluate(function(){
return [].map.call(document.querySelectorAll('a[href]'), function(a){
return a.href;
});
});
此外,您可能希望将casper.on() 事件注册移到casper.eachThen() 调用之上。您不需要在每次迭代中都注册事件。
注册链接超时
由于您遇到了某些 URL 无法加载的问题(可能是因为它们已损坏),您可以使用 casper.options.stepTimeout 设置步骤超时,这样 CasperJS 就不会在某些无法检索的 URL 上冻结。还需要定义onStepTimeout()回调,否则CasperJS会退出。
casper.then(function() {
var currentURL;
casper.options.stepTimeout = 10000; // 10 seconds
casper.options.onStepTimeout = function(timeout, stepNum){
this.echo('wait, this url timed out: ' + currentURL);
};
var urls = this.evaluate(function(){
return [].map.call(document.querySelectorAll('a[href]'), function(a){
return a.href;
});
});
this.on('http.status.404', function(resource) {
this.echo('wait, this url is 404: ' + resource.url);
});
urls.forEach(function(link) {
this.then(function(){
currentURL = link;
});
this.thenOpen(link, function(response) {
if (response == undefined || response.status >= 400) {
this.echo("failed: " + link);
}
});
});
});