CasperJS中函数内的querySelectorAll(variable)没有返回任何结果

4

我正在编写一个网站爬虫,从一个没有实际链接,只有可点击文本的ajax网站上获取一些特定内容。我只使用了大约一周的javascript,并使用CasperJS,因为它可以减少很多工作。

我遇到的问题是我正在编写多个函数,它们都做同样的事情,只是根据所在页面搜索不同的链接。所以我有:

function getLinks() {
    var links = document.querySelectorAll('div.AjaxLink h3');
    return Array.prototype.map.call(links, function(link) {
        return link.innerText;
    });
}

它是通过以下方式运行的:

casper.then(function() {
    var myLinks = this.evaulate(getLinks);
    /* ... link manipulation code code ... */
});

这个工作很好。显然,我不想有半打函数只是有不同的查询字符串。所以我想做的是:

function getLinks(findText) {
    var links = document.querySelectorAll(findText);
    return Array.prototype.map.call(links, function(link) {
        return link.innerText;
    });
}

然后我尝试通过以下方式运行它:

casper.then(function() {
    var myLinks = getLinks('div.AjaxLink h3');
    /* ... link manipulation code code ... */
});

findText变量已正确传入,但似乎查询选择器总是返回空的NodeList。

我做错了什么?document是在该函数内创建的空文档吗?

1个回答

6
CasperJS是建立在PhantomJS之上的。PhantomJS有两个上下文。通过evaluate()可以访问沙盒页面上下文,而外部上下文则可以访问requirephantom。奇怪的是,这两个上下文都可以访问windowdocument,但是在外部上下文中,document没有任何意义,因为DOM为空。这就是为什么querySelectorAll()找不到元素的原因。页面DOM只能通过evaluate()访问。
因此,您需要在casper.evaluate()中执行函数。您函数的额外参数将传递给evaluate()而不是您的函数:
function getLinks(findText) {
    ...
}

casper.then(function() {
    var myLinks = this.evaluate(getLinks, 'div.AjaxLink h3'); // THIS
    ...
});

evaluate页面底部还有一个重要的注意事项:

注意:evaluate函数的参数和返回值必须是简单基本对象。一般的原则是:如果可以通过JSON序列化,那么就没问题。

闭包、函数、DOM节点等都是不可用的!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接