如何使用casperjs点击随机链接并导航到另一个页面?

时间:2014-09-14 23:34:35

标签: javascript jquery casperjs

我正在尝试编写一个将执行以下操作的脚本:

  1. 加载网站并截取屏幕截图
  2. 从具有相同类名
  3. 的所有<a>代码中选择一个随机<a>代码
  4. 点击链接
  5. 等待新页面加载
  6. 捕获第二个屏幕截图
  7. 我坚持选择随机<a>元素并点击它。有人可以帮帮我吗?这是我与casperjs的第一天。这是我到目前为止所拥有的:

    var casper = require('casper').create({
         verbose: true,
         logLevel: 'debug',
         userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22',
         pageSettings: {}
    });
    casper.options.viewportSize = {width: 1600, height: 950};
    
    
    casper.start('http://www.myurl.com/', function() {
        this.echo(this.getTitle());
        this.capture('home.png');
    });
    
    casper.then(function() {
            this.echo("Second test");
            var random = Math.floor(Math.random() * document.querySelector(".showall").length);
            var clicker = document.querySelector('.showall').eq(random);
            this.mouseEvent('click', clicker);
    
            this.wait(5000, function() {
                this.capture('second.png');
           });
    
    });
    
    casper.run();
    

2 个答案:

答案 0 :(得分:2)

您不能在页面上下文之外使用DOM函数。您必须使用casper.evaluate。请记住,evaluate是沙箱,您只能将原始对象传入和传出页面上下文。 DOM元素不是原始对象,因此您无法将它们传递到casper上下文中。 documentevaluate之外没有任何意义。

来自docs

  

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

您必须在页面上下文中单击DOM方法的链接。如果简单的clicker.click()不起作用,则必须在页面上下文中使用this之类的内容。

如果该链接实际上是一个可以立即导航到该页面的链接,则可以删除this.wait。如果导航页面,CasperJS可以自行感知,因此您可以使用另一个casper.then步骤。

顺便说一句eq是jQuery语法,但querySelector的结果不是jQuery对象,它是一个DOM元素。如果要选择随机元素,则必须使用querySelectorAll,然后选择其中一个:

var clicker = document.querySelectorAll('.showall')[random];

代替。

完整的解决方案:

casper.then(function() {
    this.echo("Second test");
    this.evaluate(function() {
        var elements = document.querySelectorAll(".showall");
        var random = Math.floor(Math.random() * elements.length);
        var clicker = elements[random];

        // either this type of click
        clicker.click();
        // or the following
        var ev = document.createEvent("MouseEvent");
        ev.initMouseEvent(
            "click", true, true, window, null, 0, 0, 0, 0, 
            false, false, false, false, 0, null
        );
        clicker.dispatchEvent(ev);
    });
});
casper.then(function() {
    this.capture('second.png');
});

答案 1 :(得分:1)

我没有设法让Artjom的解决方案正常运作。我认为我以错误的方式使用querySelectorAll(不确定原因)。我找到了解决方法。

function getElem() {
    var arr = document.querySelectorAll('a.showall');
    return Array.prototype.map.call(arr, function(elem) {
        return elem.getAttribute('href');
    });
}

casper.then(function() {

        var elem_arr = this.evaluate(getElem);
        //this.echo(elem_arr);
        this.echo(elem_arr.length);

        for (var index = 0; index < elem_arr.length; index++) {
            this.echo(elem_arr[index]);
        }

        var random = Math.floor(Math.random() * elem_arr.length);
        this.echo(random);

        var clicker = elem_arr[random];
        this.echo("Random link: " + clicker);

        casper.open(clicker).then(function() {
            this.echo('Got it! You navigated to a random link subpage.');
        });


});

诀窍是创建一个来自所有a.showall元素的链接数组,然后选择一个随机链接并将其打开。