Browser Automation: Puppeteer Pitfalls

20th August 2020 at 2:19pm

Puppeteer 的一些坑,需要注意避免。我用的是 Python 版的 pyppeteer,但是有些坑是对 Google 官方的 Node.js 版也适用。

.click()

无论是 page.click() / 或 element.click() 函数,都会触发对某个 HTML 元素的点击事件。但是有几点需要注意:

  • Element 需要是在页面 viewport 中可见的。pyppeteer 的函数会自动 _scrollIntoViewIfNeeded()
  • .click() 操作只是模拟了用户 用鼠标 在页面中某个位置点下按钮,并不是操作底层的 DOM API 去 fire 一个 click 事件,因此如果你要点的元素被其他内容 cover 了,比如被底部的 footer 挡到了,那么对元素的 .click() 操作会 click 到 footer 上,而点不到元素本身

Windows 上的特定问题

Windows 上使用时经常会出现 "Unable to remove Temporary User Data":

  • 有人 提到 可能是因为使用了代理
  • 有人 提到 应该先 page.close()browser.close()(我觉得没道理)

我没调研过具体原因。非常建议 不要在 Windows 去调试 puppeteer。

同时发现过 Celery 搭配 pyppeteer 时,Windows 上总是表现得不正常。使用 prefork 模型时,收到截图任务后不工作;使用 solo 模型时,收到任务会工作,但是又无法正常退出。

Websockets 库 7.0 API 变动引起的问题

症状是 pyppeteer 启动 browser 20 秒后,调用任何 API 都必现 pyppeteer.errors.NetworkError: Protocol error Page.enable: Target closed.调研 了下,是 websockets 库发布了 7.0,API 变动引起的问题。

pyppeteer 0.0.25 中,对于安装依赖的限定很 松散,全部是 * 匹配,导致 websockets 库发布了 7.0 后自动被使用上了。等待作者发布新版本修复前,需要手动在你的依赖管理工具(poetry, pipenv)中指定使用 websockets=^6.0.0