puppeteer - Puppeteer:在 browser.disconnect 之后,Chromium 实例在后台保持活动状态
问题描述
我的环境
- 木偶版:3.1.0
- 平台/操作系统版本:Windows 10
- Node.js 版本:12.16.1
我的问题是:
我有一个for...of
循环可以使用 puppeteer 访问 3000 多个网址。我习惯puppeteer.connect
了,wsEndpoint
所以我可以重用一个浏览器实例。每次访问后我都会断开连接并关闭选项卡。
- 前 100 个
page.goto
urls 立即打开 urls, - 超过 100
page.goto
次,每个 url 使用 2-3 次重试, - 超过 300
page.goto
次,每个 url 使用 5-8 次重试, - 500以上我
TimeoutError: Navigation timeout of 30000 ms exceeded
一直都在。
我检查了 Windows 任务管理器,发现有数百个 Chromium 实例在后台运行,每个实例使用 80-90MB 的内存和 1-2% 的 CPU。
问题
我怎样才能真正杀死我已经断开连接的 Chromium 实例browser.disconnect
?
示例脚本
const puppeteer = require('puppeteer')
const urlArray = require('./urls.json') // contains 3000+ urls in an array
async function fn() {
const browser = await puppeteer.launch({ headless: true })
const browserWSEndpoint = await browser.wsEndpoint()
for (const url of urlArray) {
try {
const browser2 = await puppeteer.connect({ browserWSEndpoint })
const page = await browser2.newPage()
await page.goto(url) // in my original code it's also wrapped in a retry function
// doing cool things with the DOM
await page.goto('about:blank') // because of you: https://github.com/puppeteer/puppeteer/issues/1490
await page.close()
await browser2.disconnect()
} catch (e) {
console.error(e)
}
}
await browser.close()
}
fn()
错误
通常的 puppeteer 超时错误。
TimeoutError: Navigation timeout of 30000 ms exceeded
at C:\[...]\node_modules\puppeteer\lib\LifecycleWatcher.js:100:111
-- ASYNC --
at Frame.<anonymous> (C:\[...]\node_modules\puppeteer\lib\helper.js:94:19)
at Page.goto (C:\[...]\node_modules\puppeteer\lib\Page.js:476:53)
at Page.<anonymous> (C:\[...]\node_modules\puppeteer\lib\helper.js:95:27)
at example (C:\[...]\example.js:13:18)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
name: 'TimeoutError'
}
解决方案
最后,我能够通过在启动时添加--single-process
和--no-zygote
args 来达到预期的结果(--no-sandbox
它们需要 +)。
正在运行的 Chromium 进程的数量不再呈指数增长,但只有两个实例保持活动状态:其中一个是第一个位置的通常空选项卡,第二个被puppeteer.connect({ browserWSEndpoint })
.
[...]
const browser = await puppeteer.launch({
headless: true,
args: ['--single-process', '--no-zygote', '--no-sandbox']
})
const browserWSEndpoint = await browser.wsEndpoint()
[...]
--single-process
:在与浏览器相同的进程中运行渲染器和插件[来源]--no-zygote
: Disables the use of a zygote process for forking child processes. Instead, child processes will be forked and exec'd directly. Note that --no-sandbox should also be used together with this flag because the sandbox needs the zygote to work. [source]
推荐阅读
- reactjs - 是否可以将函数传递给 Chakra 的 isInvalid 属性?
- java - Selenium Java,测试名称和价格时某些产品的 Np 价格
- python - 有时我看到这个 JSONDecodeError 有时我没有
- python - 如何指定谷歌幻灯片 API PNG 导出的图像大小?
- python - Tkinter 按钮卡在负载上
- python - 为什么机器人将消息发送到私人消息而不是组?
- cmd - regedit 和 cmd 以及 .exe 文件打不开
- google-apps-script - 为每个谷歌表单响应创建新文件夹
- css - react中根据父容器的宽度渲染不同的html元素
- flutter - 如何根据 Flutter 中的数据库查询对 listView 进行分组?