PuppeteerSharp 在 C# 中已基本停止维护,5.x 是最后一个稳定版,6.x 起官方停更 NuGet 包且兼容性差;生产环境应改用 PlaywrightSharp 或 Microsoft.Playwright。

直接说结论:Puppeteer Sharp 在 C# 中已基本停止维护,PuppeteerSharp 5.x 是最后一个稳定大版本,6.x 起官方不再发布 NuGet 包,且与新版 Chromium 兼容性差;生产环境建议改用 PlaywrightSharp 或原生 Microsoft.Playwright(.NET 官方支持)。
为什么 PuppeteerSharp 启动就报 BrowserFetcher.DownloadAsync 失败或 TimeoutException
这是最常见现象——不是代码写错,而是默认下载逻辑失效。新版 Chromium 二进制地址变更,BrowserFetcher 内置的 URL 列表早已过期,且 GitHub Releases 页面结构也变了。
- 手动指定 Chromium 下载源无效:
new BrowserFetcher(new BrowserFetcherOptions { Path = "..." })不会自动修复 URL 解析逻辑 - 跳过下载、改用本地 Chrome/Edge 更可靠:
LaunchOptions.ExecutablePath指向chrome.exe或msedge.exe(需确保版本 ≥110) - 若坚持用内置下载,必须降级到
PuppeteerSharp5.1.0 +Chromium r967894(对应 Chrome 100),并设置BrowserFetcherOptions.Platform为Win64/Linux/MacOS
如何正确启动浏览器并避免 TargetClosedException 和空页面
多数“页面没加载”“元素找不到”问题源于生命周期管理混乱。PuppeteerSharp 的 Page 对象不是线程安全的,且默认启用 Headless = true(无界面),但某些网站会检测并拦截 headless 浏览器。
- 显式关闭
Headless调试:new LaunchOptions { Headless = false, Devtools = true },方便观察是否被反爬拦截 - 禁用自动化特征(绕过基础检测):
Args加入--disable-blink-features=AutomationControlled和--disable-extensions -
Page必须通过browser.NewPageAsync()创建,不能复用;关闭时调用page.CloseAsync(),而非只 Dispose - 等待页面加载完成别只靠
WaitForNavigationAsync(),优先用WaitForSelectorAsync("body")或自定义条件
用 Page.EvaluateExpressionAsync 执行 JS 时返回 null 或类型错误
EvaluateExpressionAsync 只能返回可序列化的值(string/number/bool/array/object),无法返回 DOM 节点、函数或 undefined。常见误用是试图直接取 document.querySelector(...) 结果。
- 要获取元素文本内容:用
EvaluateExpressionAsync<string>("document.querySelector('h1').innerText")</string> - 要判断元素是否存在:用
EvaluateFunctionAsync<bool>("(selector) => !!document.querySelector(selector)", "button.submit")</bool> - 要获取多个属性:封装成对象返回,例如
EvaluateFunctionAsync<jobject>("(el) => ({ text: el.textContent, href: el.href })", "a:first-child")</jobject> - 执行无返回 JS(如点击):用
Page.EvaluateFunctionAsync("el => el.click()", selector),别用EvaluateExpressionAsync
真正麻烦的不是怎么写,而是 Chromium 版本、.NET 运行时、系统权限三者耦合太紧。比如在 Linux Docker 容器里跑,缺 libnss3 或 libatk-bridge2.0-0 就会静默失败;Windows 上以服务方式运行则因会话隔离拿不到 GUI 子进程。这些细节不踩一遍很难信。


















