Безголовый Chrome отображает всю страницу

Проблема с текущим безголовым Chrome заключается в том, что нет API для отображения полной страницы, вы получаете только «окно», которое вы установили в параметре CLI.

Я использую модуль chrome-remote-interface, это пример захвата:

const fs = require('fs');
const CDP = require('chrome-remote-interface');

CDP({ port: 9222 }, client => {

    // extract domains
    const {Network, Page} = client;

    Page.loadEventFired(() => {
        const startTime = Date.now();
        setTimeout(() => {
            Page.captureScreenshot()
            .then(v => {
                let filename = `screenshot-${Date.now()}`;
                fs.writeFileSync(filename + '.png', v.data, 'base64');
                console.log(`Image saved as ${filename}.png`);
                let imageEnd = Date.now();
                console.log('image success in: ' + (+imageEnd - +startTime) + "ms");
                client.close();
            });
        }, 5e3);

    });
    // enable events then start!
    Promise.all([
        // Network.enable(),
        Page.enable()
    ]).then(() => {
        return Page.navigate({url: 'https://google.com'});
    }).catch((err) => {
        console.error(`ERROR: ${err.message}`);
        client.close();
    });
}).on('error', (err) => {
    console.error('Cannot connect to remote endpoint:', err);
});

Для рендеринга всей страницы одним более медленным и хитрым решением будет частичный рендеринг. Установите фиксированную высоту, прокручивайте страницу и делайте скриншоты через каждые X пикселей. Проблема в том, как управлять прокручиваемой частью? Было бы лучше внедрить собственный JS или это можно сделать через удаленный интерфейс Chrome?


person Risto Novik    schedule 14.04.2017    source источник


Ответы (2)


Вы видели это?

https://medium.com/@dschnr/using-headless-chrome-as-an-automated-screenshot-tool-4b07dffba79a

Этот бит звучит так, как будто он решит вашу проблему:

  // Wait for page load event to take screenshot
  Page.loadEventFired(async () => {
    // If the `full` CLI option was passed, we need to measure the height of
    // the rendered page and use Emulation.setVisibleSize
    if (fullPage) {
      const {root: {nodeId: documentNodeId}} = await DOM.getDocument();
      const {nodeId: bodyNodeId} = await DOM.querySelector({
        selector: 'body',
        nodeId: documentNodeId,
      });
      const {model: {height}} = await DOM.getBoxModel({nodeId: bodyNodeId});

      await Emulation.setVisibleSize({width: viewportWidth, height: height});
      // This forceViewport call ensures that content outside the viewport is
      // rendered, otherwise it shows up as grey. Possibly a bug?
      await Emulation.forceViewport({x: 0, y: 0, scale: 1});
    }

    setTimeout(async function() {
      const screenshot = await Page.captureScreenshot({format});
      const buffer = new Buffer(screenshot.data, 'base64');
      file.writeFile('output.png', buffer, 'base64', function(err) {
        if (err) {
          console.error(err);
        } else {
          console.log('Screenshot saved');
        }
        client.close();
      });
    }, delay);
  });
person dpd    schedule 15.06.2017
comment
Это хорошее начало, но лениво загруженные изображения покажут свои заполнители. - person Drakes; 09.07.2017

Удаленный интерфейс Chrome поддерживает имитацию жестов прокрутки с использованием домена ввода.

// scroll down y axis 9000px 
Input.synthesizeScrollGesture({x: 500, y: 500, yDistance: -9000});

дополнительная информация: https://chromedevtools.github.io/devtools-protocol/tot/Input/

Вас также может заинтересовать домен эмуляции. Ответ dpd содержит несколько удаленных методов. Я считаю, что Emulation.setVisibleSize может вам помочь.

https://chromedevtools.github.io/devtools-protocol/tot/Emulation/< /а>

person nibty    schedule 24.07.2017