Кукольник: прокрутка таймлайна останавливается - PullRequest
1 голос
/ 09 марта 2019

У меня проблемы с копированием всех URL-адресов твитов на временной шкале пользователя с кукловодом.

С кукольником сценарий должен прокручивать временную шкалу на каждой итерации цикла while в функции scrollToEnd, пока не достигнет дна.Чтобы следить за прогрессом, я заставил скрипт вывести значение переменной previousHeight, которая является текущим значением scrollheight из document.body, вычисляемым каждый раз перед выполнением прокрутки.

Однако прокрутка прекращается, когда выходное значение становится 285 834.Что удивительно, так это то, что скрипт не выходит из цикла while и метод page.waitForFunction не вызывает ошибку времени ожидания.

Как мне переписать функцию scrollToEnd или любую другую часть скрипта, чтобы функция правильно заканчивалась?

Вот фрагмент моего кода.Нерелевантные функции опущены для краткости.

const puppeteer = require('puppeteer');

var UserUrls = ['https://twitter.com/someuser'];

// more functions here

async function scrollToEnd(
    page,
    ScrollDelay = 1000
) {
    try {
        let previousHeight = 0;
        let notEnd = await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
        while (notEnd) {
            previousHeight = await page.evaluate('document.body.scrollHeight');
            await page.evaluate('window.scrollBy(0, document.body.scrollHeight)');
            await page.waitFor(ScrollDelay);

            notEnd = await page.waitForFunction(`document.body.scrollHeight > ${previousHeight}`);
            console.log(previousHeight)
        };
        return;
    } catch (e) {
        return;
    };
};

(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    var tweetUrls = [];
    for (let UserUrl of UserUrls) {
        await page.goto(UserUrl);
        await page.evaluate((async () => {
            await scrollToEnd(page);
        })());
        await page.screenshot({ path: 'PageEnd.png' });
        tweetUrls = await getTweetUrls(page, extractItems, 100);
    };
    await browser.close();
    console.log(tweetUrls);
})();

1 Ответ

0 голосов
/ 09 марта 2019

Не могли бы вы попробовать один из этих двух подходов?Этот скрипт пытается прокрутить до конца, сравнивая высоты прокрутки (как вы это сделали) или ожидая, пока элемент, отмечающий конец потока, станет видимым.Вся логика прокрутки размещается внутри функций, оцениваемых в контексте браузера.Обе функции возвращают количество твитов на полной странице, чтобы сравнить результат с количеством твитов пользователя, объявленным в верхней части временной шкалы.Кроме того, я изменил задержку на 3 секунды для первого подхода, так как иногда кажется, что 1 секунда слишком мала для изменения высоты прокрутки.

'use strict';

const puppeteer = require('puppeteer');

(async function main() {
  try {
    const browser = await puppeteer.launch({ headless: false });
    const [page] = await browser.pages();

    await page.goto('https://twitter.com/GHchangelog');
    const data1 = await page.evaluate(scrollToBottomByMaxHeight);
    console.log(`Tweets: ${data1}`);

    await page.goto('https://twitter.com/GHchangelog');
    const data2 = await page.evaluate(scrollToBottomByEndElement);
    console.log(`Tweets: ${data2}`);

    // await browser.close();
  } catch (err) {
    console.error(err);
  }
})();

async function scrollToBottomByMaxHeight() {
  try {
    let previousHeight = 0;
    let currentHeight = document.scrollingElement.scrollHeight;

    while (previousHeight < currentHeight) {
      previousHeight = document.scrollingElement.scrollHeight;
      window.scrollBy(0, previousHeight);
      await new Promise((resolve) => { setTimeout(resolve, 3000); });
      currentHeight = document.scrollingElement.scrollHeight;
    }

    return document.querySelectorAll('a.js-permalink').length;
  } catch (err) {
    return err;
  }
}

async function scrollToBottomByEndElement() {
  try {
    const endElement = document.querySelector('div.stream-end');

    while (endElement.clientHeight === 0) {
      window.scrollBy(0, document.scrollingElement.scrollHeight);
      await new Promise((resolve) => { setTimeout(resolve, 1000); });
    }

    return document.querySelectorAll('a.js-permalink').length;
  } catch (err) {
    return err;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...