Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript CasperJS,多元素在刮取过程中单击_Javascript_Phantomjs_Casperjs - Fatal编程技术网

Javascript CasperJS,多元素在刮取过程中单击

Javascript CasperJS,多元素在刮取过程中单击,javascript,phantomjs,casperjs,Javascript,Phantomjs,Casperjs,我正在尝试刮取一个页面,并将所有数据作为JSON返回。这个过程是,我首先打开www.domain.com,将各种信息放入节点数组,但对于每个节点,还有另一个页面,我想从中提取额外的数据并存储在节点数组中。我需要在循环中执行此操作,或者至少能够传递x变量,以便知道将此数据推送到数组中的位置 我已经把这段代码剥离了回来,还没有检查它是否正常工作,但是我的主版本工作得很好 非常感谢您的帮助…谢谢 var nodes = {}; var casper = require('casper').creat

我正在尝试刮取一个页面,并将所有数据作为JSON返回。这个过程是,我首先打开www.domain.com,将各种信息放入节点数组,但对于每个节点,还有另一个页面,我想从中提取额外的数据并存储在节点数组中。我需要在循环中执行此操作,或者至少能够传递x变量,以便知道将此数据推送到数组中的位置

我已经把这段代码剥离了回来,还没有检查它是否正常工作,但是我的主版本工作得很好

非常感谢您的帮助…谢谢

var nodes = {};

var casper = require('casper').create({

    pageSettings: {
        loadImages:  false,           
    },             
    verbose: true                   
});


var url = "http://www.domain.com";


function get_rows() 
{
  var nodes = {};

  var el = document.querySelectorAll(".rows");

  nodes["rows"] = {};

  for(var x = 0; x < el.length; ++x) 
  {
    // Set the arrays
    nodes["rows"][x] = {};


    nodes["rows"][x] = el[x].innerHTML;


    // THIS DATA IS ON A SEPARATE PAGE
    // el[x].click IS HOW YOU'D VISIT THAT PAGE
    nodes["rows"][x]["data"] = {};

  }

  return nodes;
}


function get_data()
{
  casper.echo("get_data");

  rows = casper.evaluate(get_rows);

  casper.echo(JSON.stringify(rows));

}

casper.start(url, function() 
{
  this.echo('Starting...' + this.getTitle());
});

casper.userAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:35.0) Gecko/20100101 Firefox/35.0');
casper.viewport(320, 480);

casper.waitFor
(
  function check() 
  {
    return this.evaluate(function() 
    {
      return $('.content').is(':visible');
    });
  }, 
  function then() 
  {    
    this.capture("/work/screen.png");

    // Lets go get the data
    this.echo("About to get_data()");
    get_data();
  }, 
  function timeout() 
  { 
    // step to execute if check has failed
    this.echo("Timeout: page did not load in time...").exit();
  }
);


casper.run();
您必须将get_rows函数拆分为多个函数。第一个将检索.rows元素的数量。casper.getElementsInfo为每个匹配的元素提供一个html属性,可在页面上下文之外调用

var nodes;
var x = require('casper').selectXPath;
casper.then(function(){
    nodes = {
        rows: {}
    };
    var elements = this.getElementsInfo(".rows");
    for(var i = 0; i < elements.length; i++) {
        nodes.rows[i] = {
            html: elements[i].html
        };
        (function(i){
            // TODO: click on the correct link
            casper.thenClick(x("(//*[contains(@class,'rows')])["+(i+1)+"]//a"));
            casper.then(function(){
                nodes.rows[i].data = this.evaluate(function(){
                    return { stuff: "whatever" }; // scrape here
                });
            });
            casper.back(); // assumes this works for your page
        })(i);
    }
}).then(function(){
    this.echo(JSON.stringify(nodes.rows, undefined, 4));
});
生命函数i{…}i;重要的是,否则只会填充最后一个i。这是因为JavaScript具有函数级作用域,而CasperJS的then*函数是异步的


如果casper.back对您不起作用,您需要使用casper.back重新加载主页面,然后打开。

这就是我目前所处的位置……第一次求值返回一个对象,效果非常好,但在每个装置中,我希望获得另一页数据,要单击的元素只是一个名为.Fixture的重复类,因此我使用第n个子元素尝试并以相关元素为目标。代码从未真正创建捕获

    fixtures = casper.evaluate(get_fixtures);

  casper.echo("Fixtures: "+Object.keys(fixtures).length );

  casper.then(function()
  {    
    Object.keys(fixtures).forEach(function(key) 
    {
      casper.echo(fixtures[key]["competition"]);

      (function(key)
      {
        casper.echo(".Fixture:nth-child("+key+")");

        var pageturnString = key.toString();
        var linknum = 'div.Fixture:nth-child('+pageturnString+')';

        casper.thenClick(linknum);

        casper.then(function()
        {
          casper.capture('/work/screen_click.png');
        });
        casper.back(); // assumes this works for your page
      })(key);

    });

  }).then(function()
  {
      casper.echo("END");
  });

我不确定这是否可以作为get_rows函数使用,因为这是在CasperJS不在范围内的求值调用中调用的?这就是为什么您必须将其拆分为多个步骤,并且大多数步骤都必须在页面上下文之外执行的原因。感谢Artjom,我将尝试一下,看看givesIt没有真正执行什么,没有进一步的转发,但我非常感谢您的回复。您可能很难找到正确的链接来点击。我在一个小助手的帮助下改变了答案。如果你想放弃,问一个新的问题。