美文网首页python爬虫
Pyppeteer踩坑记录

Pyppeteer踩坑记录

作者: Jackect | 来源:发表于2021-09-07 16:54 被阅读0次

    Pyppeteer踩坑记录

    [toc]

    简介

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

    launch常用配置

    语法 描述
    ignoreHTTPSErrors bool 是否忽略 HTTPS 错误
    headless bool 是否在无头模式下运行浏览器
    executablePath str 运行 Chromium 或 Chrome 可执行文件的路径,而不是默认捆绑的 Chromium
    slowMo float 按指定的毫秒数减慢 pyppeteer 操作
    args list 传递给浏览器进程的附加参数
    dumpio bool 是否管道浏览器进程 stdout 和 stderr 进入 process.stdout 和 process.stderr。默认为 False
    userDataDir str 用户数据目录的路径
    env dict 指定浏览器可见的环境变量。默认与 python 进程相同
    devtools bool 是否为每个选项卡自动打开 DevTools 面板。如果是此选项 True,headless 则将设置该选项 False
    logLevel str 用于打印日志的日志级别。默认值与根记录器相同
    loop asyncio.AbstractEventLoop 事件循环(实验)

    各种坑

    1、浏览器窗口很大,内容显示很小

    配置启动参数:
        args=['--window-size=1280,720'],
        defaultViewport={"width": 1280,"height": 720}
    

    2、chromium浏览器多开页面卡死问题

    配置启动参数:
        dumpio=True
    

    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"),这个时候有些网站可能还是没停止加载,不过不会导致假死,然后不设延迟获取标题即可
    

    参考链接

    相关文章

      网友评论

        本文标题:Pyppeteer踩坑记录

        本文链接:https://www.haomeiwen.com/subject/wrfpwltx.html