Кукольник не ждет завершения загрузки страницы - PullRequest
1 голос
/ 31 мая 2019

Я написал скрипт для создания скриншотов из 50 диаграмм размеров на веб-странице. Каждый график содержится в элементе. Самое смешное, что захватываются только первые три таблицы, остальные файлы PNG пустые, полностью белые.

Поскольку диаграммы извлекаются из базы данных, я подумал, что, возможно, страница не загрузилась до того, как были сделаны снимки экрана, поэтому я добавил {"waitUntil": "networkidle0"}, но это ничего не решило , Тем не менее, скрипт создает только скриншоты первых трех диаграмм, 0.png, 1.png и 2.png. Остальные файлы PNG, 3.png - 49.png, созданы, но только белые данные.

В чем может быть проблема? Если я захожу на страницу в своем браузере, все 50 графиков загружаются отлично, так почему же Puppeteer делает скриншот только из первых трех? Вот мой сценарий:

const puppeteer = require( 'puppeteer' );

( async() => {
    const browser = await puppeteer.launch();

    const page = await browser.newPage();
    await page.goto( 'http://www.example.com/size-charts.php', { "waitUntil": "networkidle0" } );

    // Get a list of all elements.
    const elements = await page.$$( 'div.chartContainer' );

    for( let i = 0; i < elements.length; i++ ) {
        try {
            // get screenshot of a particular element
            await elements[ i ].screenshot( { path: `${ i }.png` } );
        }
        catch( e ) {
            console.log( `Couldn't take a screenshot of the element with the index of: ${ i }. Reason: `, e );
        }
    }

    await browser.close();
} )();

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

Я собираюсь ответить на свой вопрос в надежде, что он может помочь другим. В моем конкретном случае решением было установить высоту окна просмотра на очень большое число, например ::10000

page.setViewport( { width: 1920, height: 100000 } );

После этого скрипт смог создавать скриншоты всех выделенных элементов.

0 голосов
/ 02 июня 2019

В то время как фактическое решение может / должно ожидать каждого элемента, чтобы быть видимым, есть некоторые другие возможные решения.

Возможное решение 1

Вы можете прокрутить до элемента, подождать некоторое время для правильной визуализации и затем сделать скриншот.

elementHandle.screenshot() прокручивает до элемента, но не может задержать или дождаться, пока элемент будет видимым.

A Быстрый поиск по официальному репо показал, что на данный момент существует не менее 19 открытых выпусков, в которых упоминается blank screenshot.

Вместо этого мы можем использовать пользовательский .evaluate, или .hover и т. Д. Для прокрутки до элемента, прежде чем делать снимок экрана.

elementHandle.hover(): Этот метод прокручивает элемент при необходимости, а затем использует page.mouse для наведения курсора на центр элемента. Если элемент отсоединен от DOM, метод выдает ошибку.

Давайте использовать его,

// Get a list of all elements.
const elements = await page.$$('div.chartContainer');

for (let i = 0; i < elements.length; i++) {
  // scrolls into view and hovers the element
  await elements[i].hover();

  // wait for some random number 
  await page.waitFor(1000);

  // get screenshot of a particular element
  await elements[i].screenshot({
    path: `${ i }.png`
  });
}

Возможное решение 2

Некоторые сообщили, что использование elementHandle.boundingBox() решило их проблему. Что это делает, захватывает положение, высоту, ширину и т. Д. Для элемента и использует это для скриншота.

// Get a list of all elements.
const elements = await page.$$('div.chartContainer');

for (let i = 0; i < elements.length; i++) {
  // get screenshot of a particular area
  await page.screenshot({ // <-- use page here
    path: `${ i }.png`,
    clip: await elements[i].boundingBox() // <-- use clip here
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...