如何通过CasperJS从具有特定类的元素中获取hrefs?

时间:2015-04-11 17:19:41

标签: javascript css-selectors casperjs

我有一个网页,其中包含以下格式的信息:

<p>
    <a class="class1" href="href1">text1</a>
    text2
</p>

<p>
    <a class="class1" href="href2">text1a</a>
    text2a
</p>

使用CasperJS,我需要以这种格式获取包含 class1 的元素中包含的所有信息的数组:

href1
text1
text2

href2
text1a
text2a

我尝试过使用此代码:

var casper = require('casper').create();
casper.start('url', function() {
    require('utils').dump(this.getElementsAttribute('div[class="class1"]', 
          'class'));
});
casper.run();

然而,我只是得到一个'[]'作为答案。

有人可以帮我找到代码中的错误吗?

1 个答案:

答案 0 :(得分:1)

div[class="class1"]作为选择器无法正常工作,因为您的标记中没有<div>class1类的元素。您可以尝试以下方法,但它不会让您走得太远:

this.getElementsAttribute('a.class1', 'href');

在页面上下文中构建对象数组

仅使用CasperJS功能很难并且可能容易出错。通过迭代所有链接并获取所需的部分,可以更轻松地完成此任务。

casper.then(function(){
    var info = this.evaluate(function(){
        var links = document.querySelectorAll(".class1");
        // iterate over links and collect stuff
        return Array.prototype.map.call(links, function(link){
            return {
                href: link.href,
                hrefText: link.textContent.trim(),
                afterText: link.parentNode.childNodes[2].textContent.trim()
            };
        });
    });
    require('utils').dump(info);
});

这是如何运作的:

您可以通过使用class1查询所有元素的全部内容来获取所有链接。由于querySelectorAll()的结果不是数组,而是类似数组的NodeList,因此无法直接使用.map()

每个链接都有href属性和textContent属性。链接后的文字有点棘手。首先需要获取链接的父级(<p>),然后通过访问childNodes属性来尝试获取链接后的TextNode。

必须使用

childNodes[2]而不是childNodes[1],因为第一个(childNodes[0])可能是一个包含空格的TextNode,所以在它移动后的所有内容。

在页面上下文中构建单个字符串

您也可以迭代它以文本表示形式获取它:

casper.then(function(){
    var info = this.evaluate(function(){
        var links = document.querySelectorAll(".class1");
        // iterate over links and collect stuff
        return Array.prototype.map.call(links, function(link){
            return [
                link.href,
                link.textContent.trim(),
                link.parentNode.childNodes[2].textContent.trim()
            ].join('\n');
        }).join('\n\n');
    });
    this.echo(info);
});

工作原理:

JavaScript数组有join() function。它可以使用指定的分隔符连接每个元素。


请记住,页面上下文(evaluate())是沙箱。 documentation说:

  

注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。

     

闭包,函数,DOM节点等将工作!