简体   繁体   English

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

[英]How to use casperjs to click a random link and navigate to another page?

I am trying to write a script that will do the following: 我正在尝试编写一个将执行以下操作的脚本:

  1. load a website and take a screenshot 加载网站并截取屏幕截图
  2. select a random <a> tag from all <a> tags with the same class name 从具有相同类名的所有<a>标签中选择随机<a>标签
  3. click the link 单击链接
  4. wait for the new page to load 等待新页面加载
  5. capture the second screenshot 捕获第二个屏幕截图

I'm stuck at selecting a random <a> element and clicking it. 我坚持选择一个随机<a>元素并单击它。 Can anyone help me out please? 有人可以帮帮我吗? It's my first day with casperjs. 这是我与casperjs的第一天。 Here's what i have so far: 这是我到目前为止所拥有的:

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();

You cannot use the DOM functions outside of the page context. 您不能在页面上下文之外使用DOM函数。 You have to use casper.evaluate for that. 你必须使用casper.evaluate Keep in mind that evaluate is sandboxed and you can only pass primitive objects to and from page context. 请记住, evaluate是沙箱,您只能将原始对象传入和传出页面上下文。 DOM elements are not primitive objects, so you cannot pass them outside into the casper context. DOM元素不是原始对象,因此您无法将它们传递到casper上下文中。 document means nothing outside of evaluate . documentevaluate之外没有任何意义。

From the docs : 来自文档

Note: The arguments and the return value to the evaluate function must be a simple primitive object. 注意:evaluate函数的参数和返回值必须是一个简单的原始对象。 The rule of thumb: if it can be serialized via JSON, then it is fine. 经验法则:如果它可以通过JSON序列化,那么它很好。

You will have to click the link with DOM methods inside of the page context. 您必须在页面上下文中单击DOM方法的链接。 If the simple clicker.click() doesn't work, you have to use something like this in the page context. 如果简单clicker.click()不工作,你必须使用类似这样的页面上下文。

If the link is actually a link which immediately navigates to the page, you can removed this.wait . 如果链接实际上是一个直接导航到页面的链接,则可以删除this.wait CasperJS can sense on its own if a page is navigated to, so you can just use another casper.then step. 如果页面被导航到,CasperJS可以自行感知,因此您可以使用另一个casper.then步骤。

By the way eq is jQuery syntax, but the result of querySelector is not a jQuery object, it is a DOM element. 顺便说一下eq是jQuery语法,但是querySelector的结果不是jQuery对象,它是一个DOM元素。 If you want to select a random element then you have to use querySelectorAll and then select one of them: 如果要选择随机元素,则必须使用querySelectorAll ,然后选择其中一个:

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

instead. 代替。

Complete solution: 完整解决方案

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

I didn't manage to get Artjom's solution working. 我没有设法让Artjom的解决方案正常工作。 I think i'm using querySelectorAll in a wrong way (not sure why). 我想我正在以错误的方式使用querySelectorAll (不知道为什么)。 I found a workaround. 我找到了一个解决方法。

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.');
        });


});

The trick is to create an array of links from all a.showall elements and then select a random link and open it. 诀窍是从所有a.showall元素创建一个链接数组,然后选择一个随机链接并打开它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM