首页 > 解决方案 > 如何让 puppeteer 简单地加载网页?

问题描述

我不能让傀儡师做任何事情。我只是想让它显示 google.com,但我什至无法让它这样做。这是我的代码:

console.log('Loading puppeteer...');
const puppeteer = require('puppeteer');

async function test() {
    console.log('Launching browser...');
    const browser = await puppeteer.launch({headless: false});
  
    console.log('Creating new page...');
    const page = await browser.newPage();
    
    console.log('Requesting url...');
    await page.goto('https://www.google.com');

    console.log('Closing browser...');
    await browser.close();
}

test().catch(e=>{console.log(e)});

每次我尝试做任何事情时,Chromium 都会崩溃......

铬崩溃

然后我得到一个超时错误:

Loading puppeteer...
Launching browser...
TimeoutError: waiting for target failed: timeout 30000ms exceeded
...
...

几个星期以来,我一直在寻找解决方案。难道这件事不再起作用了吗?

标签: node.jswindowspuppeteer

解决方案


在查看此线程后,将其确定为 Puppeteer 的一个众所周知的问题,这里有一些关于 Puppeteer 超时问题的更多信息。

Puppeteer.launch() 有两个部分会导致超时问题。一种是goto超时,另一种是waitfor超时。由于我不知道是什么可能导致您的特定问题,因此我将为您提供两者的潜在解决方案。

可能的问题 #1:Goto 超时。

我将直接引用发布此解决方案的人 rudiedirkx:

在我的情况下,goto 超时是由于永久加载阻塞资源(js 或 css)而发生的。这永远不会触发页面的加载或 domcontentloaded。Puppeteer IMO 中的一个错误,但无论如何。

我的修复(终于!)是做 Lighthouse 在其驱动程序中所做的事情:一个 Promise.race() 用于自定义“超时”-ish。我使用的较短版本:

    const LOAD_FAIL = Math.random();
const sleep = options => new Promise(resolve => {
    options.timer = setTimeout(resolve, options.ms, options.result === undefined ? true : options.result);
});

const sleepOptions = {ms: TIMEOUT - 1000, result: LOAD_FAIL};
const response = await Promise.race([
    sleep(sleepOptions),
    page.goto(url, {timeout: TIMEOUT + 1000}),
]);
clearTimeout(sleepOptions.timer);
const success = response !== LOAD_FAIL;

可能的问题 #2:Waitfor 超时。

或者,您可以尝试解决经销商给出的等待超时的解决方案,添加 -- enable-blink-features=HTMLImportsin args

browser = await puppeteer.launch({
        //headless: false,
        'args': [
            '--enable-blink-features=HTMLImports'
        ]
    });

如果这些都不起作用

如果这些解决方案都不起作用,我建议浏览该线程以找到人们建议的更多解决方案,看看是否可以缩小问题范围。使用此代码生成一些控制台日志,看看是否能找到问题所在:

page
    .on('console', message =>
    console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`))
    .on('pageerror', ({ message }) => console.log(message))
    .on('response', response =>
    console.log(`${response.status()} ${response.url()}`))
    .on('requestfailed', request =>
    console.log(`${request.failure().errorText} ${request.url()}`));

推荐阅读