如何使用Casperjs检查网页中的断开链接

How to check broken links in a webpage using Casperjs?

本文关键字:断开 链接 网页 何使用 Casperjs 检查      更新时间:2023-09-26

我想检查使用casperjs的网页中存在的所有断开链接。我写了下面的代码,但它不工作:

casper.then(function() {
     var urls=casper.getElementsAttribute('a[href]', 'href');
    casper.eachThen(urls, function(response) {
        var  link=response.data;
        this.thenOpen(demourl, function(response) { 
             if (response == undefined || response.status >= 400) {
                this.echo("failed");
            }
        })
        this.on('http.status.404', function(resource) {
            this.echo('wait, this url is 404: ' + resource.url);
        })
    })
})

我的网页由400多个链接组成。我的代码没有完成它的执行,并在一些链接后保持空闲。它没有给我任何回应。我不明白为什么会这样?

获取链接url

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);
            }
        });
    });
});