• pyppeteer使用笔记


    pyppeteer -- python版本的puppeteer,一个强大的chronium headless浏览器API

    最近搞天猫用了一波儿,记录一下。

     

    先上文档: https://miyakogi.github.io/pyppeteer/

     

    举个最简单的例子入门一下:

    比如打开百度,然后截图

    # coding:utf8
    import asyncio
    from pyppeteer import launch
    
    
    async def main():
        launch_kwargs = {
            # 默认无头模式
            # "headless": False,
        }
        # 启动浏览器
        browser = await launch(launch_kwargs)
        # 打开标签页
        page = await browser.newPage()
        # 输入网址并打开
        await page.goto("http://www.baidu.com")
        # 获取页面元素
        title = await page.title()
        print(title)
        # 关闭浏览器
        await browser.close()
        return
    
    
    asyncio.get_event_loop().run_until_complete(main())
    View Code

      下面说一些小技巧:

    1、启动参数

    launch_kwargs = {
            # 控制是否为无头模式
            "headless": False,
            # chrome启动命令行参数
            "args": [
                # 浏览器代理 配合某些中间人代理使用
                "--proxy-server=http://127.0.0.1:8008",
                # 最大化窗口
                "--start-maximized",
                # 取消沙盒模式 沙盒模式下权限太小
                "--no-sandbox",
                # 不显示信息栏  比如 chrome正在受到自动测试软件的控制 ...
                "--disable-infobars",
                # log等级设置 在某些不是那么完整的系统里 如果使用默认的日志等级 可能会出现一大堆的warning信息
                "--log-level=3",
                # 设置UA
                "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
            ],
            # 用户数据保存目录 这个最好也自己指定一个目录
            # 如果不指定的话,chrome会自动新建一个临时目录使用,在浏览器退出的时候会自动删除临时目录
            # 在删除的时候可能会删除失败(不知道为什么会出现权限问题,我用的windows) 导致浏览器退出失败
            # 然后chrome进程就会一直没有退出 CPU就会狂飙到99%
            "userDataDir": "",
        }
    View Code

         注意:同一个用户目录(userDataDir)不能被两个chrome进程使用,如果你要多开,记得分别指定用户目录。否则会报编码错误。

    2、设置viewport

        自动获取当前屏幕大小并设置viewport      

    # coding:utf8
    import asyncio
    from pyppeteer import launch
    
    
    def screen_size():
        """使用tkinter获取屏幕大小"""
        import tkinter
        tk = tkinter.Tk()
        width = tk.winfo_screenwidth()
        height = tk.winfo_screenheight()
        tk.quit()
        return width, height
    
    
    async def main():
        launch_kwargs = {
            "headless": False
        }
        # 启动浏览器
        browser = await launch(launch_kwargs)
        # 打开标签页
        page = await browser.newPage()
        # 默认 800 * 600 一般是不够的
        print(page.viewport)
        #
        width, height = screen_size()
        # 设置网页可视区域大小
        await page.setViewport({
            "width": width,
            "height": height
        })
        await browser.close()
        return
    
    
    asyncio.get_event_loop().run_until_complete(main())
    View Code

    3、导出或加载cookie

        # 取出cookie
        cookies = await page.cookies()
        # 这里可以做些什么 :)
        pass
        # 然后导入cookie
        await page.setCookie(*cookies)
    View Code

    4、选择器

        让人极度舒适的一个特性:

          使用 page.querySelector如果没有找到指定的对象,则返回None,而不是抛出异常。不管规范不规范,反正比selenium爽多了。

    5、hook

      在页面开始加载前注入js代码,例如修改掉webdriver属性,让天猫检测不到

    # coding:utf8
    import asyncio
    from pyppeteer import launch
    
    
    async def main():
        launch_kwargs = {
            "headless": False
        }
        # 启动浏览器
        browser = await launch(launch_kwargs)
        # 打开标签页
        page = await browser.newPage()
        page.evaluateOnNewDocument("""
                var _navigator = {};
                for (name in window.navigator) {
                    if (name != "webdriver") {
                        _navigator[name] = window.navigator[name]
                    }
                }
                Object.defineProperty(window, 'navigator', {
                    get: ()=> _navigator,
                })
            """)
        #
        page.goto("http://www.tmall.com")
    
        await browser.close()
        return
    
    
    asyncio.get_event_loop().run_until_complete(main())
    View Code

    6、关于各种事件的isTrusted

      这个js事件属性,用js是无法伪造的,但是用pyppeteer发生的各种操作所触发的事件,是完全真实的,这个归功于CDP吧。

    7、卡死

      如果在操作过程中不小心点击了某个a标签,导致浏览器新打开了一个标签页,而你的代码还在傻乎乎的使用之前的page对象做操作的时候,整个进程就卡住了

      没有超时、没有异常、就是完全的不知道在干啥

      当你把新开的标签页手动关闭后,一切就恢复原样。

      tips:

        避免这种情况的发生,其实也很简单,就是在每个可能误操作点击导致新开标签页的行为后面都强制关闭一下其他标签页:

        比如:

        # 关闭其他标签页
        for _page in await browser.pages():
            if _page != page:
                _page.close()
    View Code

      

  • 相关阅读:
    DirectoryEntry配置IIS7出现ADSI Error:未知错误(0x80005000) [转]
    自定义Microsoft Visual Studio 代码模板,增加公司和个人信息
    RabbitMQ消息队列名词解释[转]
    RabbitMQ消息队列的小伙伴: ProtoBuf(Google Protocol Buffer) [转]
    RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC) [转]
    RabbitMQ消息队列(六):使用主题进行消息分发[转]
    RabbitMQ消息队列(五):Routing 消息路由 2[原]
    RabbitMQ消息队列(五):Routing 消息路由[转]
    RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)[转]
    RabbitMQ消息队列(三):任务分发机制[转]
  • 原文地址:https://www.cnblogs.com/dyfblog/p/10170959.html
Copyright © 2020-2023  润新知