Pyppeteer踩坑记录

Pyppeteer踩坑记录

[toc]

pyperteer是puppeteer的Python实现,相比于selenium具有异步加载、速度快、具备有界面/无界面模式、伪装性更强不易被识别为机器人同时可以伪装手机平板等终端。 官方文档链接
本来chrome就问题多多,puppeteer也是各种坑,加上pyppeteer是前两者的python版本,也就是产生了只要前两个有一个有bug,那么pyppeteer就会原封不动的继承下来,本来这没什么,但是现在遇到的问题就是pyppeteer这个项目从18年9月份之后就没更新过了,前两者都在不断的更新迭代,而pyppeteer一直不更新,导致很多bug根本没人修复。

launch常用配置

3、当使用pyppeteer一段时间之后,在.dev_profile文件夹里会产生大量的文件

设置autoClose=True,让它自动关闭的同时清理缓存文件或者手动执行await browser.close()
以上方法在某些时候会删除文件失败,我的解决方法是在每次启动前清空这个文件夹,代码如下
    p = os.path.join(pyppeteer.__pyppeteer_home__, ".dev_profile")
    shutil.rmtree(p, ignore_errors=True)

4、pyppeteer打印大量日志的问题

配置启动参数:
    logLevel='ERROR'

5、程序运行自动下载chromium报错或者下载很慢

可以设置环境变量使用淘宝加速镜像
os.environ["PYPPETEER_DOWNLOAD_HOST"]="https://npm.taobao.org/mirrors"
或者设置参数executablePath指定已安装的chrome或者chromium路径

6、无法关闭(Chrome 正受到自动测试软件的控制)这个控制条

这个问题在旧版本的chrome中可以设置'--disable-infobars'启动参数解决,但是较新版的chrome已经去掉了这个功能,但可以设置参数ignoreDefaultArgs=['--enable-automation']来去掉,不过这有副作用。

7、page.click模拟点击网页跳转导致报错

可以通过以下方式调用click
await asyncio.gather(
    page.waitForNavigation(),
    page.click(selector),

8、page.goto超时之后偶尔失去响应

这是一个bug,Puppeteer最新版本中同样存在,解决方法是在捕获超时错误后执行以下代码
await page._client.send("Page.stopLoading")

9、网站超时不报错,进程假死

这类网站很奇怪,连用curl命令也不触发超时错误,查阅大量资料之后,想到一个解决方案,代码如下:
res = await asyncio.wait_for(page.goto(url, {
    'waitUntil': ['load','networkidle0'],
    "timeout": timeout
}), timeout / 1000 + 1)

10、屏蔽dialog弹窗,否则有弹窗的网站会导致进程会卡住

async def close_dialog(dialog):
    await dialog.dismiss()
page.on("dialog", lambda x: asyncio.ensure_future(close_dialog(x)))

11、在docker容器中直接启动chrome报错

配置启动参数:
    args=['--no-sandbox']

12、使用新版本chrome时经常卡住

配置启动参数:
    args=['--disable-features=TranslateUI']

13、存在反调试的网站会导致浏览器直接卡死

一般情况过反调试
await page.evaluateOnNewDocument("()=>{Object.defineProperties(navigator,{webdriver:{get:()=>false}});")
过sojsonv6反调试
await page.evaluateOnNewDocument('()=>{Object.defineProperties(navigator,{webdriver:{get:()=>false}});var func=function(){};window["console"]["log"]=func;window["console"]["warn"]=func;window["console"]["debug"]=func;window["console"]["info"]=func;window["console"]["error"]=func;window["console"]["exception"]=func;window["console"]["trace"]=func;}')

14、部分网站会自动打开一个新的页面,数量多了之后会导致浏览器崩溃

每次访问网页之后都用await browser.pages()获取所有page,检测一下数量是否正常,如果异常可以遍历关闭page,也可以关闭浏览器,然后重启一个chrome实例。

15、长时间运行可能遇到有些网站在获取标题时超时,导致假死

捕获超时错误时第一件事就先发送停止命令await page._client.send("Page.stopLoading"),这个时候有些网站可能还是没停止加载,不过不会导致假死,然后不设延迟获取标题即可