Drissionpage迁移记录

1.drissionpage

drissionpage是2023年新开发的一款自动化框架。
它的特点是可以抓取到shadow-root.
通过这个可以越过cloudflare以及recaptcha v2(只能使用播放音频的方式去选择越过).
5s盾越过方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
if 'Just a moment' in tab.title or '请稍候' in tab.title:
                    if tab.ele('x://div[@id="rvwE0"]', timeout=10):
                        # 这里是有可能会出现的button。
                        if tab.ele('x://div[@id="rvwE0"]/div/input', timeout=0.1):
                            tab.ele('x://div[@id="rvwE0"]/div/input').click()
                        iframe = tab.ele('x://div[@id="rvwE0"]/div/div').sr('x://iframe', timeout=10)
                        if iframe:
                            body = iframe.ele('x://body', timeout=10)
                            if body:
                                checkbox = body.sr('x://input[@type="checkbox"]', timeout=10)
                                if checkbox:
                                    print("检测到 Cloudflare 验证,尝试点击复选框")
                                    checkbox.click()
                                    print("已点击 Cloudflare 验证框")
                                    if tab.ele('x://div[@id="rvwE0"]/div/input', timeout=20):
                                        tab.ele('x://div[@id="rvwE0"]/div/input').click()

2.记录一个头疼的迁移问题

众所周知脚本的开发调试在win上基本上是没问题的。问题是在linux下可能就执行不了。
同一套代码不但是运行的问题以及环境差异的导致。 这里我一共出现两个问题。
1. 脚本无法在linux系统上安装chrome插件。
2. 同一个方法在windows和linux上有差异?

a.首先第一点安装chrome插件。

1.编写简易插件,不起作用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# 代理服务器信息(以 SOCKS5 代理为例)
proxyHost = "38.60.xx.xx"  # SOCKS5 代理地址
proxyPort = "10888"  # SOCKS5 代理端口


def create_proxy_extension(proxy_host, proxy_port, scheme='socks5', plugin_path=None):
    # 创建Chrome插件的manifest.json文件内容
    manifest_json = """
    {
        "version": "1.0.0",
        "manifest_version": 2,
        "name": "SOCKS5 Proxy",
        "permissions": [
            "proxy",
            "tabs",
            "unlimitedStorage",
            "storage",
            "<all_urls>",
            "webRequest",
            "webRequestBlocking"
        ],
        "background": {
            "scripts": ["background.js"]
        },
        "minimum_chrome_version":"22.0.0"
    }
    """

    # 创建Chrome插件的background.js文件内容
    background_js = string.Template(
        """
        var config = {
            mode: "fixed_servers",
            rules: {
                singleProxy: {
                    scheme: "${scheme}",
                    host: "${host}",
                    port: parseInt(${port})
                },
                bypassList: ["localhost"]
            }
        };

        chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

        function callbackFn(details) {
            return {};  // No credentials needed for SOCKS5 without authentication
        }

        chrome.webRequest.onAuthRequired.addListener(
            callbackFn,
            {urls: ["<all_urls>"]},
            ['blocking']
        );
        """
    ).substitute(
        host=proxy_host,
        port=proxy_port,
        scheme=scheme,
    )

    # 创建插件目录并写入manifest.json和background.js文件
    os.makedirs(plugin_path, exist_ok=True)
    with open(os.path.join(plugin_path, "manifest.json"), "w+") as f:
        f.write(manifest_json)
    with open(os.path.join(plugin_path, "background.js"), "w+") as f:
        f.write(background_js)

    return os.path.join(plugin_path)

proxy_auth_plugin_path = create_proxy_extension(
    plugin_path="/tmp/drissionpage",  # 插件保存路径
    proxy_host=proxyHost,
    proxy_port=proxyPort
)

co = ChromiumOptions().add_extension(path=proxy_auth_plugin_path)

尽管background_js编写最简单的输出代码都无法安装上。

2.通过API添加浏览器插件。 co.add_extension('/opt/proxy_switchyomega-2.5.20-an+fx')确保有这个文件夹 这里添加之后前往插件页面验证。

1
2
3
tab.get("chrome://extensions")
tab.wait(3)
print("Extensions page HTML: ", tab.html)

打印出的页面最终显示是空的.看extensions-manager标签。仍然不起作用。

1
2
3
4
<body>
  <extensions-manager></extensions-manager>
  <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
</body></html>

3.命令行添加插件 google-chrome --no-sandbox --headless --load-extension=/tmp/drissionpage还是不起作用。

最终无奈只能安装远程桌面

最终不知道什么原因,依旧无法安装插件,这里我最终安装了linux桌面环境来进行安装。

1
2
3
4
5
6
7
8
#安装XFCE桌面环境
sudo apt install -y xfce4 xfce4-goodies
#安装XRDP
sudo apt install -y xrdp
echo "startxfce4" > ~/.xsession
chmod +x ~/.xsession
sudo systemctl enable xrdp
sudo systemctl start xrdp

安装完成之后就可以在本地windows上打开远程桌面进行互联了。
1734012455397.png
账号密码可以用root的
连接后,可以更改服务区上的代码。
可以先将无头模式取消,这样在桌面上,可以看到chrome的运行情况,方便调试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
            # 设置浏览器选项
            co = ChromiumOptions()
            co.set_user_agent(user_agent=windows_user_agent)
            # co.set_argument("--headless=new")
            co.set_argument('--incognito')
            co.set_argument("--no-sandbox")
            co.set_local_port(9211)
            co.add_extension('/opt/proxy_switchyomega-2.5.20-an+fx')
            self.browser = Chromium(co)
            self.browser.set.auto_handle_alert()

然后手动进去settings-》Extensions-》

进入页面后,点击Developer mode-》点击Load unPacked 1734012588749.png
然后将GitHub上下载的SwitchyOmega目录打开。
1734012639124.png
解压的文件夹。然后应该打开就会和我一样。安装插件成功了(终于)。 这是切换ip的方法。
原理是通过插件进行自动化来更改代理,插件也算网页可以通过捕捉元素来进行操作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def switch_ip(self,tab,ip_port=None, proxy_type=None):
    global set_proxy
    if ip_port:
        # 设置proxy
        if proxy_type is None:
            proxy_type = 'HTTP'
        else:
            proxy_type = proxy_type.upper()
        ip, port = ip_port.split(":")
        tab.get("chrome-extension://padekgcemlokbadohgkifijomclgjgif/options.html#!/profile/proxy")
        tab.wait(3)
        print(tab.url)
        print(tab.html)
        tab.ele('x://select[@ng-model="proxyEditors[scheme].scheme"]').select(proxy_type)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].host"]').clear(by_js=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].host"]').input(ip, clear=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].port"]').clear(by_js=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].port"]').input(port, clear=True)
        tab.ele('x://a[@ng-click="applyOptions()"]').click()
        # 提示框
        txt = tab.handle_alert()
        print("提示框", txt)
        tab.handle_alert(accept=False)
        if not set_proxy:
            # 切换proxy
            tab.get("chrome-extension://padekgcemlokbadohgkifijomclgjgif/popup/index.html#")
            tab.wait(1)
            tab.ele('x://span[text()="proxy"]').click()
            set_proxy = True
    else:
        tab = self.browser.new_tab()
        tab.get("chrome-extension://padekgcemlokbadohgkifijomclgjgif/popup/index.html#")
        tab.ele('x://span[text()="[直接连接]"]').click()
    if len(self.browser.tab_ids) > 1:
        print("当前tab个数", len(self.browser.tab_ids))
        tab.close()

self.switch_ip(tab,f"38.60.xx.xx:10888", "socks5")

b.无键盘驱动问题

.input(ip, clear=True)
这里clear看文档,是通过按键去清空的,但是linux上好像没有键盘驱动,似乎无法在输入之前清空掉文本框。
这里需要使用js去清空。
.clear(by_js=True) 至少我在windows上
tab.ele(‘x://input[@ng-model=“proxyEditors[scheme].host”]’).input(ip, clear=True)
是可以清空的。但是linux上没有正确清空掉文本框,导致代理无法配置成功。
前面要加上tab.ele(‘x://input[@ng-model=“proxyEditors[scheme].host”]’).clear(by_js=True)

1
2
3
4
5
6
tab.ele('x://select[@ng-model="proxyEditors[scheme].scheme"]').select(proxy_type)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].host"]').clear(by_js=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].host"]').input(ip, clear=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].port"]').clear(by_js=True)
        tab.ele('x://input[@ng-model="proxyEditors[scheme].port"]').input(port, clear=True)
        tab.ele('x://a[@ng-click="applyOptions()"]').click()

1734013022329.png
最后改完之后确实可以跑了,似乎互联网上没有相关问题产生,绕了很多弯路。其实主要还是解决的是代理的问题。 因为cloudflare对机房ip似乎有风控,机房ip点击时,无法成功。最后就完成了无头模式使用drissionpage越过cf。

💬评论
0%