如何向下滚动Phantomjs以加载动态内容

Pun*_*ini 46 javascript dom screen-scraping web-scraping phantomjs

我试图从用户向下滚动到底部(无限滚动)动态生成内容的页面中抓取链接.我曾尝试用Phantomjs做不同的事情但不能收集第一页以外的链接.让我们说加载内容的底部元素具有类.has-more-items.它在滚动期间加载最终内容之前可用,然后在DOM中变为不可用(显示:无).以下是我试过的事情 -

  • 之后将viewportSize设置为较大的高度 var page = require('webpage').create();

page.viewportSize = {width:1600,height:10000,};

  • 使用page.scrollPosition = { top: 10000, left: 0 }内部,page.open但没有效果像 -
page.open('http://example.com/?q=houston', function(status) {
   if (status == "success") {
      page.scrollPosition = { top: 10000, left: 0 };  
   }
});
Run Code Online (Sandbox Code Playgroud)
  • 也试过把它放在page.evaluate功能内但是给出了

参考错误:找不到变量页面

  • 尝试使用jQuery和JS代码page.evaluate,page.open但没有用 -

$("html,body").animate({scrollTop:$(document).height()},10,function(){// console.log('check for execution');});

既然如此,也在里面document.ready.类似的JS代码 -

window.scrollBy(0,10000)
Run Code Online (Sandbox Code Playgroud)

既然如此,也在里面 window.onload

我现在真的被打了两天而且找不到方法.任何帮助或提示将不胜感激.

更新

我在https://groups.google.com/forum/?fromgroups=#!topic/phantomjs/8LrWRW8ZrA0找到了一段有用的代码

var hitRockBottom = false; while (!hitRockBottom) {
    // Scroll the page (not sure if this is the best way to do so...)
    page.scrollPosition = { top: page.scrollPosition + 1000, left: 0 };

    // Check if we've hit the bottom
    hitRockBottom = page.evaluate(function() {
        return document.querySelector(".has-more-items") === null;
    }); }
Run Code Online (Sandbox Code Playgroud)

哪里.has-more-items是元素类我想访问其可在页面的底部开始,当我们向下滚动,它的动作进一步下跌,直到所有数据被加载,然后变得不可用.

但是,当我测试时,很明显它在没有向下滚动的情况下运行到无限循环中(我渲染图片以进行检查).我也尝试page.scrollPosition = { top: page.scrollPosition + 1000, left: 0 };用下面的代码替换(一次一个)

window.document.body.scrollTop = '1000';
location.href = ".has-more-items";
page.scrollPosition = { top: page.scrollPosition + 1000, left: 0 };
document.location.href=".has-more-items";
Run Code Online (Sandbox Code Playgroud)

但似乎没有任何效果.

Joã*_*sce 45

找到了一种方法,并尝试适应您的情况.我没有测试找到页面底部的最佳方法,因为我有不同的上下文,但检查出来.问题是你必须稍等一下才能加载页面并且javascript异步工作,所以你必须使用setIntervalsetTimeout(参见参考资料).

page.open('http://example.com/?q=houston', function () {

  // Checks for bottom div and scrolls down from time to time
  window.setInterval(function() {
      // Checks if there is a div with class=".has-more-items" 
      // (not sure if this is the best way of doing it)
      var count = page.content.match(/class=".has-more-items"/g);

      if(count === null) { // Didn't find
        page.evaluate(function() {
          // Scrolls to the bottom of page
          window.document.body.scrollTop = document.body.scrollHeight;
        });
      }
      else { // Found
        // Do what you want
        ...
        phantom.exit();
      }
  }, 500); // Number of milliseconds to wait between scrolls

});
Run Code Online (Sandbox Code Playgroud)

  • 使用`window.scrollTo(0,Math.max(Math.max(document.body.scrollHeight,document.documentElement.scrollHeight),Math.max(document.body.offsetHeight,document.documentElement.offsetHeight)可能会有所帮助,Math.max(document.body.clientHeight,document.documentElement.clientHeight)));`因为它是casperjs在内部执行的操作. (4认同)