javascript - 为什么 Puppeteer 工作的 headless 需要是 false 的?
问题描述
我正在创建一个 Web api,它会抓取给定的 url 并将其发回。我正在使用 Puppeteer 来执行此操作。我问了这个问题:Puppeteer not behavior like in Developer Console
并收到一个答案,表明它只有在 headless 设置为 false 时才有效。我不想经常打开一个我不需要的浏览器 UI(我只需要数据!)所以我正在寻找为什么 headless 必须是 false 并且我可以得到一个让 headless = true 的修复.
这是我的代码:
express()
.get("/*", (req, res) => {
global.notBaseURL = req.params[0];
(async () => {
const browser = await puppet.launch({ headless: false }); // Line of Interest
const page = await browser.newPage();
console.log(req.params[0]);
await page.goto(req.params[0], { waitUntil: "networkidle2" }); //this is the url
title = await page.$eval("title", (el) => el.innerText);
browser.close();
res.send({
title: title,
});
})();
})
.listen(PORT, () => console.log(`Listening on ${PORT}`));
解决方案
它可能在 UI 模式下工作但不是无头模式的原因是那些积极反对抓取的网站会检测到你在无头浏览器中运行。
一些可能的解决方法:
利用puppeteer-extra
在这里找到:https ://github.com/berstend/puppeteer-extra 查看他们的文档以了解如何使用它。它有几个插件可能有助于通过无头模式检测:
puppeteer-extra-plugin-anonymize-ua
-- 匿名你的用户代理。请注意,这可能有助于通过无头模式检测,但正如您将看到的那样,如果您访问https://amiunique.org/,它可能不足以阻止您被识别为重复访问者。puppeteer-extra-plugin-stealth
- 这可能有助于赢得不被检测为无头的猫捉老鼠游戏。有许多技巧可用于检测无头模式,也有许多技巧可以规避它们。
运行“真实”的 Chromium 实例/UI
可以以让您将 puppeteer 附加到该运行实例的方式运行单个浏览器 UI。这是一篇解释它的文章:https ://medium.com/@jaredpotter1/connecting-puppeteer-to-existing-chrome-window-8a10828149e0
本质上,您是从命令行使用--remote-debugging-port=9222
(或任何旧端口?)以及其他命令行开关启动 Chrome 或 Chromium(或 Edge?),具体取决于您运行它的环境。然后您使用 puppeteer 连接到该运行实例而不是让它执行启动无头 Chromium 实例的默认行为:const browser = await puppeteer.connect({ browserURL: ENDPOINT_URL });
. 在此处阅读 puppeteer 文档以获取更多信息:https ://pptr.dev/#?product=Puppeteer&version=v5.2.1&show=api-puppeteerlaunchoptions
当您使用该选项ENDPOINT_URL
从命令行启动浏览器时,会显示在终端中。--remote-debugging-port=9222
此选项将需要一些服务器/操作 mojo,因此请准备好进行更多 Stack Overflow 搜索。:-)
我确定还有其他策略,但这是我最熟悉的两个。祝你好运!
推荐阅读
- python - 如何定位/导入我的带有破折号的 plaid-python python 模块?
- tensorflow - 如何将 tfrecord 拆分为多个 tfrecord?
- excel - 使用粘贴方法获取运行时错误 1004
- python - 连接大量具有相同列和相同索引的熊猫数据框
- botframework - 使用 BotFramework Dispatch 的最佳情况
- mysql - 我应该使用什么方法在 SQL 中存储大量数据?
- javascript - 从 Object.entries 中提取值
- android - Kodein:在 FirebaseMessagingService 中检索绑定
- mysql - 如果表中不存在参数,如何抛出错误处理程序?
- swift - NSSavePannel - 如何限制用户只保存一组目录?