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.
Files changed (46) hide show
  1. {dp_cli-0.4.0 → dp_cli-0.6.0}/PKG-INFO +14 -13
  2. {dp_cli-0.4.0 → dp_cli-0.6.0}/README.md +13 -12
  3. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/bridge_manager.py +5 -4
  4. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/__init__.py +2 -2
  5. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/_utils.py +14 -3
  6. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/browser.py +34 -14
  7. dp_cli-0.6.0/dp_cli/commands/keyboard.py +405 -0
  8. dp_cli-0.6.0/dp_cli/commands/record.py +204 -0
  9. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/snapshot_cmd.py +1 -1
  10. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/tab.py +6 -0
  11. dp_cli-0.6.0/dp_cli/recorder.py +799 -0
  12. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/session.py +60 -5
  13. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/PKG-INFO +14 -13
  14. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/SOURCES.txt +2 -0
  15. {dp_cli-0.4.0 → dp_cli-0.6.0}/pyproject.toml +1 -1
  16. dp_cli-0.4.0/dp_cli/commands/keyboard.py +0 -225
  17. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/__init__.py +0 -0
  18. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/bridge.py +0 -0
  19. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/element.py +0 -0
  20. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/misc.py +0 -0
  21. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/network.py +0 -0
  22. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/page.py +0 -0
  23. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/commands/storage.py +0 -0
  24. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/__init__.py +0 -0
  25. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/playwright.py +0 -0
  26. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/locators/pw_js.py +0 -0
  27. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/main.py +0 -0
  28. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/output.py +0 -0
  29. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/__init__.py +0 -0
  30. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/a11y.py +0 -0
  31. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable.py +0 -0
  32. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/clickable_js.py +0 -0
  33. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/extract.py +0 -0
  34. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/js_scripts.py +0 -0
  35. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/snapshot/utils.py +0 -0
  36. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli/stealth.py +0 -0
  37. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/dependency_links.txt +0 -0
  38. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/entry_points.txt +0 -0
  39. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/requires.txt +0 -0
  40. {dp_cli-0.4.0 → dp_cli-0.6.0}/dp_cli.egg-info/top_level.txt +0 -0
  41. {dp_cli-0.4.0 → dp_cli-0.6.0}/setup.cfg +0 -0
  42. {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_bridge_integration.py +0 -0
  43. {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_bridge_manager.py +0 -0
  44. {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_clickable.py +0 -0
  45. {dp_cli-0.4.0 → dp_cli-0.6.0}/tests/test_pw_locator.py +0 -0
  46. {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.4.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
  )
@@ -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(如有),否则返回 ChromiumPage。
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
- target = page
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
- @click.option('--channel', type=click.Choice(['stable', 'beta', 'dev', 'canary', 'chromium']),
30
- default='stable', show_default=True,
31
- help='配合 --auto-connect 使用,定位默认 user-data-dir')
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. 打开 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: