我有一个网页,其中包含以下格式的信息:
<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();
然而,我只是得到一个'[]'作为答案。
有人可以帮我找到代码中的错误吗?
答案 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节点等将不工作!