javascript - 如何使用 Phantomjs 向下滚动以加载动态内容

标签 javascript dom web-scraping screen-scraping phantomjs

我正在尝试从一个页面中抓取链接,该页面会在用户向下滚动到底部(无限滚动)时动态生成内容。我曾尝试使用 Phantomjs 做不同的事情,但无法收集第一页以外的链接。假设底部加载内容的元素具有类 .has-more-items。它在滚动时加载最终内容之前可用,然后在 DOM 中变得不可用(显示:无)。这是我尝试过的东西-

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

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

  • page.open 中使用 page.scrollPosition = { top: 10000, left: 0 } 但没有像-
  • 这样的效果
page.open('http://example.com/?q=houston', function(status) {
   if (status == "success") {
      page.scrollPosition = { top: 10000, left: 0 };  
   }
});
  • 还尝试将其放入 page.evaluate 函数中,但这给出了

Reference error: Can't find variable page

  • 尝试在 page.evaluatepage.open 中使用 jQuery 和 JS 代码,但无济于事-

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

原样并且也在 document.ready 中。同样对于 JS 代码-

window.scrollBy(0,10000)

原样并且也在 window.onload

我真的对它感到震惊了 2 天,但找不到方法。任何帮助或提示将不胜感激。

更新

我在 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;
    }); }

.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";

但似乎没有任何效果。

最佳答案

找到了一种方法,并尝试适应您的情况。我没有测试找到页面底部的最佳方法,因为我有不同的上下文,但请检查下面的解决方案。这里的事情是你必须等待页面加载和 javascript 异步工作所以你必须使用 setIntervalsetTimeout ( see ) 来实现这个.

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

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

      if(count === null) { // Didn't find
        page.evaluate(function() {
          // Scroll 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

});

关于javascript - 如何使用 Phantomjs 向下滚动以加载动态内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16561582/

相关文章:

javascript - 点击函数内的ajax请求干扰执行

javascript - DOM子节点输出与父节点相同

javascript - Casperjs 单击无法打开 'download csv' 操作系统窗口

python - BeautifulSoup 删除嵌套标签

javascript - 通过ajax发送DOM

python - 无法以正确的方式从网页收集标题

javascript - JavaScript 是否在内部将数组转换为对象?

javascript - 使用 Mocha 和 Sinon spy 在 promise 范围内测试 Express.js res.render

javascript - 谷歌表格: Return Multi Dimensional Array (JavaScript)

javascript - jQuery选择的嵌套dom元素的后序遍历