Casperjs click()不会正确触发点击事件

时间:2015-08-13 04:12:50

标签: javascript ajax click casperjs image-loading

我使用CasperJS进行网页抓取,但我在抓取下面描述的页面时遇到了一些问题。

页面的html如下所示:

<img id="trigger">
<img id="cur_img_xxx" class="show">
<img id="cur_img_yyy" class="cache">

所有<img>元素共享相同的维度,"#trigger"位于最顶层。当图像具有.show类时,它将显示在页面上;当它的.cache类时,它会被下载但隐藏。这样,当用户点击图像(实际上是触发器)时,将显示下一个图像,并通过AJAX下载新图像。结果html变为:

<img id="trigger">
<img id="cur_img_xxx" class="cache">
<img id="cur_img_yyy" class="show">
<img id="cur_img_zzz" class="cache">

我认为这是一个增加用户体验的好策略,有利于避免网页抓取,但我仍然想要抓住:P

我在网络控制台中尝试了$("#trigger").click(),图片得到了导航和下载更正。但是,当我尝试使用CasperJS模拟此过程时,导航和图像下载均无效。请参阅代码:

var casper = require ("casper").create({
  clientScripts:  [
    'include/jquery.js'
  ],
  pageSettings: {
    loadImages:  false, // this won't affect since this will only forbid
    loadPlugins: false  // inline imgs from loading, but all imgs in this
  },                    // page are loaded dynamically
  verbose: true
});

casper.start("http://www.example.com/1234.html");

casper.then(function () {
  console.log("Connected! Current Url = " + this.getCurrentUrl());
});

casper.then(function () {
  // findInitialImgs will find imgs that have already been loaded 
  imgs = this.evaluate(findInitialImgs);

  this.waitForSelector("#image_trigger").thenClick("#image_trigger");

  var next = this.evaluate(function () {
    return $("img[id^='cur_img_']").last().attr("href");
  });

  console.log(next);
});

casper.run(function () {
  this.echo('End').exit();
});

右键单击"#trigger"后,最后一个条目会有所不同,即从<img id="cur_img_yyy">变为<img id="cur_img_zzz">。但是,next仍然保留<img id="cur_img_yyy">。我做错了吗?

2 个答案:

答案 0 :(得分:1)

您如何确认没有任何反应?所有wait*()then*()函数都是异步步骤函数,但evaluate不是,因此它在其他两个函数之前执行。您需要在evaluate块中包装最后一次then调用,以确保在单击后执行包含它的步骤。

由于图像加载可能是异步执行的,因此您需要在evaluate块中包含最后wait次调用,但等待时间很短:

casper.then(function () {
  // findInitialImgs will find imgs that have already been loaded 
  imgs = this.evaluate(findInitialImgs);

  this.waitForSelector("#image_trigger")
    .thenClick("#image_trigger")
    .wait(1000, function(){
      var next = this.evaluate(function () {
        return $("img[id^='cur_img_']").last()[0].id;
      });
      console.log(next);
    });
});

请注意,您无法将DOM节点传递出页面上下文(evaluate()),因此您需要使用某种表示方式。这里我使用了最后一个元素的id。

对于referencecasper.evaluate()只是PhantomJS&#39; page.evaluate()的包装器):

  

注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。

     

闭包,函数,DOM节点等将工作!

答案 1 :(得分:0)

这似乎是JQuery的问题。删除JQuery注入后,将$("img[id^='cur_img_']").last().attr("href")更改为

var imgs = document.querySelectorAll("img[id^='cur_img_']");
return imgs[imgs.length - 1].getAttribute("href");

一切正常。

然后我发现这个答案非常强大:CasperJS click event having AJAX call

因此确认,当您将JQuery注入使用$ JQuery的网页时,原始脚本将会被破坏。