从evaluate方法访问CasperJS变量

时间:2015-07-24 18:35:08

标签: phantomjs casperjs

我正在试图抓一个网站。我有一个网站,其中有一个select元素,因此在选择元素后,另一个选择框会动态显示,等等。

我可以使用waitForSelector方法,但我不知道动态元素的id,或者我可以使用wait等待几秒钟。< / p>

但是,对于动态加载的内容,页面将发送ajax请求。我使用函数onResourceRequestonResourceReceived来保持计数,这样无论何时请求资源,我都会增加计数,在事件reource.receivedonResourceError之后,我可以减少计数计算并检查如果计数为0,我将继续前进或者等待请求完成。

但是我使用evaluate方法抓取页面,并且我增加和减少计数的变量在CasperJS上下文中。我应该如何从evaluate函数访问CasperJS中声明的变量,以便检查是否所有请求都已完成。

1 个答案:

答案 0 :(得分:2)

由于evaluate()是沙箱,因此无法直接访问外部定义的变量。有多种方法可以将数据传递出页面上下文(控制台消息,警报,page.onCallbackevaluate()结果),但只有一种方法可以传入数据,直接将数据传递给evaluate()作为论据。

问题是你如何传递它以便你的脚本有意义。

每次传递

每当你在需要该变量的页面上下文中执行某些操作时,就可以将其传入。当您在使用该信息之前执行大量异步工作时,这可能无法正常工作,因为它在那时可能是陈旧的。 / p>

主动将其放入页面上下文

每当该计数发生变化时,您可以将该信息放入页面上下文中的全局范围:

// do this inside of the `reource.received` and `onResourceError` events
casper.evaluate(function(count){
    window._myCount = count;
}, count);

然后,只要您需要在页面上下文中使用该信息,您只需要访问window._myCount中已有的信息。

您可以或多或少地自由嵌套waitForSelector()

等步骤
casper.waitForSelector(selector1, function(){
    var dynamicId = this.evaluate(function(){
        ...
        return dynId;
    });
    this.waitForSelector("#" + dynamicId);
});

casper.then(function(){
    // this is only executed when the previous `"#" + dynamicId` was found
});