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. 浏览器有记忆功能。如果你已经启用了某个插件,那么之后再打开的时候插件就已经是启用状态了。
posted @ 2020-01-21 21:20  Mr..D  阅读(1600)  评论(0编辑  收藏  举报