node.js - 如何让 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
...
...
几个星期以来,我一直在寻找解决方案。难道这件事不再起作用了吗?
解决方案
在查看此线程后,将其确定为 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=HTMLImports
in 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()}`));
推荐阅读
- python - 如何在 python 中编写一个函数,将 2 个数字和 1 个字符串作为输入
- flutter - Flutter 中的 Android Java 注解
- docker - 远程访问在 WSL 2 上的 docker 容器中运行的 jupyter notebook
- javascript - 使用 npm 安装 ply 时没有获取此类文件或目录
- javascript - 如何让侧面菜单栏根据鼠标位置移动并立即做出反应?
- javascript - 如何在 React 中播放音频 onClick?
- css - Quasar Vue:在网格样式上设置静态宽度内容
- python - 通过将字符串列转换为pyspark中的整数类型来获取非空值的计数 - sql
- javascript - 等效于 fs.readFile() -> 到 -> 在 DOM 中上传 HTML
- python - 更新矢量化函数内的 tqdm 进度条