函数中的CasperJS querySelectorAll(变量)不返回任何结果

dcm*_*own 4 javascript selectors-api phantomjs casperjs

我正在编写一个站点刮板来从ajax站点获取一些特定内容而没有实际链接,只有可点击的文本.我现在只使用javascript大约一个星期,并且正在使用CasperJS,因为它会减少很多工作.

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

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

它的运行方式是:

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

这很好用.我显然不希望有六个函数只有一个不同的查询字符串.所以我想做的是:

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

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

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

findText变量正确传入但看起来查询选择器总是返回一个空的NodeList.

我究竟做错了什么?是记录该函数内部创建了一个空文件?

Art*_* B. 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
    ...
});
Run Code Online (Sandbox Code Playgroud)

evaluate页面底部还有一个重要说明:

注意:函数的参数和返回值evaluate必须是简单的原始对象.经验法则:如果它可以通过JSON序列化,那么它很好.

闭包功能,DOM节点等,将工作!