zoukankan      html  css  js  c++  java
  • pyppeteer控制Chromium在隐身模式下启用插件

    基础

    启用隐身模式

    from pyppeteer import launch
    
    
    async def start_browser():
        browser = await launch(**{"headless": False})
        browser_context = await browser.createIncognitoBrowserContext()
        page = await browser_context.newPage()
    
        await page.goto("http://www.baidu.com")
        await browser.close()
        return
    
    

    非隐身模式启用插件

    from pyppeteer import launch
    
    
    async def start_browser():
        chrome_extension_path = "插件所在目录"
        args = [
            "--load-extension={}".format(chrome_extension_path),
            "--disable-extensions-except={}".format(chrome_extension_path),
        ]
    
        browser = await launch(**{"headless": False, "args": args})
        page = await browser.newPage()
    
        await page.goto("http://www.baidu.com")
        await browser.close()
        return
    
    

    正文

    如果是非隐身模式启用插件的话,上面的代码就可以了。但很蛋疼的是,有个场景必须得在隐身模式下运行,还需要插件。如果是人为操作的话,启用步骤如下:

    1. 打开插件管理页面 chrome://extensions/
    2. 找到需要启动的插件,点击详细信息,进入插件详情。
    3. 在详情中寻找: 在无痕模式下启用的选项并勾选

    然后就可以在隐身模式下使用了。

    BUT,我的目的是自动隐身模式下启用插件。Google大法开始启用。。。
    一个小时后。。。WTF,反正我是没找到正常的实现方式,貌似pyppeteer不支持,不知道是不是有什么隐藏的chrome参数能用的,但找起来太费劲了,放弃。

    其实在Google过程中也找到了一个办法,只是不那么优雅而已。其实很简单,就是把上面人为操作的步骤自动化一下。

    代码并不是很复杂,不过在实现过程中还是学到了点新东西的。

    代码如下:

    import asyncio
    from pyppeteer.browser import Browser
    
    
    async def enable_extension_for_incognito(browser: Browser, extension_name: str) -> bool:
        """
            在隐身模式下启用指定插件
        Args:
            extension_name: 插件名称
    
        Returns:
    
        """
        # 新开非隐身窗口并打开扩展程序页面
        page = await browser.newPage()
        await page.goto("chrome://extensions/")
        # 执行js代码获取指定的扩展id
        get_eid_js = (
            """() => {
            var extension_id;
            document.querySelector("extensions-manager").shadowRoot
            .querySelector("extensions-item-list").shadowRoot
            .querySelectorAll("extensions-item").forEach(function (e) {
                var e_name = e.shadowRoot.querySelector("#name").textContent.trim();
                if (e_name == "%s") {
                    extension_id = e.getAttribute("id")
                }
            })
            return extension_id
        }"""
            % extension_name
        )
        extension_id = await page.evaluate(get_eid_js)
        await asyncio.sleep(1)
        # 进入扩展详情页面
        await page.goto("chrome://extensions/?id={}".format(extension_id))
        # 判断插件是否启用
        get_extension_status_js = """
                        () => {
                        return document.querySelector("extensions-manager").shadowRoot
                        .querySelector("extensions-detail-view").shadowRoot
                        .querySelector("extensions-toggle-row#allow-incognito").shadowRoot
                        .querySelector("#crToggle").getAttribute("aria-pressed")
                        }
                        """
        r = await page.evaluate(get_extension_status_js)
        if r != "true":
            # 点击在无痕模式下启用
            click_enable_js = """
            () => {document.querySelector("extensions-manager").shadowRoot
            .querySelector("extensions-detail-view").shadowRoot
            .querySelector("extensions-toggle-row#allow-incognito").shadowRoot
            .querySelector("#crToggle").shadowRoot
            .querySelector("button").click()}
            """
            await page.evaluate(click_enable_js)
            await asyncio.sleep(1)
        # 确认是否启用成功
        r = await page.evaluate(get_extension_status_js)
        assert r == "true"
        await page.close()
        return True
    

    需要注意的地方有两个:

    1. shadowRoot这个东西第一次遇到。。。
    2. 浏览器有记忆功能。如果你已经启用了某个插件,那么之后再打开的时候插件就已经是启用状态了。
  • 相关阅读:
    C#学习笔记:多态与隐藏,覆盖
    HTML与XML数据的结合小总结
    基于角色(RoleBased)的表单验证
    去除C++String的首尾空格
    Bash Shell中命令行选项/参数处理
    linux shell 执行多个命令的几种方法
    gdb 多线程调试
    linux 时间戳及时间差计算
    oracle sql日期比较
    在Fedora 14上安装Sun JDK 6
  • 原文地址:https://www.cnblogs.com/dyfblog/p/12225796.html
Copyright © 2011-2022 走看看