从 evaluate 方法访问 CasperJS 变量

Access CasperJS variable from evaluate method

我正在尝试抓取网站。我有一个网站,其中有一个 select 元素,所以在 select 元素之后,另一个 select 框会动态出现,依此类推。

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

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

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

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

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

每次都通过

每当您在需要该变量的页面上下文中执行某些操作时,您都可以将其传入。当您在使用该信息之前执行大量异步工作时,这可能无法按预期工作,因为那时它可能已经过时.

主动将其放入页面上下文

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

// 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
});