在PhantomJS中动态更改链接并单击它以刮取页面

时间:2015-11-05 04:16:06

标签: javascript jquery click phantomjs

我现在已经试图解决这个问题几天但是还没有能够实现它。

我需要删除此网页上的所有可用记录,我注意到如果我修改了与firebug或浏览器检查员的分页链接,我可以获取所有我需要的记录,例如,这是原始链接:

<a href="javascript:gReport.navigate.paginate('paginator_min_row=16max_rows=15rows_fetched=15')">

如果我像这样修改那个链接

<a href="javascript:gReport.navigate.paginate('paginator_min_row=1max_rows=5000rows_fetched=5000')">

然后点击浏览器上的分页按钮(包含我刚刚更改过的链接)我能够从该网站获取所需的所有记录(大部分时间和时间) #34;行&#34;没有大于4000,我使用5000以防万一)

由于我每天必须手工处理该文件,我认为也许我可以使用PhantomJS自动化该过程并在一次运行中获取整个页面而无需查找该链接然后更改它,因此为了修改分页链接并使用以下代码获取所有记录:

var page = require('webpage').create();
var fs = require('fs');
page.open('http://testingsite1.local', function () {
    page.evaluate(function(){
        $('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').first().attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id','clickit');
    $('#clickit')[0].click();
    });

    page.render('test.png');
    fs.write('test.html', page.content, 'w');
    phantom.exit();
});

请注意,该网站上有两个分页链接,因为我使用了jquery&#34; .first()&#34;只选择第一个。

此外,由于所需的链接没有任何标识符,我使用自己的链接选择它,然后将其更改为我需要的,最后我添加&#34; clickit&#34;用于以后调用的ID。

现在,这是我的问题:

我不确定为什么它不起作用,如果我运行代码它只获取第一页,在检查所请求的页面源代码之后我确实看到href链接已经改为我想要的只是它没有被召唤,我对可能出错的地方有两种不同的理论

  1. 修改后的href未点击&#34;点击&#34;所以页面没有更新

  2. href确实被点击了,但由于页面花了几秒钟动态加载所有结果我只能转储Phantomjs看到的第一页

  3. 你们怎么看?

    [2015年11月6日更新] 好的,所以@Artjomb和@pguardiario提供的答案指出了我的新方向:

    1. 我需要更多关于发生了什么的调试信息
    2. 我需要直接调用gReport.navigate.paginate函数
    3. 可悲的是,我只是缺乏正确使用PhantomJS的经验,其他几个样本表明我可以用CasperJS实现我想要的,所以我尝试了,这是我几个小时后制作的

      var utils = require('utils');
      var fs = require('fs');
      var url = 'http://testingsite1.local';
      
      var casper = require('casper').create({
        verbose: true,
        logLevel: 'debug'
      });
      
      casper.on('error', function(msg, backtrace) {
        this.echo("=========================");
        this.echo("ERROR:");
        this.echo(msg);
        this.echo(backtrace);
        this.echo("=========================");
      });
      
      casper.on("page.error", function(msg, backtrace) {
        this.echo("=========================");
        this.echo("PAGE.ERROR:");
        this.echo(msg);
        this.echo(backtrace);
        this.echo("=========================");
      });
      
      casper.start(url, function() {
        var url = this.evaluate(function() {
          $('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id', 'clicklink');
          return gReport.navigate.paginate('paginator_min_row=1max_rows=5000rows_fetched=5000');
        });
      });
      
      casper.then(function() {
        this.waitForSelector('.nonexistant', function() {
          // Nothing here
        }, function() {
          //page load failed after 5 seconds
          this.capture('screen.png');
          var html = this.getPageContent();
          var f = fs.open('test.html', 'w');
          f.write(html);
          f.close();
        }, 50000);
      });
      
      casper.run(function() {
        this.exit();
      });
      

      请保持温和,因为我知道这个代码很糟糕,我不是Javascript专家,事实上我知之甚少,我知道我应该等待一个元素出现,但它根本没有工作在我的测试中,因为我仍然没有从AJAX请求更新页面。

      最后我等了很长时间(50秒)让AJAX请求在页面上显示然后转储HTML

      哦!直接调用函数确实很有用!

1 个答案:

答案 0 :(得分:0)

  
      
  1. href确实被点击了,但由于页面花了几秒钟动态加载所有结果我只能转储Phantomjs看到的第一页
  2.   

很容易通过在setTimeout中包装渲染,写入和退出调用并尝试不同的超时来检查是否是这样:

page.open('http://testingsite1.local', function () {
    page.evaluate(function(){
        $('a[href="javascript:gReport.navigate.paginate(\'paginator_min_row=16max_rows=15rows_fetched=15\')"]').first().attr('href', 'javascript:gReport.navigate.paginate(\'paginator_min_row=1max_rows=5000rows_fetched=5000\')').attr('id','clickit');
        $('#clickit')[0].click();
    });

    setTimeout(function(){
        page.render('test.png');
        fs.write('test.html', page.content, 'w');
        phantom.exit();
    }, 5000);
});

如果它确实只是一个超时问题,那么你应该使用waitFor() function等待一个特定条件,比如“加载所有元素”或“加载该类型的x个元素”。

  
      
  1. 修改后的href没有被“点击”,因此页面没有得到更新
  2.   

这有点棘手。您可以收听onConsoleMessageonErroronResourceErroronResourceTimeout个事件(Example)并查看网页上是否有错误。其中一些错误可以通过您在PhantomJS中执行的操作来解决:Function.prototype.bind not availableHTTPS site/resources cannot be loaded

还有其他方法可以点击更可靠的内容,例如this one