| name | drissionpage-cli |
| description | Automate browser interactions, scrape web pages and test with DrissionPage. |
| allowed-tools | Bash(drissionpage-cli:*) Bash(python:*) Bash(pip:*) |
Browser Automation with drissionpage-cli
How this works: agent drives, human assists
drissionpage-cli opens a visible (headed) browser by default. The human can see the browser window and step in whenever needed — to log in, solve a CAPTCHA, complete a 2FA prompt, or accept a cookie banner. Once the human is done, the agent continues from where it left off.
Login state persists permanently in ~/.drissionpage-cli/profile. After the human logs in once, every future session is already authenticated — the agent never needs to ask again.
Typical flow
Agent: drissionpage-cli open https://some-site.com/dashboard
→ browser opens visibly; site redirects to login page
→ "I need you to log in — complete it in the browser window, then let me know"
Human: [logs in, handles any CAPTCHA or 2FA in the browser window]
Human: "done"
Agent: drissionpage-cli snapshot
→ now sees the dashboard; continues autonomously
→ next run: already logged in, skips this entirely
When to ask the human for help:
- Login / sign-in pages
- CAPTCHA or bot-detection challenges
- Two-factor authentication prompts
- OAuth / SSO flows that open popup windows
- Cookie consent dialogs that block interaction
Quick start
drissionpage-cli open
drissionpage-cli goto https://example.com
drissionpage-cli click "#submit-button"
drissionpage-cli type "search query"
drissionpage-cli press Enter
drissionpage-cli screenshot
drissionpage-cli close
Commands
Core
drissionpage-cli open
drissionpage-cli open https://example.com/
drissionpage-cli goto https://example.com
drissionpage-cli type "search query"
drissionpage-cli click "#submit"
drissionpage-cli dblclick "@id=item"
drissionpage-cli right-click "tag:div"
drissionpage-cli fill "css:input[name=email]" "user@example.com" --submit
drissionpage-cli drag "@id=source" "@id=target"
drissionpage-cli hover "tag:button"
drissionpage-cli select "tag:select" "option-text"
drissionpage-cli upload "css:input[type=file]" ./document.pdf
drissionpage-cli check "@type=checkbox"
drissionpage-cli uncheck "@type=checkbox"
drissionpage-cli snapshot
drissionpage-cli eval "document.title"
drissionpage-cli eval "return this.id" "#element"
drissionpage-cli dialog-accept
drissionpage-cli dialog-accept "confirmation text"
drissionpage-cli dialog-dismiss
drissionpage-cli resize 1920 1080
drissionpage-cli close
Navigation
drissionpage-cli go-back
drissionpage-cli go-forward
drissionpage-cli reload
Keyboard
drissionpage-cli press Enter
drissionpage-cli press ArrowDown
drissionpage-cli press Tab
Mouse
drissionpage-cli mousemove 150 300
drissionpage-cli mousedown
drissionpage-cli mousedown right
drissionpage-cli mouseup
drissionpage-cli scroll 0 100
Save as
drissionpage-cli screenshot
drissionpage-cli screenshot "#element"
drissionpage-cli screenshot --filename=page.png
drissionpage-cli pdf --filename=page.pdf
Tabs
drissionpage-cli tab-list
drissionpage-cli tab-new
drissionpage-cli tab-new https://example.com/page
drissionpage-cli tab-close
drissionpage-cli tab-close 2
drissionpage-cli tab-select 0
Storage
drissionpage-cli state-save
drissionpage-cli state-save auth.json
drissionpage-cli state-load auth.json
drissionpage-cli cookie-list
drissionpage-cli cookie-list --domain=example.com
drissionpage-cli cookie-get session_id
drissionpage-cli cookie-set session_id abc123
drissionpage-cli cookie-set session_id abc123 --domain=example.com --httpOnly --secure
drissionpage-cli cookie-delete session_id
drissionpage-cli cookie-clear
drissionpage-cli localstorage-list
drissionpage-cli localstorage-get theme
drissionpage-cli localstorage-set theme dark
drissionpage-cli localstorage-delete theme
drissionpage-cli localstorage-clear
drissionpage-cli sessionstorage-list
drissionpage-cli sessionstorage-get step
drissionpage-cli sessionstorage-set step 3
drissionpage-cli sessionstorage-delete step
drissionpage-cli sessionstorage-clear
DevTools
drissionpage-cli console
drissionpage-cli console warning
drissionpage-cli network
drissionpage-cli run-code "result = page.title"
drissionpage-cli run-code --filename=script.py
Open parameters
drissionpage-cli open
drissionpage-cli open --headless
drissionpage-cli open --sandbox
drissionpage-cli open --profile=/path/to/profile
drissionpage-cli open --port=9333
drissionpage-cli close
drissionpage-cli delete-data --reset-profile
--capture (network traffic recording)
Append --capture to any interaction command to record all network traffic triggered by that action.
Supported commands: open, goto, click, dblclick, right-click, type, fill, hover, drag, select, check, uncheck.
drissionpage-cli open https://example.com --capture
drissionpage-cli goto https://example.com --capture
drissionpage-cli click "#submit" --capture
drissionpage-cli fill "css:input[name=q]" "search term" --submit --capture
drissionpage-cli hover "@id=lazy-load-trigger" --capture
Creates a timestamped folder capture-<ts>/ in the current working directory:
capture-2026-04-14T16-06-30/
snapshot.html ← page HTML after the action completes
traffic.json ← manifest: [{url, method, status, content_type, file}, ...]
0001_index.html ← each network response body as its own file
0002_styles.css
0004_logo.png
0017_hero.jpg
0063_promo.mp4
...
Saves all response types: HTML, CSS, JS, JSON, images (jpg/png/webp/gif/svg/avif/bmp/ico), audio (mp3/ogg/wav/aac/flac), video (mp4/webm/ogv/mov).
Output:
[capture] folder → /project/capture-2026-04-14T16-06-30
[capture] snapshot → snapshot.html
[capture] traffic → traffic.json (125 requests)
[capture] media → 63 files (images/audio/video)
Snapshots
After each command, drissionpage-cli provides a snapshot of the current page state.
> drissionpage-cli goto https://example.com
- Page URL: https://example.com/
- Page Title: Example Domain
[Snapshot](~/.drissionpage-cli/snapshots/page-2026-02-14T19-22-42.html)
Targeting elements
DrissionPage supports multiple locator strategies:
drissionpage-cli click "css:#main > button.submit"
drissionpage-cli click "xpath://button[@id='submit']"
drissionpage-cli click "text:Submit"
drissionpage-cli click "tag:button"
drissionpage-cli click "@id=submit"
drissionpage-cli click "@class:btn"
drissionpage-cli click "@name^=user"
drissionpage-cli click "@data-testid=login"
drissionpage-cli click "@@tag()=button@@text()=Submit"
drissionpage-cli click "@|id=btn1@id=btn2"
Browser Sessions
drissionpage-cli -s=mysession open https://example.com
drissionpage-cli -s=mysession click "#button"
drissionpage-cli -s=mysession close
drissionpage-cli list
drissionpage-cli close-all
drissionpage-cli kill-all
Running custom code
Use run-code to execute arbitrary DrissionPage Python code:
drissionpage-cli run-code "result = page.title"
drissionpage-cli run-code "page.get('https://example.com'); result = page.html[:100]"
drissionpage-cli run-code --filename=myscript.py
The page variable is the active ChromiumPage instance. Set result to output a value.
Installation
pip install drissionpage-cli
Or install skills for Claude Code:
drissionpage-cli install --skills
Specific tasks
Feishu → Markdown (md command)
drissionpage-cli md https://<company>.feishu.cn/docx/<token> [out_dir]
drissionpage-cli md https://<company>.feishu.cn/wiki/<token> ./output
drissionpage-cli md https://<company>.feishu.cn/docx/<token> --save-html
Converts a Feishu document to Markdown. Captures full network traffic on page
load — the complete document block tree is embedded in Feishu's SSR HTML as
window.DATA.clientVars.data.block_map. No scrolling or DOM scraping needed.
Output layout:
out_dir/
Title/
Title.md ← Markdown with local references
images/
img_001.png ← document images and file cover thumbnails
files/
report.pdf ← file attachments if captured in traffic
Supported block types
| Block | Feishu name | Markdown output |
|---|
heading1–heading9 | 标题1–9 | #–###### (H7–H9 map to H6) |
text | 正文 | paragraph |
bullet | 无序列表 | - item |
ordered | 有序列表 | 1. item |
todo | 任务列表 | - [ ] item / - [x] item |
code | 代码块 | fenced ``` block |
quote_container | 引用块 | > blockquote |
callout | 高亮块 | > highlighted text |
divider | 分隔线 | --- |
image | 图片 |  — saved locally |
file | 文件 | > 📎 [name](files/name) if captured; metadata + cover thumbnail if not |
table | 表格 | GFM pipe table |
grid / grid_column | 分栏 | columns rendered inline (no visual columns) |
bookmark | 链接 | [title](url) inline link |
synced_source | 同步块 | content rendered inline (same as regular blocks) |
whiteboard | 绘图/思维导图/流程图/UML图 |  — screenshot of rendered canvas |
page | 子页面引用 | > 📄 title |
Inline formatting
bold, italic, bold italic, code, strikethrough, links — all decoded from Quill/Etherpad attributed text.
Known limitations
| Block | Feishu name | Reason |
|---|
whiteboard | 绘图/思维导图/流程图/UML | Screenshotted via live browser (WASM renderer). Fallback > 🎨 [not captured] if the element was not rendered (empty whiteboard or scroll timing). |
equation | 公式 | $$\nlatex\n$$ block math; inline $latex$ in text paragraphs |
button | 按钮 | Interactive UI element; no text equivalent |
comment | 评论/划线 | Annotation layer; not in block_map |
| Old DOC format | wikcn… wiki URLs | Different flat-text structure; not supported |
| Large docs (>239 blocks) | — | Feishu SSR caps initial payload; truncation warning added |
File attachments
Files in traffic are saved to files/. Cover thumbnails (PNG previews) are
always captured and shown as inline images. The actual file is only captured
if the browser downloaded it (small files may be auto-fetched; large PDFs usually are not).
Options:
out_dir — output directory (default: .)
--save-html — also save the raw SSR HTML alongside the Markdown