Подтвердить что ты не робот

Как прокрутить вниз с помощью Phantomjs для загрузки динамического содержимого

Я пытаюсь очистить ссылки со страницы, которая динамически генерирует контент, когда пользователь прокручивается вниз (бесконечная прокрутка). Я пробовал делать разные вещи с Phantomjs, но не смог собрать ссылки за первой страницей. Пусть говорят, что элемент внизу, который загружает контент, имеет класс .has-more-items. Он доступен до тех пор, пока окончательный контент не будет загружен во время прокрутки, а затем будет недоступен в DOM (display: none). Вот что я пробовал -

  • Настройка viewportSize на большую высоту сразу после var page = require('webpage').create();

page.viewportSize = {ширина: 1600, высота: 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 };  
   }
});
  • Также попытался поместить его внутрь 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)

как есть, а также внутри 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";

Но ничего не работает.

4b9b3361

Ответ 1

Нашел способ сделать это и попытался адаптироваться к вашей ситуации. Я не тестировал лучший способ найти нижнюю часть страницы, потому что у меня был другой контекст, но проверьте его. Проблема в том, что вам нужно немного подождать, чтобы страница загружалась, а javascript работает асинхронно, поэтому вам нужно использовать 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

});

Ответ 2

Я знаю, что он был дан ответ уже давно, но я также нашел решение для моего конкретного сценария. Результатом является фрагмент javascript, который прокручивается в нижней части страницы. Он оптимизирован для уменьшения времени ожидания.

Он не написан для PhantomJS по умолчанию, поэтому его нужно будет изменить. Тем не менее, для новичков или тех, у кого нет доступа к корню, IFrame с внедренным javascript (запустите Google Chrome с параметром --disable-javascript) является хорошим альтернативным методом для сокрытия меньшего набора страниц ajax. Главное преимущество заключается в том, что он легко отлаживается, потому что у вас есть визуальный обзор того, что происходит с вашим скребком.

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 - это переменная времени ожидания. Надеюсь, это полезно кому-то:)

Ответ 3

"Правильное" решение для меня не сработало. И из того, что я читал, 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 в функцию Каспера then.

Однако вышеупомянутое решение не будет работать на некоторых сайтах, таких как Twitter; jQuery, похоже, нарушает функцию casper.scrollToBottom(), и мне пришлось удалить ссылку clientScripts для jQuery при работе в Twitter.

var casper = require('casper').create({
    clientScripts: [
       // 'jquery.js'
    ]
});

Некоторые веб-сайты (например, BoingBoing.net), похоже, отлично работают с jQuery и CasperJS scrollToBottom(). Не уверен, почему некоторые сайты работают, а другие нет.

Ответ 4

Ниже приведенный ниже фрагмент кода отлично подходит для pinterest. Я много исследовал, чтобы очистить pinterest без phantomjs, но невозможно найти бесконечную ссылку триггера прокрутки. Я думаю, что приведенный ниже код поможет очистить веб-страницу другой бесконечной прокрутки.

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();
            })