如何使用Phantomjs向下滚动以加载dynamic内容
我试图从用户向下滚动到底部(无限滚动)时dynamic生成内容的页面刮取链接。 我试图用Phantomjs做不同的事情,但不能收集第一页以外的链接。 假设加载内容的底部的元素具有类.has-more-items
。 直到最终内容在滚动时才加载,然后在DOM中变为不可用(display:none)。 这是我尝试过的东西 –
- 在
var page = require('webpage').create();
后面设置viewportSize到一个很大的高度var page = require('webpage').create();
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
函数里面,但是给出了
参考错误:无法findvariables页面
- 尝试在
page.evaluate
和page.open
内使用jQuery和JS代码,但page.open
$(“html,body”)。animate({scrollTop:$(document).height()},10,function(){//console.log('check for execution');});
因为它也是在document.ready
。 类似的JS代码 –
window.scrollBy(0,10000)
因为它也是在window.onload
里面
我现在真的打了2天,没能find办法。 任何帮助或暗示将不胜感激。
更新
我在https://groups.google.com/forum/?fromgroups=#!topic/phantomjs/8LrWRW8ZrA0find了一段有用的代码
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
是我想要访问的元素类,它最初在页面的底部可用,当我们向下滚动时,它向下移动,直到所有的数据被加载,然后变得不可用。
然而,当我testing它很明显,它是无限循环运行而不滚动(我渲染图片来检查)。 我试图replacepage.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";
但似乎没有任何工作。
find一个方法来做到这一点,并试图适应你的情况。 我没有testingfind页面底部的最佳方式,因为我有不同的上下文,但检查出来。 问题是,你不得不等待页面加载和javascript的asynchronous工作,所以你必须使用setInterval
或setTimeout
( 请参阅 )。
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 });
我知道很久以前就已经回答了,但是我也find了解决scheme。 结果是一段JavaScript滚动到页面的底部。 这是优化,以减less等待时间。
它不是为PhantomJS默认写的,所以必须修改。 然而,对于初学者或者没有root权限的用户来说,一个带有注入javascript的iframe(运行带有–disable-javascript参数的谷歌浏览器)是一个很好的替代方法,用于抓取更小的一组Ajax页面。 主要的好处是它很容易debugging,因为你可以直观的看到你的刮板正在发生什么。
function ScrollForAjax () { scrollintervals = 50; scrollmaxtime = 1000; if(typeof(scrolltime)=="undefined"){ scrolltime = 0; } scrolldocheight1 = $(iframeselector).contents().find("body").height(); $("body").scrollTop(scrolldocheight1); setTimeout(function(){ scrolldocheight2 = $("body").height(); if(scrolltime===scrollmaxtime || scrolltime>scrollmaxtime){ scrolltime = 0; $("body").scrollTop(0); ScrapeCurrentPage(iframeselector); } else if(scrolldocheight2>scrolldocheight1){ scrolltime = 0; ScrollForAjax (iframeselector); } else if(scrolldocheight1>=scrolldocheight2){ ScrollForAjax (iframeselector); } },scrollintervals); scrolltime += scrollintervals; }
scrollmaxtime是一个超时variables。 希望这对某个人有用:)
“正确的”解决scheme并不适合我。 而且,从我读到的CasperJS不使用window
(但我可能是错误的),这使我怀疑window
作品。
以下在Firefox / Chrome控制台中适用于我; 但是,在CasperJS中不起作用(在casper.evaluate
函数内)。
$(document).scrollTop($(document).height());
CasperJS为我工作的是:
casper.scrollToBottom(); casper.wait(1000, function waitCb() { casper.capture("loadedContent.png"); });
其中,当casper.capture
移入Casper的then
function也工作。
但是,上述解决scheme在Twitter等网站上不起作用。 jQuery似乎打破了casper.scrollToBottom()
函数,并且在Twitter中工作时,我不得不移除对jQuery的clientScripts
引用。
var casper = require('casper').create({ clientScripts: [ // 'jquery.js' ] });
一些网站(如BoingBoing.net)似乎与jQuery和CasperJS scrollToBottom()
一起工作正常。 不知道为什么一些网站的工作,而其他人不。
下面的代码片段适用于pinterest。 我研究了很多没有phantomjs刮了pinterest,但它是不可能find无限滚动触发器链接。 我认为下面的代码将帮助其他无限滚动网页刮。
page.open(pageUrl).then(function (status) { var count = 0; // Scrolls to the bottom of page function scroll2btm(){ if(count <500) { page.evaluate(function(limit) { window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight); return document.getElementsByClassName('pinWrapper').length; //use desired contents(eg. pin) selector for count presence number }).then(function(c){ count=c; console.log(count)//print no of content found to check }); setTimeout(scroll2btm,3000); } else { // required number of item found } } scroll2btm(); })