dp-cli 0.4.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dp_cli-0.4.0 → dp_cli-0.6.0}/PKG-INFO +14 -13
- {dp_cli-0.4.0 → dp_cli-0.6.0}/README.md +13 -12
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/bridge_manager.py +5 -4
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/__init__.py +2 -2
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/_utils.py +14 -3
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/browser.py +34 -14
- dp_cli-0.6.0/dp_cli/commands/keyboard.py +405 -0
- dp_cli-0.6.0/dp_cli/commands/record.py +204 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/snapshot_cmd.py +1 -1
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/tab.py +6 -0
- dp_cli-0.6.0/dp_cli/recorder.py +799 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/session.py +60 -5
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/PKG-INFO +14 -13
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/SOURCES.txt +2 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/pyproject.toml +1 -1
- dp_cli-0.4.0/dp_cli/commands/keyboard.py +0 -225
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/__init__.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/bridge.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/element.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/misc.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/network.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/page.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/storage.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/__init__.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/playwright.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/pw_js.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/main.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/output.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/__init__.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/a11y.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable_js.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/extract.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/js_scripts.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/utils.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/stealth.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/dependency_links.txt +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/entry_points.txt +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/requires.txt +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/top_level.txt +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/setup.cfg +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_bridge_integration.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_bridge_manager.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_clickable.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_pw_locator.py +0 -0
- {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_resolve_locator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dp-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A powerful CLI for DrissionPage — browser automation, structured data extraction, network listening and more.
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
Project-URL: Homepage, https://github.com/mofanx/dp-cli
|
|
@@ -26,7 +26,7 @@ A powerful CLI for [DrissionPage](https://github.com/g1879/DrissionPage) — bro
|
|
|
26
26
|
## Features
|
|
27
27
|
|
|
28
28
|
- **Anti-detection by default** — not based on webdriver, `navigator.webdriver` is `false`
|
|
29
|
-
- **Reuse your own browser** — `--auto-connect` (Chrome 144+, no CLI flag needed) or `--port`
|
|
29
|
+
- **Reuse your own browser** — `--auto-connect` (Chrome/Edge 144+, no CLI flag needed) or `--port`
|
|
30
30
|
- **Hybrid snapshot** — a11y tree + Vimium-style clickable detection, catches icon-only buttons
|
|
31
31
|
and custom menu items the a11y tree misses; every element gets an `[N]` ref with
|
|
32
32
|
confidence markers (`⚡` medium, `?` low)
|
|
@@ -64,25 +64,26 @@ dp open https://example.com --port 9222
|
|
|
64
64
|
dp snapshot
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
## Connect to a Normally-Launched Chrome (Chrome 144+)
|
|
67
|
+
## Connect to a Normally-Launched Chrome/Edge (Chrome/Edge 144+)
|
|
68
68
|
|
|
69
|
-
No `--remote-debugging-port` required. Chrome 144+ exposes opt-in remote debugging
|
|
70
|
-
via `chrome://inspect
|
|
69
|
+
No `--remote-debugging-port` required. Chrome/Edge 144+ exposes opt-in remote debugging
|
|
70
|
+
via `chrome://inspect` (Chrome) or `edge://inspect/#devices` (Edge):
|
|
71
71
|
|
|
72
|
-
1. Open your Chrome as usual (no special flags)
|
|
73
|
-
2. Visit `chrome://inspect/#remote-debugging`
|
|
72
|
+
1. Open your Chrome or Edge as usual (no special flags)
|
|
73
|
+
2. Visit `chrome://inspect/#remote-debugging` (Chrome) or `edge://inspect/#devices` (Edge)
|
|
74
74
|
3. Check **"Allow remote debugging for this browser instance"**
|
|
75
75
|
4. Run `dp open --auto-connect`
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
|
-
dp open --auto-connect #
|
|
79
|
-
dp open --auto-connect --channel
|
|
78
|
+
dp open --auto-connect # auto channel: sniffs Chrome stable → Edge stable
|
|
79
|
+
dp open --auto-connect --channel edge # force Edge stable
|
|
80
|
+
dp open --auto-connect --channel beta # Chrome beta
|
|
80
81
|
dp open --auto-connect --probe-dir ~/my-profile # custom user-data-dir
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
### How it works
|
|
84
85
|
|
|
85
|
-
Chrome 144+ in this mode exposes **only** a browser-level WebSocket and omits the HTTP
|
|
86
|
+
Chrome/Edge 144+ in this mode exposes **only** a browser-level WebSocket and omits the HTTP
|
|
86
87
|
REST API (`/json`, `/json/version`, ...) that DrissionPage / puppeteer / Playwright
|
|
87
88
|
depend on. `dp-cli` transparently handles this:
|
|
88
89
|
|
|
@@ -95,14 +96,14 @@ depend on. `dp-cli` transparently handles this:
|
|
|
95
96
|
4. Points DrissionPage at the bridge. Subsequent `dp` commands reuse the same bridge.
|
|
96
97
|
|
|
97
98
|
The bridge subprocess and its port are tracked in the session file; `dp close` stops
|
|
98
|
-
the bridge automatically and never quits your
|
|
99
|
+
the bridge automatically and never quits your browser (it's your browser, not dp's).
|
|
99
100
|
|
|
100
101
|
### Caveats
|
|
101
102
|
|
|
102
|
-
- Chrome always shows an **"Allow remote debugging"** dialog per new WebSocket client.
|
|
103
|
+
- Chrome/Edge always shows an **"Allow remote debugging"** dialog per new WebSocket client.
|
|
103
104
|
Since bridge maintains one WebSocket and dp commands share it, you confirm at most
|
|
104
105
|
once per `dp open --auto-connect`.
|
|
105
|
-
- Works with whatever profile Chrome is actually using — same cookies, logins, history.
|
|
106
|
+
- Works with whatever profile Chrome/Edge is actually using — same cookies, logins, history.
|
|
106
107
|
- Classic `--remote-debugging-port=9222` mode still works unchanged via `dp open --port 9222`.
|
|
107
108
|
|
|
108
109
|
## Hybrid Snapshot (a11y + Vimium-style)
|
|
@@ -5,7 +5,7 @@ A powerful CLI for [DrissionPage](https://github.com/g1879/DrissionPage) — bro
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Anti-detection by default** — not based on webdriver, `navigator.webdriver` is `false`
|
|
8
|
-
- **Reuse your own browser** — `--auto-connect` (Chrome 144+, no CLI flag needed) or `--port`
|
|
8
|
+
- **Reuse your own browser** — `--auto-connect` (Chrome/Edge 144+, no CLI flag needed) or `--port`
|
|
9
9
|
- **Hybrid snapshot** — a11y tree + Vimium-style clickable detection, catches icon-only buttons
|
|
10
10
|
and custom menu items the a11y tree misses; every element gets an `[N]` ref with
|
|
11
11
|
confidence markers (`⚡` medium, `?` low)
|
|
@@ -43,25 +43,26 @@ dp open https://example.com --port 9222
|
|
|
43
43
|
dp snapshot
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
## Connect to a Normally-Launched Chrome (Chrome 144+)
|
|
46
|
+
## Connect to a Normally-Launched Chrome/Edge (Chrome/Edge 144+)
|
|
47
47
|
|
|
48
|
-
No `--remote-debugging-port` required. Chrome 144+ exposes opt-in remote debugging
|
|
49
|
-
via `chrome://inspect
|
|
48
|
+
No `--remote-debugging-port` required. Chrome/Edge 144+ exposes opt-in remote debugging
|
|
49
|
+
via `chrome://inspect` (Chrome) or `edge://inspect/#devices` (Edge):
|
|
50
50
|
|
|
51
|
-
1. Open your Chrome as usual (no special flags)
|
|
52
|
-
2. Visit `chrome://inspect/#remote-debugging`
|
|
51
|
+
1. Open your Chrome or Edge as usual (no special flags)
|
|
52
|
+
2. Visit `chrome://inspect/#remote-debugging` (Chrome) or `edge://inspect/#devices` (Edge)
|
|
53
53
|
3. Check **"Allow remote debugging for this browser instance"**
|
|
54
54
|
4. Run `dp open --auto-connect`
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
dp open --auto-connect #
|
|
58
|
-
dp open --auto-connect --channel
|
|
57
|
+
dp open --auto-connect # auto channel: sniffs Chrome stable → Edge stable
|
|
58
|
+
dp open --auto-connect --channel edge # force Edge stable
|
|
59
|
+
dp open --auto-connect --channel beta # Chrome beta
|
|
59
60
|
dp open --auto-connect --probe-dir ~/my-profile # custom user-data-dir
|
|
60
61
|
```
|
|
61
62
|
|
|
62
63
|
### How it works
|
|
63
64
|
|
|
64
|
-
Chrome 144+ in this mode exposes **only** a browser-level WebSocket and omits the HTTP
|
|
65
|
+
Chrome/Edge 144+ in this mode exposes **only** a browser-level WebSocket and omits the HTTP
|
|
65
66
|
REST API (`/json`, `/json/version`, ...) that DrissionPage / puppeteer / Playwright
|
|
66
67
|
depend on. `dp-cli` transparently handles this:
|
|
67
68
|
|
|
@@ -74,14 +75,14 @@ depend on. `dp-cli` transparently handles this:
|
|
|
74
75
|
4. Points DrissionPage at the bridge. Subsequent `dp` commands reuse the same bridge.
|
|
75
76
|
|
|
76
77
|
The bridge subprocess and its port are tracked in the session file; `dp close` stops
|
|
77
|
-
the bridge automatically and never quits your
|
|
78
|
+
the bridge automatically and never quits your browser (it's your browser, not dp's).
|
|
78
79
|
|
|
79
80
|
### Caveats
|
|
80
81
|
|
|
81
|
-
- Chrome always shows an **"Allow remote debugging"** dialog per new WebSocket client.
|
|
82
|
+
- Chrome/Edge always shows an **"Allow remote debugging"** dialog per new WebSocket client.
|
|
82
83
|
Since bridge maintains one WebSocket and dp commands share it, you confirm at most
|
|
83
84
|
once per `dp open --auto-connect`.
|
|
84
|
-
- Works with whatever profile Chrome is actually using — same cookies, logins, history.
|
|
85
|
+
- Works with whatever profile Chrome/Edge is actually using — same cookies, logins, history.
|
|
85
86
|
- Classic `--remote-debugging-port=9222` mode still works unchanged via `dp open --port 9222`.
|
|
86
87
|
|
|
87
88
|
## Hybrid Snapshot (a11y + Vimium-style)
|
|
@@ -94,9 +94,10 @@ def start_bridge(user_data_dir: str | os.PathLike,
|
|
|
94
94
|
|
|
95
95
|
# 立即提示用户:bridge 正在连接;若 Chrome 弹出授权框请点击。
|
|
96
96
|
# 写 stderr 避免污染 stdout 的 JSON 输出。
|
|
97
|
-
print('[dp] 正在启动 bridge
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
print('[dp] 正在启动 bridge 并连接浏览器(Chrome/Edge)…',
|
|
98
|
+
file=sys.stderr, flush=True)
|
|
99
|
+
print('[dp] 💡 若浏览器弹出 "Allow remote debugging" 对话框,'
|
|
100
|
+
'请切到浏览器窗口点击 "Allow"(后续命令会自动复用连接)',
|
|
100
101
|
file=sys.stderr, flush=True)
|
|
101
102
|
|
|
102
103
|
# 异步读 stderr,方便 timeout 时回显给用户
|
|
@@ -143,7 +144,7 @@ def start_bridge(user_data_dir: str | os.PathLike,
|
|
|
143
144
|
proc.terminate()
|
|
144
145
|
raise RuntimeError(
|
|
145
146
|
f'bridge 启动超时 ({ready_timeout}s)。\n'
|
|
146
|
-
f'
|
|
147
|
+
f'若是首次连接:请把浏览器窗口(Chrome/Edge)切到前台,点击弹出的'
|
|
147
148
|
f' "Allow remote debugging for this browser instance" 对话框。\n'
|
|
148
149
|
f'当前 bridge stderr:\n{_collect_stderr()}'
|
|
149
150
|
)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# -*- coding:utf-8 -*-
|
|
2
2
|
from dp_cli.commands import (
|
|
3
3
|
browser, snapshot_cmd, element, keyboard,
|
|
4
|
-
page, tab, storage, network, misc,
|
|
4
|
+
page, tab, storage, network, record, misc,
|
|
5
5
|
)
|
|
6
6
|
|
|
7
|
-
_MODULES = [browser, snapshot_cmd, element, keyboard, page, tab, storage, network, misc]
|
|
7
|
+
_MODULES = [browser, snapshot_cmd, element, keyboard, page, tab, storage, network, record, misc]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def register_all(cli):
|
|
@@ -25,11 +25,12 @@ def session_option(f):
|
|
|
25
25
|
help='会话名称,默认 default', show_default=True)(f)
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def _get_page(session: str, raw: bool = False):
|
|
28
|
+
def _get_page(session: str, raw: bool = False, inject_recording: bool = True):
|
|
29
29
|
"""获取页面对象,失败则 error 退出。
|
|
30
30
|
|
|
31
31
|
:param raw: True 时始终返回 ChromiumPage(用于浏览器级操作如标签页管理)。
|
|
32
|
-
False 时返回绑定的标签页 ChromiumTab
|
|
32
|
+
False 时返回绑定的标签页 ChromiumTab(如有),否则返回当前激活标签页。
|
|
33
|
+
:param inject_recording: session 录制中时是否自动注入录制器。
|
|
33
34
|
"""
|
|
34
35
|
try:
|
|
35
36
|
page = get_browser(session)
|
|
@@ -53,7 +54,10 @@ def _get_page(session: str, raw: bool = False):
|
|
|
53
54
|
save_session(session, sess)
|
|
54
55
|
target = page
|
|
55
56
|
else:
|
|
56
|
-
|
|
57
|
+
try:
|
|
58
|
+
target = page.latest_tab or page
|
|
59
|
+
except Exception:
|
|
60
|
+
target = page
|
|
57
61
|
|
|
58
62
|
# 自动重新应用 stealth:CDP init_js 绑定到 CDP session,每个 dp 命令是独立
|
|
59
63
|
# Python 进程/独立 session,必须重新注册才能让下一次 navigation 生效。
|
|
@@ -71,6 +75,13 @@ def _get_page(session: str, raw: bool = False):
|
|
|
71
75
|
except Exception:
|
|
72
76
|
pass # 不能让 stealth 失败阻塞常规命令
|
|
73
77
|
|
|
78
|
+
if inject_recording and sess.get('recording'):
|
|
79
|
+
try:
|
|
80
|
+
from dp_cli.recorder import inject_recorder
|
|
81
|
+
inject_recorder(target)
|
|
82
|
+
except Exception:
|
|
83
|
+
pass
|
|
84
|
+
|
|
74
85
|
return target
|
|
75
86
|
|
|
76
87
|
|
|
@@ -7,7 +7,8 @@ import click
|
|
|
7
7
|
from dp_cli.session import (get_browser, close_browser, list_sessions,
|
|
8
8
|
delete_session, load_session, save_session,
|
|
9
9
|
discover_port_from_profile,
|
|
10
|
-
default_user_data_dir_for_channel
|
|
10
|
+
default_user_data_dir_for_channel,
|
|
11
|
+
sniff_auto_user_data_dir)
|
|
11
12
|
from dp_cli.output import ok, error, format_page_info
|
|
12
13
|
from dp_cli.commands._utils import session_option, _get_page, normalize_url
|
|
13
14
|
from dp_cli.stealth import apply_stealth, PRESETS, DEFAULT_UA
|
|
@@ -23,12 +24,15 @@ def register(cli):
|
|
|
23
24
|
@click.option('--profile', 'user_data_dir', default=None, help='用户数据目录')
|
|
24
25
|
@click.option('--proxy', default=None, help='代理服务器,如 http://127.0.0.1:7890')
|
|
25
26
|
@click.option('--port', type=int, default=None, help='连接指定端口的已有浏览器实例')
|
|
26
|
-
@click.option('--auto-connect', is_flag=True,
|
|
27
|
-
help='从用户常规启动的 Chrome 读取 DevToolsActivePort 自动发现端口'
|
|
28
|
-
'(需 Chrome 144+,用户在 chrome://inspect/#remote-debugging
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
@click.option('--auto-connect', '-a', is_flag=True,
|
|
28
|
+
help='从用户常规启动的 Chrome/Edge 读取 DevToolsActivePort 自动发现端口'
|
|
29
|
+
'(需 Chrome/Edge 144+,用户在 chrome://inspect/#remote-debugging 或 '
|
|
30
|
+
'edge://inspect/#devices 启用)')
|
|
31
|
+
@click.option('--channel',
|
|
32
|
+
type=click.Choice(['auto', 'stable', 'beta', 'dev', 'canary', 'chromium', 'edge']),
|
|
33
|
+
default='auto', show_default=True,
|
|
34
|
+
help='配合 --auto-connect 使用,定位默认 user-data-dir;'
|
|
35
|
+
'auto = 依次嗅探 chrome stable → edge stable,取首个含 DevToolsActivePort 的目录')
|
|
32
36
|
@click.option('--probe-dir', 'probe_dir', default=None,
|
|
33
37
|
help='配合 --auto-connect 使用,显式指定要探测的 user-data-dir '
|
|
34
38
|
'(覆盖 --channel 的默认路径)')
|
|
@@ -46,14 +50,16 @@ def register(cli):
|
|
|
46
50
|
dp open --port 9222
|
|
47
51
|
|
|
48
52
|
\b
|
|
49
|
-
【复用用户自己的浏览器 - 方式 B:--auto-connect(Chrome 144+ 推荐)】
|
|
50
|
-
无需特殊启动参数,正常打开 Chrome 即可:
|
|
51
|
-
1.
|
|
53
|
+
【复用用户自己的浏览器 - 方式 B:--auto-connect(Chrome/Edge 144+ 推荐)】
|
|
54
|
+
无需特殊启动参数,正常打开 Chrome 或 Edge 即可:
|
|
55
|
+
1. 打开浏览器:
|
|
56
|
+
- Chrome:访问 chrome://inspect/#remote-debugging
|
|
57
|
+
- Edge: 访问 edge://inspect/#devices
|
|
52
58
|
2. 勾选 "Allow remote debugging for this browser instance"
|
|
53
|
-
3. dp open --auto-connect
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
3. dp open --auto-connect # 默认 auto:先嗅探 Chrome,再 Edge
|
|
60
|
+
dp open --auto-connect --channel edge # 强制使用 Edge stable
|
|
61
|
+
dp open --auto-connect --channel beta # 使用 Chrome beta
|
|
62
|
+
dp open --auto-connect --probe-dir ~/my-profile # 自定义 profile
|
|
57
63
|
|
|
58
64
|
\b
|
|
59
65
|
【dp 自动管理浏览器】
|
|
@@ -83,6 +89,20 @@ def register(cli):
|
|
|
83
89
|
return
|
|
84
90
|
if probe_dir:
|
|
85
91
|
dir_to_probe = Path(probe_dir).expanduser()
|
|
92
|
+
elif channel == 'auto':
|
|
93
|
+
# 自动嗅探:chrome stable → edge stable,取首个含 DevToolsActivePort 的目录
|
|
94
|
+
hit, diag = sniff_auto_user_data_dir()
|
|
95
|
+
if hit is None:
|
|
96
|
+
detail = '\n'.join(f' - {ch:7s} {p} [{reason}]'
|
|
97
|
+
for ch, p, reason in diag)
|
|
98
|
+
error('自动嗅探未找到含 DevToolsActivePort 的 user-data-dir。\n'
|
|
99
|
+
'请先在 Chrome (chrome://inspect/#remote-debugging) 或 '
|
|
100
|
+
'Edge (edge://inspect/#devices) 启用远程调试,\n'
|
|
101
|
+
'或用 --channel/--probe-dir 显式指定。\n'
|
|
102
|
+
f'嗅探记录:\n{detail}',
|
|
103
|
+
code='PROFILE_NOT_FOUND')
|
|
104
|
+
return
|
|
105
|
+
dir_to_probe = hit
|
|
86
106
|
else:
|
|
87
107
|
dir_to_probe = default_user_data_dir_for_channel(channel)
|
|
88
108
|
if not dir_to_probe:
|