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

Javascript 如何使用casperjs单击一个随机链接并导航到另一个页面?,javascript,jquery,casperjs,Javascript,Jquery,Casperjs,我正在尝试编写一个脚本,该脚本将执行以下操作: 加载网站并截图 从所有具有相同类名的标记中随机选择一个标记 点击链接 等待新页面加载 捕获第二个屏幕截图 我一直在选择一个随机的元素并单击它。有人能帮我吗?这是我和casperjs在一起的第一天。以下是我目前掌握的情况: var casper = require('casper').create({ verbose: true, logLevel: 'debug', userAgent: 'Mozilla/5.0 (M

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

  • 加载网站并截图
  • 从所有具有相同类名的
    标记中随机选择一个
    标记
  • 点击链接
  • 等待新页面加载
  • 捕获第二个屏幕截图
  • 我一直在选择一个随机的
    元素并单击它。有人能帮我吗?这是我和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();
    

    不能在页面上下文之外使用DOM函数。你必须用它。请记住,
    evaluate
    是沙盒,您只能在页面上下文之间传递基本体对象。DOM元素不是基本对象,因此不能将它们从外部传递到casper上下文中<代码>文档表示除
    评估
    之外的任何内容

    从:

    注意:参数和evaluate函数的返回值必须是一个简单的基元对象。经验法则:如果可以通过JSON对其进行序列化,那么就可以了

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

    如果该链接实际上是一个可立即导航到该页面的链接,则可以删除
    this.wait
    。CasperJS可以自己感知页面是否被导航到,所以您可以使用另一个
    casper

    顺便说一下,
    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');
    });
    

    我没能让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.');
            });
    
    
    });
    
    函数getElem(){ var arr=document.querySelectorAll('a.showall'); 返回Array.prototype.map.call(arr,function(elem){ 返回elem.getAttribute('href'); }); } casper.then(函数(){ var elem_arr=这个。评估(getElem); //这个.echo(elem_arr); 该回波(元素到达长度); 对于(var index=0;index

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

    如果将
    random
    索引替换为硬编码索引会怎么样?您的脚本是否按预期运行?并非如此。我只需要点击一个特定的元素:
    casper.then(function(){this.echo(“Second test”);this.mouseEvent('click','.showall');this.wait(5000,function(){this.capture('Second.png');})
    通过读取capser的
    mouseEvent
    函数,它似乎期望的是一个选择器查询(即
    .showall
    ),而不是
    .eq()
    返回的jQuery对象。如果
    mouseEvent
    的查询选择器使用的是
    第n个子项
    伪选择器,代码是否按预期工作?(即,
    .showall:nth child(此处插入编号)
    )它仅适用于第n个child(1),尽管我100%确定页面上大约有20个
    标记。如果第n个子项大于1,我得到
    CasperError:无法在不存在的选择器上调度click事件:.showall:n个子项(2)
    非常感谢您的帮助,Artjom。但是,我注意到,
    this.evaluate(function()中的所有代码
    完全被执行。这是什么原因造成的?我以前在尝试使用
    评估
    时遇到过这个问题。这是一个配置问题吗?似乎不是,但我不完全确定。它被执行了,但您不一定看到结果。您应该注册到和事件。实际上,注册page.error-helped并显示以下错误:
    error:TypeError:“未定义”不是对象(评估“clicker.click”)
    。我完全错过了
    querySelector
    应该是
    querySelectorAll
    。我添加了一个原因。如果答案对您有帮助,请接受。它仍然不起作用,但我会自己找到解决方案。谢谢您的帮助。