Как настроить Puppeteer для правильного рендеринга внешних JS-страниц? Работает только для URL-адресов Localhost

Я пытаюсь настроить рендеринг на стороне сервера для внешних страниц Javascript. Я использую Puppeteer для этой цели, и когда я предоставляю какой-либо внешний URL-адрес (не страницы localhost), Puppeteer извлекает только исходный код URL-адреса (который вы можете видеть в режиме просмотра исходного кода запрошенной страницы), не отображая всю DOM . Когда я пытаюсь использовать SSR для любого URL-адреса страницы Javascript локального хоста (страница, созданная тем же сервером node js на моем локальном хосте) - все работает нормально.

Сообщите, пожалуйста, что-то не хватает или мне нужно попробовать другой подход.

Мне удалось настроить кукольника со всеми зависимостями на моем локальном хосте, как показано ниже:

В настоящее время переменная 'html' возвращает только исходный код полученного URL-адреса, мне нужно получить полностью визуализированную DOM запрошенного URL-адреса.

Код в server.js

var puppeteer = require('puppeteer');

async function ssr(url) {
  console.info('rendering the page in ssr mode');
  const browser = await puppeteer.launch({headless: true});
  const page = await browser.newPage();

  try {
    await page.goto(url, {waitUntil: 'domcontentloaded'});
  } catch (err) {
    console.error(err);
    throw new Error('page.goto/waitForSelector timed out.');
  }

  const html = await page.content();
  await browser.close();
  return {html};
}

module.exports = ssr;

Код в app.js

var err = require('http-errors');
var express = require('express');
var path = require('path');
var ssr = require('./ssr.js');

var app = express();

app.listen(3000, function(){ console.info('Server listening on port '); });

app.use('/index/', async(req, res) => {
  const { html } = await ssr(`www.example.com`);
  return res.send(html);
});

person web_master    schedule 26.03.2019    source источник


Ответы (2)


Вероятно, проблема в том, что вы не даете странице достаточно времени для отображения содержимого DOM. {waitUntil: 'domcontentloaded'} будет ждать только события DOMContentLoaded, но не каких-либо запросов AJAX или DOM. модификации.

Попробуйте использовать 'networkidle0' или 'load' в качестве waitUntil значения страницы .goto вместо этого.

Если это не сработает, у вас есть два варианта:

  • Дайте странице фиксированное количество времени для отображения страницы с помощью _ 5_
  • Используйте await page.waitForSelector(/* ... */), чтобы дождаться определенного селектора загружается перед вызовом page.content(). Так вы сможете убедиться, что интересующие вас части документа загружены.
person Thomas Dondorf    schedule 26.03.2019
comment
Я действительно пробовал использовать параметры, описанные в официальной документации Google: 'networkidle0', 'networkidle2' и page.waitForSelector (...), прежде чем опубликовать свой публичный вопрос, но результат был таким же - только исходный html-код URL-адреса ( как если бы я проверял страницу в режиме просмотра исходного кода) был возвращен Puppeteer. Все это отлично работает только для страниц, созданных NodeJS на локальном хосте. Даже не знаю, что проверить. - person web_master; 26.03.2019
comment
Привет, Томас! К сожалению, это не так ... Может быть, это из-за localhost (но, думаю, для этого нет никаких причин). Люди с форума Chrome DEV не отвечают. Без понятия... - person web_master; 02.04.2019
comment
Я получаю в терминале 404 отчета по всем связанным скриптам и изображениям ... - person web_master; 02.04.2019

пытаться

const html = 'what ever you selector is but since you want the html just type in "html"'; 

let gg = await page.evaluate((sel) => {
        let element = document.querySelector(sel);
        console.log ('got Boom');
        return element? element.innerHTML: null;
    }, html);


    console.log (gg);

person Rakan Habab    schedule 26.03.2019
comment
Привет, Раках Хабаб! - person web_master; 27.03.2019
comment
Спасибо за ответ! Я еще не эксперт, не могли бы вы пояснить, где именно мне следует интегрировать предоставленный вами фрагмент кода? - person web_master; 27.03.2019
comment
Внутри вашего заявления try - person Rakan Habab; 27.03.2019
comment
Спасибо, Раках. Попробовал - снова в терминале возвращается только исходный код запрашиваемой страницы, DOM-сборка JS не рендерится. Не знаю, что делать тогда ... - person web_master; 27.03.2019
comment
Я не знаю, какой результат вам нужен. Например, хотите ли вы, чтобы текст заголовка, в данном случае это Пример, ИЛИ вы хотите, чтобы это было так? ‹H› Пример ‹\ h› - person Rakan Habab; 27.03.2019
comment
Я хочу в выводе получить HTML-результат визуализации Javascript. Другими словами, чтобы получить полностью отрисованную DOM. - person web_master; 27.03.2019
comment
мне очень странно, что если я попытаюсь отобразить страницу Javascript, сгенерированную тем же сервером nodejs на Localhost, все содержимое javascript будет правильно отображаться в HTML. Не могу понять, почему Puppeteer не может сделать то же самое для других внешних URL-адресов - person web_master; 27.03.2019
comment
ну, это называется бэкэнд и интерфейс по той причине, что javascript выполняет свою работу в бэкэнде и выводит его для пользователя в переведенный HTML-файл, который является передним концом. Кукловод смотрит на интерфейс страницы (видимую часть для браузера) и использует ее. - person Rakan Habab; 27.03.2019