Кукольник не закрывает браузер - PullRequest
0 голосов
/ 27 декабря 2018

Я управляю кукловодом в Express / Node / Ubuntu следующим образом:

var puppeteer = require('puppeteer');
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
    (async () => {
        headless = true;
        const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
        const page = await browser.newPage();
        url = req.query.url;
        await page.goto(url);
        let bodyHTML = await page.evaluate(() => document.body.innerHTML);
        res.send(bodyHTML)
        await browser.close();
    })();
});

запуск этого скрипта несколько раз оставляет сотни зомби:

$ pgrep chrome | wc -l
133

, который забивает srv,

Как это исправить?

Запуск kill из сценария Express JS может решить эту проблему?

Есть ли лучший способ получить тот же результат, кроме кукловодаи безголовый хром?

Ответы [ 5 ]

0 голосов
/ 17 августа 2019

Я столкнулся с той же проблемой, и хотя ваше решение shelljs сработало, оно убивает все процессы chrome, которые могут прервать процесс, который все еще обрабатывает запрос.Вот лучшее решение, которое должно работать.

var puppeteer = require('puppeteer');
var express = require('express');
var router = express.Router();

router.get('/', function (req, res, next) {
    (async () => {
        await puppeteer.launch({ headless: true }).then(async browser => {
            const page = await browser.newPage();
            url = req.query.url;
            await page.goto(url);
            let bodyHTML = await page.evaluate(() => document.body.innerHTML);
            await browser.close();
            res.send(bodyHTML);
        });
    })();
});
0 голосов
/ 19 июля 2019

Ааа!Это простой недосмотр.Вы пытаетесь закрыть браузер после отправки ответа.Поток выполнения останавливается после отправки ответа, и ваш await browser.close() никогда не выполняется, в результате чего вы остаетесь с зомби.

Использование shell.js кажется хакерским способом решения этой проблемы.

Вы могли быпросто поменяйте местами две строки res.send(bodyHTML) и await browser.close().

Однако лучше использовать try..catch..finally.Причина в том, что вы хотите, чтобы браузер закрывался, независимо от того, удачен ли поток или выдается ошибка.И, в отличие от другого фрагмента кода, вам не нужно пытаться закрыть браузер как в блоке catch, так и в блоке finally.Блок finally всегда выполняется независимо от того, выдана ошибка или нет.

Итак, ваш код должен выглядеть следующим образом:

const puppeteer = require('puppeteer');
const express = require('express');

const router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  (async () => {
    try {
      headless = true;
      const browser = await puppeteer.launch({
        headless: true,
        args: ['--no-sandbox'],
      });
      const page = await browser.newPage();
      url = req.query.url;
      await page.goto(url);
      const bodyHTML = await page.evaluate(() => document.body.innerHTML);
      res.send(bodyHTML);
    } catch (e) {
      console.log(e);
    } finally {
      await browser.close();
    }
  })();
});

Надеюсь, это поможет!

0 голосов
/ 27 декабря 2018

оберните ваш код в try-catch следующим образом и посмотрите, поможет ли это

headless = true;
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
try {
  const page = await browser.newPage();
  url = req.query.url;
  await page.goto(url);
  let bodyHTML = await page.evaluate(() => document.body.innerHTML);
  res.send(bodyHTML);
  await browser.close();
} catch (error) {
  console.log(error);
  await browser.close();
} finally {
  await browser.close();
}
0 голосов
/ 04 марта 2019

попробуйте закрыть браузер перед отправкой ответа

var puppeteer = require('puppeteer');
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
    (async () => {
        headless = true;
        const browser = await puppeteer.launch({headless: true});
        const page = await browser.newPage();
        url = req.query.url;
        await page.goto(url);
        let bodyHTML = await page.evaluate(() => document.body.innerHTML);
        await browser.close();
        res.send(bodyHTML);
    })();
});
0 голосов
/ 27 декабря 2018

Я решаю это с https://www.npmjs.com/package/shelljs

var shell = require('shelljs');
shell.exec('pkill chrome')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...