Node.js未检测到的指纹浏览器:Puppeteer和Playwright
Expert in Web Scraping Technologies
TL;DR:
- 在 Node.js 中,浏览器是被检测的原因,而不是你的代码。 Puppeteer 和 Playwright 都通过 DevTools 协议驱动 Chromium,并且都通过一个 URL 连接到远程浏览器,因此解决方案是改变浏览器运行的位置,而不是重写脚本。
- 本地 Node.js 浏览器在三个方面同时泄漏自动化信息:
navigator.webdriver标志、默认的无头指纹,以及你自己的出口 IP。检测器会将这三者共同评分,这就是为什么逐一修补永远无法完全成立的原因。 - 一个终端点服务于两个库。
wss://browser.scrapeless.com/api/v2/browser是一个 CDP 端点 —puppeteer.connect({ browserWSEndpoint })和chromium.connectOverCDP()都可以连接到它,并获取真实的 Chromium、干净的每会话指纹以及在 195 个国家的住宅出口。 - 连接只需编写一次,处处重复使用。 一个构建端点的单一助手使所有脚本 — Puppeteer 或 Playwright — 指向同一个管理会话。
- 实时验证: Puppeteer 和 Playwright 的连接都将
navigator.webdriver读取为false,并返回了目标页面的真实标题,而 Puppeteer 运行报告了一个美国住宅出口 IP。 - 免费开始。 新的 Scrapeless 账户包括免费的 Scraping Browser 运行时 — 访问 app.scrapeless.com 注册。
介绍:浏览器是信号,而不是脚本
Node.js 爬虫栈通常从本地开始:安装 Puppeteer 或 Playwright,启动 Chromium,驱动页面。它能工作直到目标开始评估浏览器。然后,无论你选择哪个库,都会出现相同的三种信号 — 脚本通过 navigator.webdriver 属性 宣布自动化,无头构建使用默认字体和画布行为,以及流量从已经知道的 IP 声誉服务中退出。
这些是浏览器级别和网络级别的问题,而不是逻辑问题。Puppeteer 和 Playwright 都已经知道如何附加到没有启动的浏览器 — 通过 Chrome DevTools 协议 — Scrapeless Scraping Browser 正是如此:一个通过一个 WebSocket URL 到达的 CDP 端点。将任一库指向它,指纹、行为和出口 IP 会在服务器端变化,而你的 Node.js 代码保持不变。
你可以用它做什么
- 保持你的库 — Puppeteer 和 Playwright 都连接到同一端点;无需重写。
- 对抗反爬虫保护的网站进行操作 — 挑战在渲染时清除,因此导航到达内容。
- 本地化会话 — 一个
proxyCountry值选择住宅出口区域。 - 发送一致的指纹 — 一个
fingerprint对象保持用户代理、平台、屏幕和时区的一致性。 - 保持状态 — 一个
profileId在运行之间传递 cookies 和本地存储。 - 不受笔记本电脑限制扩展 — 会话在云中运行,因此批处理不受本地 Chromium 限制。
为什么选择 Scrapeless Scraping Browser
Scrapeless Scraping Browser 是一款可定制的、反检测的云浏览器,专为网页爬虫和 AI 代理设计。针对 Node.js 栈,它带来了:
- 真正自开发的 Chromium,能够准确运行页面 JavaScript,就像 Chrome 一样,因此 SPA 和挑战可以解决。
- 一致的每会话指纹 — 无
navigator.webdriver信号,无无头默认泄漏。 - 在 195 个国家的住宅出口,每个会话可以通过一个
proxyCountry值选择。 - 为两个库提供一个 CDP 接口 — Puppeteer 和 Playwright 连接到同一个 WebSocket 端点。
- 通过
profileId保持会话持久性,因此经过身份验证的流程保持其状态。
在免费计划中获取你的 API 密钥,访问 app.scrapeless.com。
先决条件
- Node.js 18 或更高版本
puppeteer-core和/或playwright-core(两者都跳过本地浏览器下载 — 你连接到远程浏览器)- 一个 Scrapeless 账户和 API 密钥 — 访问 app.scrapeless.com 注册
完整的连接细节请查阅 Scraping Browser 文档。
安装
安装你的项目已经使用的任何库 — 或同时安装两个。
bash
npm install puppeteer-core playwright-core
export SCRAPELESS_API_KEY=your_api_token_here # 免费密钥请访问 https://app.scrapeless.com
连接只需编写一次
端点对于这两个库是相同的,因此只需在一个地方构建它。每个选项 — proxyCountry、fingerprint、profileId — 都是查询参数。
javascript
// scrapeless.js — 整个项目的端点构建器
import { URLSearchParams } from "node:url";
export function scrapelessEndpoint(extra = {}) {
const params = new URLSearchParams({
token: process.env.SCRAPELESS_API_KEY,
sessionTTL: "180", // 秒
proxyCountry: "US",
...extra,
});
return `wss://browser.scrapeless.com/api/v2/browser?${params}`;
}
路径 A — Puppeteer
Puppeteer 使用 puppeteer.connect() 进行连接。W3C WebDriver 规范 要求符合标准的自动化暴露 webdriver 标志;云浏览器不携带它。
javascript
import puppeteer from "puppeteer-core";
import { URLSearchParams } from "node:url";
const params = new URLSearchParams({
token: process.env.SCRAPELESS_API_KEY,
sessionTTL: "180",
proxyCountry: "US",
});
const endpoint = `wss://browser.scrapeless.com/api/v2/browser?${params}`;
const browser = await puppeteer.connect({ browserWSEndpoint: endpoint });
const page = await browser.newPage();
await page.goto("https://www.scrapeless.com/en", { waitUntil: "domcontentloaded", timeout: 60000 });
console.log("puppeteer title:", await page.title());
console.log("puppeteer navigator.webdriver:", await page.evaluate(() => navigator.webdriver));
await browser.close();
一次实时运行输出 puppeteer title: Effortless Web Scraping Toolkit - Scrapeless 和 puppeteer navigator.webdriver: false,在美国住宅出口 IP 上。
在免费计划中获取您的 API 密钥: app.scrapeless.com
路径 B — Playwright
Playwright 通过 chromium.connectOverCDP() 连接到相同的端点。以下代码是标准的 Playwright。
javascript
import { chromium } from "playwright-core";
import { URLSearchParams } from "node:url";
const params = new URLSearchParams({
token: process.env.SCRAPELESS_API_KEY,
sessionTTL: "180",
proxyCountry: "US",
});
const endpoint = `wss://browser.scrapeless.com/api/v2/browser?${params}`;
const browser = await chromium.connectOverCDP(endpoint);
const page = await browser.newPage();
await page.goto("https://www.scrapeless.com/en", { waitUntil: "domcontentloaded", timeout: 60000 });
console.log("playwright title:", await page.title());
console.log("playwright navigator.webdriver:", await page.evaluate(() => navigator.webdriver));
await browser.close();
一次实时运行输出 playwright title: Effortless Web Scraping Toolkit - Scrapeless 和 playwright navigator.webdriver: false。
在它们之间选择
端点是相同的,因此根据各自的优点选择库,而不是根据哪个能够避免检测 — 云浏览器会为两者处理这个问题:
- 已经在使用 Puppeteer? 将
puppeteer.launch()更改为puppeteer.connect({ browserWSEndpoint })。其他地方保持不变。 - 已经在使用 Playwright? 将
chromium.launch()更改为chromium.connectOverCDP()。定位器和自动等待保持不变。 - 刚开始? Playwright 的定位器和自动等待对于复杂流程非常方便;而 Puppeteer 在您主要浏览和读取的情况下更精简。两者都连接到相同的会话。
本地 Node.js 浏览器的局限
在您自己的计算机上运行 Chromium 对于打开的页面是可以的。问题出现在目标网站对浏览器进行评分的地方:停留在数据中心 IP 上的挑战插页、对无头默认设置进行指纹识别的页面,或者希望跨访问拥有稳定身份的登录墙。这些都是指纹、行为和 IP 问题 — 云浏览器在服务器端处理这三者 — 它们对 Puppeteer 和 Playwright 的影响是一样的。连接到 Scrapeless 将这些情况交给一个管理的会话,同时您的 Node.js 代码保持不变。
您将获得的内容
这两条路径为各自的库返回一个正常的浏览器对象 — Puppeteer 页面,Playwright 定位器 — 并且表现得像任何本地会话。一些诚实的观察:
navigator.webdriver在两者上都为false,因此网站运行的第一个检查就像一个真实的 Chrome。sessionTTL在这里以秒为单位 — 设置它以覆盖整个流程;会话在超时后关闭。- 出口 IP 与
proxyCountry相匹配 — 地理限制页面将根据本地访客的视角显示。 - 为顽固页面预热会话 — 首先加载该网站的主页,然后再加载受保护页面,因此行为面看起来像正常访问。
结论:一个端点,任一库
在 Node.js 中,检测表面是浏览器,因此修复的办法是移动浏览器,而不是重写抓取器。构建端点一次,然后使用 puppeteer.connect() 或 chromium.connectOverCDP() 连接到它,保留其余代码。将 proxyCountry 固定为住宅区域,传递一致的 fingerprint,并在认证流程中重用 profileId。要使用 Python 从而运行相同的云浏览器,请参阅 Scrapling 生产抓取器指南,并比较 Scrapeless 定价页面 上的计划。
准备构建您的 Node.js 抓取管道?
加入我们的社区,索取免费计划,并与构建 Node.js 抓取管道的开发者联系:Discord · Telegram。
在 app.scrapeless.com 注册以免费使用抓取浏览器运行时,并将 Puppeteer 或 Playwright 指向您的目标无法指纹识别的云浏览器。
常见问题
问:我必须在 Puppeteer 和 Playwright 之间选择吗?
不。两者都连接到同一 Scrapeless 端点 — puppeteer.connect({ browserWSEndpoint }) 或 chromium.connectOverCDP()。使用您项目中已经运行的任何一个,或者两个都用。
问:我需要更改我的抓取逻辑吗?
不。您只需更改获取浏览器的方式;导航、选择器/定位器和评估保持不变。
问:为什么是 -core 软件包?
puppeteer-core 和 playwright-core 跳过捆绑的浏览器下载,因为您连接到云浏览器,而不是启动本地浏览器。
问:我需要代理吗?
不。住宅出站是内置的 — 将 proxyCountry 设置为一个区域或 ANY。
问:使用 Node.js 进行网络抓取合法吗?
访问公开可用的数据通常是允许的,但规则因辖区和网站而异。查看目标的服务条款,尊重爬虫指令,并就任何敏感内容咨询律师。
在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。



