【问题标题】:How to check broken links in a webpage using Casperjs?如何使用 Casperjs 检查网页中损坏的链接?
【发布时间】:2015-08-03 11:43:41
【问题描述】:

我想使用 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 多个链接。我的代码没有完成它的执行并且在一些链接之后保持空闲。它没有给我任何回应。我不明白为什么会这样?

【问题讨论】:

    标签: javascript hyperlink casperjs broken-links


    【解决方案1】:

    获取链接网址

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

    【讨论】:

    • 我的页面包含所有绝对 URL。我一次将一个 URL 传递给 thenOpen 并检查它们的状态。但是我的代码再次没有完成它的执行并且在一些链接之后保持空闲。那么我如何处理这个?
    • 我不知道你的脚本为什么闲置。最后打开的 URL 有什么特别之处吗?是否总是相同的 URL 导致它空闲?请注册resource.errorpage.errorremote.messagecasper.page.onResourceTimeout 活动 (Example)。可能有错误。
    • 没有网址不一样。我注册了所有事件,但它没有给我任何错误。但在一些链接之后它再次空闲。我不明白该怎么办?
    • 我不明白为什么我的脚本空闲。是由于我的网络连接或任何其他原因。我不明白该怎么办?
    • 我不知道该告诉你什么。您是否尝试过切换到另一个 PhantomJS 版本?尝试 1.9.8 和 2.0.0。如果您通过 npm 安装 CasperJS,请记住它还会安装旧版本的 PhantomJS。您应该一次将其他 PhantomJS 版本放在 PATH 上。
    猜你喜欢
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2012-05-12
    • 2010-12-08
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    相关资源
    最近更新 更多