Protocol error page navigate target closed

Как видно из приведенного ниже примера кода, я использую Puppeteer с кластером воркеров в Node для выполнения нескольких запросов снимков экрана веб-сайтов по заданному URL-адресу: const cluster = require('cluster'); const express = require('express'); const bodyParser = require('body-parser'); cons...

Как видно из приведенного ниже примера кода, я использую Puppeteer с кластером воркеров в Node для выполнения нескольких запросов снимков экрана веб-сайтов по заданному URL-адресу:

const cluster = require('cluster');
const express = require('express');
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');

async function getScreenshot(domain) {
    let screenshot;
    const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] });
    const page = await browser.newPage();

    try {
        await page.goto('http://' + domain + '/', { timeout: 60000, waitUntil: 'networkidle2' });
    } catch (error) {
        try {
            await page.goto('http://' + domain + '/', { timeout: 120000, waitUntil: 'networkidle2' });
            screenshot = await page.screenshot({ type: 'png', encoding: 'base64' });
        } catch (error) {
            console.error('Connecting to: ' + domain + ' failed due to: ' + error);
        }

    await page.close();
    await browser.close();

    return screenshot;
}

if (cluster.isMaster) {
    const numOfWorkers = require('os').cpus().length;
    for (let worker = 0; worker < numOfWorkers; worker++) {
        cluster.fork();
    }

    cluster.on('exit', function (worker, code, signal) {
        console.debug('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
        Cluster.fork();
    });

    cluster.on('message', function (handler, msg) {
        console.debug('Worker: ' + handler.process.pid + ' has finished working on ' + msg.domain + '. Exiting...');
        if (Cluster.workers[handler.id]) {
            Cluster.workers[handler.id].kill('SIGTERM');
        }
    });
} else {
    const app = express();
    app.use(bodyParser.json());
    app.listen(80, function() {
        console.debug('Worker ' + process.pid + ' is listening to incoming messages');
    });

    app.post('/screenshot', (req, res) => {
        const domain = req.body.domain;

        getScreenshot(domain)
            .then((screenshot) =>
                try {
                    process.send({ domain: domain });
                } catch (error) {
                    console.error('Error while exiting worker ' + process.pid + ' due to: ' + error);
                }

                res.status(200).json({ screenshot: screenshot });
            })
            .catch((error) => {
                try {
                    process.send({ domain: domain });
                } catch (error) {
                    console.error('Error while exiting worker ' + process.pid + ' due to: ' + error);
                }

                res.status(500).json({ error: error });
            });
    });
}

Некоторое объяснение:

  1. Каждый раз, когда поступает запрос, воркер обрабатывает его и в конце убивает себя.
  2. Каждый рабочий создает новый экземпляр браузера с одной страницей, и если для загрузки страницы потребовалось более 60 секунд, он попытается перезагрузить ее (на той же странице, потому что, возможно, некоторые ресурсы уже были загружены) с таймаутом 120 секунд.
  3. После завершения и страница, и браузер будут закрыты.

Моя проблема в том, что в некоторых законных доменах возникают ошибки, которые я не могу объяснить:

Error: Protocol error (Page.navigate): Target closed.
Error: Protocol error (Runtime.callFunctionOn): Session closed. Most likely the page has been closed.

Я читал о какой-то проблеме с git (которую я сейчас не могу найти), что это может произойти, когда страница перенаправляется и добавляет в начале ‘www’, но я надеюсь, что это неверно … Что-то мне не хватает?

6 ответов

Лучший ответ

Что означает «Цель закрыта»

Когда вы запускаете браузер через puppeteer.launch, он запускает браузер и подключается к нему. Оттуда любая функция, которую вы выполняете в открытом браузере (например, page.goto), будет отправляться через Протокол Chrome DevTools в браузер. В данном контексте цель означает вкладку.

Исключение Target closed выдается, когда вы пытаетесь запустить функцию, но цель (вкладка) уже закрыта.

Подобные сообщения об ошибках

Сообщение об ошибке было недавно изменено, чтобы дать более значимую информацию. Теперь он дает следующее сообщение:

Ошибка: ошибка протокола (Target.activateTarget): сеанс закрыт. Скорее всего страницу закрыли.


Почему это происходит

Это могло произойти по нескольким причинам.

  • Вы использовали уже закрытый ресурс

    Скорее всего, вы видите это сообщение, потому что вы закрыли вкладку / браузер и все еще пытаетесь использовать ресурс. Приведу простой пример:

    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    
    await browser.close();
    await page.goto('http://www.google.com');
    

    В этом случае браузер был закрыт, и после этого был вызван page.goto, что привело к сообщению об ошибке. В большинстве случаев это не так очевидно. Возможно, обработчик ошибок уже закрыл страницу во время задачи очистки, а ваш скрипт все еще сканирует.

  • В браузере произошел сбой или не удалось инициализировать

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

    Я не нашел «серебряной пули» решения этой проблемы. Но вы можете проверить библиотеку puppeteer-cluster (отказ от ответственности: я автор) который обрабатывает такие случаи ошибок и позволяет вам повторно вводить URL-адрес, когда возникает ошибка. Он также может управлять пулом экземпляров браузера и упростить ваш код.


61

Thomas Dondorf
6 Апр 2019 в 21:01

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

Я заставил его работать, удалив и переустановив пакет кукловода:

npm remove puppeteer
npm i puppeteer

* Я столкнулся с этой проблемой только при установке параметра headless на ‘false’


9

Timo
27 Июл 2020 в 18:47

На мой взгляд, удаление '--single-process' из args устранило проблему.

puppeteerOptions: {
    headless: true,
    args: [
        '--disable-gpu',
        '--disable-dev-shm-usage',
        '--disable-setuid-sandbox',
        '--no-first-run',
        '--no-sandbox',
        '--no-zygote',
        '--deterministic-fetch',
        '--disable-features=IsolateOrigins',
        '--disable-site-isolation-trials',
        // '--single-process',
    ],
}


8

Shaig Khaligli
8 Апр 2021 в 00:45

В 2021 году я получаю очень похожую следующую ошибку Error: Error pdf creationError: Protocol error (Target.setDiscoverTargets): Target closed., я решил ее, играя с разными аргументами, поэтому, если на вашем производственном сервере есть флаг pipe:true в объекте puppeteer.launch, это приведет к ошибкам .

Также флаг --disable-dev-shm-usage поможет

Приведенное ниже решение работает для меня:

const browser = await puppeteer.launch({
  headless: true,
  // pipe: true, <-- delete this property
  args: [
    '--no-sandbox',
    '--disable-dev-shm-usage', // <-- add this one
    ],
});


6

Igor Kurkov
15 Мар 2021 в 22:14

Проверьте свой файл jest-puppeteer.config.js. Я сделал ошибку ниже

module.exports = {
    launch: {
        headless: false,
        browserContext: "default",
    },
};

И после исправления, как показано ниже

module.exports = {
    launch: {
        headless: false
    },
    browserContext: "default",
};

Все работало отлично !!!


1

Shashank Shukla
27 Июн 2020 в 21:43

После нескольких часов разочарований я понял, что это происходит, когда он переходит на новую страницу, и мне нужно использовать await page.waitForNavigation(), прежде чем я что-либо сделаю, и после того, как я нажму кнопку или выполню любое действие, которое вызовет перенаправление.


1

destroyer22719
7 Апр 2022 в 21:15

Как вы можете видеть с примером кода ниже, я использую Puppeteer с кластером рабочих в Node для запуска нескольких запросов скриншотов веб-сайтов по заданному URL-адресу:

const cluster = require('cluster');
const express = require('express');
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');

async function getScreenshot(domain) {
let screenshot;
const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'] });
const page = await browser.newPage();

try {
await page.goto('http://' + domain + '/', { timeout: 60000, waitUntil: 'networkidle2' });
} catch (error) {
try {
await page.goto('http://' + domain + '/', { timeout: 120000, waitUntil: 'networkidle2' });
screenshot = await page.screenshot({ type: 'png', encoding: 'base64' });
} catch (error) {
console.error('Connecting to: ' + domain + ' failed due to: ' + error);
}

await page.close();
await browser.close();

return screenshot;
}

if (cluster.isMaster) {
const numOfWorkers = require('os').cpus().length;
for (let worker = 0; worker < numOfWorkers; worker++) {
cluster.fork();
}

cluster.on('exit', function (worker, code, signal) {
console.debug('Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal);
Cluster.fork();
});

cluster.on('message', function (handler, msg) {
console.debug('Worker: ' + handler.process.pid + ' has finished working on ' + msg.domain + '. Exiting...');
if (Cluster.workers[handler.id]) {
Cluster.workers[handler.id].kill('SIGTERM');
}
});
} else {
const app = express();
app.use(bodyParser.json());
app.listen(80, function() {
console.debug('Worker ' + process.pid + ' is listening to incoming messages');
});

app.post('/screenshot', (req, res) => {
const domain = req.body.domain;

getScreenshot(domain)
.then((screenshot) =>
try {
process.send({ domain: domain });
} catch (error) {
console.error('Error while exiting worker ' + process.pid + ' due to: ' + error);
}

res.status(200).json({ screenshot: screenshot });
})
.catch((error) => {
try {
process.send({ domain: domain });
} catch (error) {
console.error('Error while exiting worker ' + process.pid + ' due to: ' + error);
}

res.status(500).json({ error: error });
});
});
}

Некоторое объяснение:

Каждый раз, когда запрос приходит, рабочий обрабатывает его и убивает себя в конце Каждый рабочий создает новый экземпляр браузера с одной страницей, и если на страницу загружено более 60 секунд, он будет перезагружать его (на той же странице, потому что, возможно, некоторые ресурсы уже загружены) с тайм-аутом 120 секунд После завершения как страницы, так и браузера будут закрыты

Моя проблема в том, что некоторые легитимные домены получают ошибки, которые я не могу объяснить:

Error: Protocol error (Page.navigate): Target closed.
Error: Protocol error (Runtime.callFunctionOn): Session closed. Most likely the page has been closed.

Я читал в какой-то git-проблеме (которую я не могу найти сейчас), что это может произойти, когда страница перенаправляет и добавляет «www» в начале, но я надеюсь, что она будет ложной… Есть ли что-то, что мне не хватает?

rawbin-

Error Protocol Error Target Closed with many type of reason

Steps to reproduce

it is an error occurs with probability, with the following script we can always see it

repro demo:
https://github.com/rawbin-/puppeteer-test/blob/master/protocol-error-target-closed-repo.js

node protocol-error-target-closed-repo.js
Tell us about your environment:

  • Puppeteer version: 2.0.0/2.1.1/3.0.0
  • Platform / OS version: CentOS/MacOS 10.15.3 (19D76)
  • URLs (if applicable): https://github.com/rawbin-/puppeteer-test/blob/master/protocol-error-target-closed-repo.js
  • Node.js version: 12.14

What steps will reproduce the problem?
node protocol-error-target-closed-repo.js

Please include code that reproduces the issue.
https://github.com/rawbin-/puppeteer-test/blob/master/protocol-error-target-closed-repo.js

What is the expected result?
no Protocol error

What happens instead?
different exception occurs from time to time

Error: Protocol error (Emulation.setDeviceMetricsOverride): Target closed.
Error: Protocol error (Target.setAutoAttach): Target closed.
Error: Protocol error (Page.setLifecycleEventsEnabled): Target closed.
Error: Protocol error (Target.setAutoAttach): Target closed.
Error: Protocol error (Log.enable): Target closed.
Error: Protocol error (Performance.enable): Target closed.
Error: Protocol error (Page.enable): Target closed.
Error: Protocol error (Target.attachToTarget): No target with given id found
Error: Protocol error (Page.getFrameTree): Target closed.
Error: Protocol error (Emulation.setTouchEmulationEnabled): Target closed.
Protocol error (Emulation.setDeviceMetricsOverride): Session closed. Most likely the page has been closed.

image

more detail:

    try{
        openPages = await broswer.pages(); // here throws differents exceptions
    }catch (e) {
        // console.warn(broswer.isConnected(),broswer,broswer.target(),broswer.wsEndpoint())
        console.warn('get pages failed:',e)
        await broswer.close();
        process.exit(1)
        return
    }

duxiaofeng-github

i’m facing the same issue here.

i run a simple service and running a headless chromium to render a simple poster. i guess it caused by memory used up.

here’s the error stack:

Error: Protocol error (Emulation.setDeviceMetricsOverride): Session closed. Most likely the page has been closed.
      at CDPSession.send (/node_modules/puppeteer/lib/Connection.js:180:29)
      at EmulationManager.emulateViewport (/node_modules/puppeteer/lib/EmulationManager.js:41:20)
      at Page.setViewport (/node_modules/puppeteer/lib/Page.js:763:54)
      at Page. (/node_modules/puppeteer/lib/helper.js:111:23)
      at handleTask (/poster-gen/src/generator.js:73:6)
      at Promise (/poster-gen/src/generator.js:105:7)
      at new Promise ()
      at htmlToImage (/poster-gen/src/generator.js:101:10)
      at Object.generate (/poster-gen/src/generator.js:195:28)
      at handler (/poster-gen/src/fission-poster.js:21:35)
    -- ASYNC --
      at Page. (/node_modules/puppeteer/lib/helper.js:110:27)
      at handleTask (/poster-gen/src/generator.js:73:6)
      at Promise (/poster-gen/src/generator.js:105:7)
      at new Promise ()
      at htmlToImage (/poster-gen/src/generator.js:101:10)
      at Object.generate (/poster-gen/src/generator.js:195:28)
      at handler (/poster-gen/src/fission-poster.js:21:35)
      at process._tickCallback (internal/process/next_tick.js:68:7)

MarianAlexandruAlecu

Any updates on this? We’re experiencing the same issue ⬆️

SoraDaibu-Makip

Any updates on this issue? We are experiencing the same error a few times for one crawling.

stale

We’re marking this issue as unconfirmed because it has not had recent activity and we weren’t able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

jlvernam

Same issue here, ran into it Today- Jun 28th. Any updates?

yki-hong

Same issue here, any updates?

chrisdel101

How can I fix this? Puppeteer keeps crashing when I call it from inside a loop. Each call makes:

 const browser = await puppeteer.launch({
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox', '--use-gl=egl'],
    })```

OrKoN

I was not able to repro in the latest version. It is possible that the page gets closed/shut down by the browser for whatever reason, in that case you can get those errors. Please re-open with a recent repro if it’s still an issue.

fademan01

I hit this error whenever running from terminal of VS Code , but it doesn’t happen on native terminal. Probably it releates to memory used.

jacty

Try to turn off headless mode to see if the page closed or crashed accidentally.

Понравилась статья? Поделить с друзьями:
  • Prology imap open registry error prology
  • Protocol error occurred error was returned from the destination server перевод
  • Protocol error not enough cash
  • Protocol error minecraft server
  • Prolog program error 7002