函数 returns 中的 CasperJS querySelectorAll(variable) 没有结果

CasperJS querySelectorAll(variable) in function returns no results

我正在编写一个站点抓取工具,以从 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 变量已正确传递,但查询选择器似乎总是 returns 一个空的 NodeList。

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

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页面底部还有一条重要提示:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!