跳到正文

事件与调试

哪些页面事件会到达你的自动化客户端,如何仍然捕获控制台输出,以及如何检查页面实际由哪个渲染器绘制。

控制台与页面错误事件

引擎不会把控制台事件或页面错误事件转发给自动化客户端,因此 page.on("console") 和 page.on("pageerror") 收不到任何内容。这是有意为之——检测自动化是否存在的探针,测的恰恰就是这种转发。页面内的 window.onerror 和 unhandledrejection 处理函数会正常触发,所以要捕获控制台输出,请在页面内收集,再用 page.evaluate() 读回来。Python 和 Node SDK 会在启动时就此打印一次提示。

有两个驱动调用依赖这些事件。Playwright 的 page.setContent() 会等待一个控制台事件,因此会超时(Puppeteer 的可以正常使用):请以 data: URL 的形式打开 HTML,或者用 page.evaluate() 把它写入页面。在 Playwright 和 Puppeteer 中,exposeFunction() 和 exposeBinding() 在调用时已打开的页面中生效,该页面一旦发生导航就会失效:请在最后一次导航之后再调用它们,或者通过 page.evaluate() 把结果传回。

from urllib.parse import quote

# Instead of page.set_content(html):
# short HTML: a data: URL (the page gets no origin of its own, so no cookies or storage)
page.goto("data:text/html," + quote(html))
# any HTML: write it into a page you have navigated to; it keeps that page's origin
page.evaluate("html => { document.open(); document.write(html); document.close(); }", html)

渲染后端一致性检查(checkRenderCoherence)

身份画像可以声称自己用的是某块 GPU,但如果页面实际上是由软件光栅化器绘制的(SwiftShader / llvmpipe——在没有 GPU 的无头环境中很常见),严格的检测器就能分辨出来。对一个已打开的页面执行探测:它会读取页面实际看到的(未屏蔽的)WebGL vendor/renderer,标记出软件光栅化器回退(这是致命的无头破绽——请启用 canvas bridge,或在真实 GPU 上以有头模式运行)或不一致的 vendor/renderer 组合,并返回结构化的判定结果。传入声称的 GPU,还可以同时断言实际渲染的 GPU 系列。同步、异步和 Node 版本均可用。

from clearcote import launch, check_render_coherence

browser = launch(fingerprint="seed-123")
page = browser.new_page(); page.goto("about:blank")

verdict = check_render_coherence(page)   # {'renderer', 'software_suspected', 'coherent', 'warnings'}
if not verdict["coherent"]:
    print(verdict["warnings"])            # e.g. software rasterizer / incoherent GPU family
browser.close()