dp-cli 0.5.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.
Files changed (45) hide show
  1. {dp_cli-0.5.0 → dp_cli-0.6.0}/PKG-INFO +14 -13
  2. {dp_cli-0.5.0 → dp_cli-0.6.0}/README.md +13 -12
  3. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/bridge_manager.py +5 -4
  4. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/browser.py +33 -13
  5. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/session.py +60 -5
  6. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/PKG-INFO +14 -13
  7. {dp_cli-0.5.0 → dp_cli-0.6.0}/pyproject.toml +1 -1
  8. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/__init__.py +0 -0
  9. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/bridge.py +0 -0
  10. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/__init__.py +0 -0
  11. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/_utils.py +0 -0
  12. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/element.py +0 -0
  13. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/keyboard.py +0 -0
  14. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/misc.py +0 -0
  15. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/network.py +0 -0
  16. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/page.py +0 -0
  17. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/record.py +0 -0
  18. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/snapshot_cmd.py +0 -0
  19. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/storage.py +0 -0
  20. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/commands/tab.py +0 -0
  21. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/locators/__init__.py +0 -0
  22. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/locators/playwright.py +0 -0
  23. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/locators/pw_js.py +0 -0
  24. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/main.py +0 -0
  25. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/output.py +0 -0
  26. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/recorder.py +0 -0
  27. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/__init__.py +0 -0
  28. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/a11y.py +0 -0
  29. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable.py +0 -0
  30. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable_js.py +0 -0
  31. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/extract.py +0 -0
  32. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/js_scripts.py +0 -0
  33. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/snapshot/utils.py +0 -0
  34. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli/stealth.py +0 -0
  35. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/SOURCES.txt +0 -0
  36. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/dependency_links.txt +0 -0
  37. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/entry_points.txt +0 -0
  38. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/requires.txt +0 -0
  39. {dp_cli-0.5.0 → dp_cli-0.6.0}/dp_cli.egg-info/top_level.txt +0 -0
  40. {dp_cli-0.5.0 → dp_cli-0.6.0}/setup.cfg +0 -0
  41. {dp_cli-0.5.0 → dp_cli-0.6.0}/tests/test_bridge_integration.py +0 -0
  42. {dp_cli-0.5.0 → dp_cli-0.6.0}/tests/test_bridge_manager.py +0 -0
  43. {dp_cli-0.5.0 → dp_cli-0.6.0}/tests/test_clickable.py +0 -0
  44. {dp_cli-0.5.0 → dp_cli-0.6.0}/tests/test_pw_locator.py +0 -0
  45. {dp_cli-0.5.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.5.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 # stable channel, default profile
79
- dp open --auto-connect --channel beta # pick a different 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 Chrome (it's your browser, not dp's).
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 # stable channel, default profile
58
- dp open --auto-connect --channel beta # pick a different 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 Chrome (it's your browser, not dp's).
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 并连接 Chrome', file=sys.stderr, flush=True)
98
- print('[dp] 💡 若 Chrome 弹出 "Allow remote debugging" 对话框,'
99
- '请切到 Chrome 窗口点击 "Allow"(后续命令会自动复用连接)',
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'若是首次连接:请把 Chrome 窗口切到前台,点击弹出的'
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
  )
@@ -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
@@ -24,11 +25,14 @@ def register(cli):
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
27
  @click.option('--auto-connect', '-a', is_flag=True,
27
- help='从用户常规启动的 Chrome 读取 DevToolsActivePort 自动发现端口'
28
- '(需 Chrome 144+,用户在 chrome://inspect/#remote-debugging 启用)')
29
- @click.option('--channel', type=click.Choice(['stable', 'beta', 'dev', 'canary', 'chromium']),
30
- default='stable', show_default=True,
31
- help='配合 --auto-connect 使用,定位默认 user-data-dir')
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. 打开 Chrome,访问 chrome://inspect/#remote-debugging
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
- dp 会从 Chrome user-data-dir 自动读取 DevToolsActivePort 拿到端口。
55
- 指定非 stable 渠道:dp open --auto-connect --channel beta
56
- 指定自定义 profile:dp open --auto-connect --probe-dir ~/my-chrome-profile
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:
@@ -84,9 +84,9 @@ def _detect_headless(port: int) -> bool:
84
84
 
85
85
 
86
86
  def default_user_data_dir_for_channel(channel: str = 'stable') -> Path | None:
87
- """返回指定 channel 的 Chrome 默认 user-data-dir。
87
+ """返回指定 channel 的 Chrome/Edge 默认 user-data-dir。
88
88
 
89
- :param channel: stable / beta / dev / canary / chromium
89
+ :param channel: stable / beta / dev / canary / chromium / edge
90
90
  :return: 用户数据目录 Path;不存在时返回 None
91
91
  """
92
92
  home = Path.home()
@@ -98,6 +98,7 @@ def default_user_data_dir_for_channel(channel: str = 'stable') -> Path | None:
98
98
  'dev': [home / '.config' / 'google-chrome-unstable'],
99
99
  'canary': [home / '.config' / 'google-chrome-canary'],
100
100
  'chromium': [home / '.config' / 'chromium'],
101
+ 'edge': [home / '.config' / 'microsoft-edge'],
101
102
  }
102
103
  elif sys.platform == 'darwin':
103
104
  base = home / 'Library' / 'Application Support'
@@ -107,6 +108,7 @@ def default_user_data_dir_for_channel(channel: str = 'stable') -> Path | None:
107
108
  'dev': [base / 'Google' / 'Chrome Dev'],
108
109
  'canary': [base / 'Google' / 'Chrome Canary'],
109
110
  'chromium': [base / 'Chromium'],
111
+ 'edge': [base / 'Microsoft Edge'],
110
112
  }
111
113
  elif sys.platform.startswith('win'):
112
114
  local = Path(os.environ.get('LOCALAPPDATA', home / 'AppData' / 'Local'))
@@ -116,6 +118,7 @@ def default_user_data_dir_for_channel(channel: str = 'stable') -> Path | None:
116
118
  'dev': [local / 'Google' / 'Chrome Dev' / 'User Data'],
117
119
  'canary': [local / 'Google' / 'Chrome SxS' / 'User Data'],
118
120
  'chromium': [local / 'Chromium' / 'User Data'],
121
+ 'edge': [local / 'Microsoft' / 'Edge' / 'User Data'],
119
122
  }
120
123
 
121
124
  for p in candidates.get(channel, []):
@@ -124,6 +127,56 @@ def default_user_data_dir_for_channel(channel: str = 'stable') -> Path | None:
124
127
  return None
125
128
 
126
129
 
130
+ # --auto-connect 不传 --channel 时的嗅探顺序:先 Chrome stable,再 Edge stable
131
+ _AUTO_SNIFF_CHANNELS = ('stable', 'edge')
132
+
133
+
134
+ def _is_port_alive(port: int, timeout: float = 0.3) -> bool:
135
+ """轻量 TCP 探活:能 connect 上即视为活的。"""
136
+ import socket
137
+ try:
138
+ with socket.create_connection(('127.0.0.1', port), timeout=timeout):
139
+ return True
140
+ except Exception:
141
+ return False
142
+
143
+
144
+ def sniff_auto_user_data_dir() -> tuple[Path | None, list[tuple[str, Path, str]]]:
145
+ """auto channel:按 _AUTO_SNIFF_CHANNELS 顺序查找首个含可用 DevToolsActivePort 的目录。
146
+
147
+ 会校验端口实际可连通,避免命中浏览器已关闭后残留的陈旧文件。
148
+
149
+ :return: (命中目录或 None, 诊断记录列表)
150
+ 诊断记录每项为 (channel, path, reason),reason 取值:
151
+ - 'hit' 命中(文件存在且端口活)
152
+ - 'no_dir' 用户数据目录不存在
153
+ - 'no_port' 目录存在但缺 DevToolsActivePort
154
+ - 'stale' DevToolsActivePort 存在但端口不通(陈旧残留)
155
+ - 'bad_file' DevToolsActivePort 文件解析失败
156
+ """
157
+ diag: list[tuple[str, Path, str]] = []
158
+ for ch in _AUTO_SNIFF_CHANNELS:
159
+ p = default_user_data_dir_for_channel(ch)
160
+ if p is None:
161
+ diag.append((ch, Path('<not found>'), 'no_dir'))
162
+ continue
163
+ f = p / 'DevToolsActivePort'
164
+ if not f.exists():
165
+ diag.append((ch, p, 'no_port'))
166
+ continue
167
+ try:
168
+ port = discover_port_from_profile(p)
169
+ except (FileNotFoundError, ValueError):
170
+ diag.append((ch, p, 'bad_file'))
171
+ continue
172
+ if not _is_port_alive(port):
173
+ diag.append((ch, p, 'stale'))
174
+ continue
175
+ diag.append((ch, p, 'hit'))
176
+ return p, diag
177
+ return None, diag
178
+
179
+
127
180
  def discover_port_from_profile(user_data_dir: str | os.PathLike) -> int:
128
181
  """从 Chrome user-data-dir 的 DevToolsActivePort 文件读取端口号。
129
182
 
@@ -137,9 +190,11 @@ def discover_port_from_profile(user_data_dir: str | os.PathLike) -> int:
137
190
  if not p.exists():
138
191
  raise FileNotFoundError(
139
192
  f'未找到 {p}。请确认:\n'
140
- f' 1. 浏览器正在运行,且 --user-data-dir 匹配:{user_data_dir}\n'
141
- f' 2. 已在地址栏打开 chrome://inspect/#remote-debugging 并点击\n'
142
- f' "Allow remote debugging for this browser instance"(需 Chrome 144+)'
193
+ f' 1. 浏览器正在运行,且 user-data-dir 匹配:{user_data_dir}\n'
194
+ f' 2. 已在地址栏打开 chrome://inspect/#remote-debugging\n'
195
+ f' (Edge edge://inspect/#devices)并点击\n'
196
+ f' "Allow remote debugging for this browser instance"\n'
197
+ f' (需 Chrome/Edge 144+)'
143
198
  )
144
199
  lines = [l.strip() for l in p.read_text(encoding='utf-8').splitlines() if l.strip()]
145
200
  if not lines:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dp-cli
3
- Version: 0.5.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 # stable channel, default profile
79
- dp open --auto-connect --channel beta # pick a different 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 Chrome (it's your browser, not dp's).
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)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dp-cli"
7
- version = "0.5.0"
7
+ version = "0.6.0"
8
8
  description = "A powerful CLI for DrissionPage — browser automation, structured data extraction, network listening and more."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes