DrissionPage-cli
Token-efficient browser automation CLI for coding agents, powered by DrissionPage.
Mirrors the architecture of playwright-cli but uses DrissionPage as the backend — pure Python, no Node.js required.
Recommended use: Agent-controlled browser with human in the loop
The intended workflow is agent drives, human assists:
- The agent opens a visible (headed) browser and starts the task.
- The human watches the browser window. When the agent hits a wall — login page, CAPTCHA, 2FA prompt, cookie consent — the human steps in, completes it manually, and tells the agent to continue.
- Login state is saved permanently in
~/.drissionpage-cli/profile. Log in once and every future session picks up where you left off — no re-authentication needed.
Agent: drissionpage-cli open https://github.com/settings
→ browser opens, hits sign-in page
→ reports: "I need you to log in — complete it in the browser window, then let me know"
Human: [logs in, solves any CAPTCHA/2FA in the browser]
Human: "done, continue"
Agent: drissionpage-cli snapshot
→ now sees the settings page, carries on autonomously
→ login is saved; next run skips this step entirely
This design handles the real-world friction that fully-headless automation cannot: sites that require human verification, SSO flows, or browser fingerprint checks.
Why CLI + Skills over MCP
Modern coding agents (Claude Code, GitHub Copilot, etc.) increasingly favour CLI-based workflows exposed as SKILLs over MCP because CLI invocations are more token-efficient: they avoid loading large tool schemas and verbose accessibility trees into the model context. This makes CLI + SKILLs better suited for high-throughput agents that must balance browser automation with large codebases within limited context windows.
Requirements
- Python 3.8+
- Chrome / Chromium browser installed
Installation
From PyPI (recommended)
pip install drissionpage-cli
From source (development)
git clone https://github.com/nicekate/DrissionPage-MCP.git
cd DrissionPage-MCP/DrissionPage-cli
pip install -e .
After installation both drissionpage-cli and the shortcut dp-cli are available globally:
dp-cli --version
dp-cli --help
dp-cli and drissionpage-cli are identical — use whichever you prefer.
Install skills for Claude Code
drissionpage-cli install --skills
This copies the SKILL.md and reference guides into .claude/skills/drissionpage-cli/ so that Claude Code (or any compatible agent) can discover them automatically.
One-liner — install the package and set up Claude Code skills in a single command:
pip install drissionpage-cli && drissionpage-cli install --skills
What gets installed
The install --skills command copies the following into .claude/skills/drissionpage-cli/:
| File | Purpose |
|---|---|
SKILL.md |
Skill definition & quick-start guide for the agent |
references/element-locators.md |
CSS, XPath, text, and attribute locator syntax |
references/running-code.md |
Custom DrissionPage Python code execution |
references/session-management.md |
Multiple concurrent browser sessions |
references/storage-state.md |
Cookies, localStorage, sessionStorage management |
references/screenshots-pdf.md |
Visual capture and PDF generation |
references/network-listening.md |
Network request monitoring |
references/dual-mode.md |
Browser + HTTP request mode switching |
Once installed, Claude Code automatically discovers the skill and can use drissionpage-cli commands for browser automation tasks.
Quick Start
# Open a headed browser (default) — user can see and interact with it
drissionpage-cli open https://example.com
# Take a snapshot of the page
drissionpage-cli snapshot
# Interact with elements using DrissionPage locators
drissionpage-cli click "@id=submit"
drissionpage-cli fill "css:input[name=email]" "user@example.com" --submit
# Evaluate JavaScript
drissionpage-cli eval "return document.title"
# Take a screenshot
drissionpage-cli screenshot --filename=result.png
# Close the browser
drissionpage-cli close
Headless mode (no visible window)
drissionpage-cli open https://example.com --headless
Use headless when running in CI or when no human oversight is needed and the site doesn't require interactive login.
Persistent Profile
By default, every session uses a single persistent Chrome profile stored at:
~/.drissionpage-cli/profile
This profile accumulates cookies, localStorage, and login tokens across all sessions. The practical effect:
- Log in once to any site — the agent never needs to authenticate again on subsequent runs.
- Works across different working directories — the profile is home-based, not project-local.
- Both headed and headless mode share the same profile.
To reset all login state (start fresh):
drissionpage-cli delete-data --reset-profile
For a fully isolated throwaway session (no persistent state):
drissionpage-cli open --sandbox
Capture mode (full page archive)
drissionpage-cli open https://example.com --capture
Creates a timestamped folder capture-<ts>/ in the current directory containing:
| File | Contents |
|---|---|
snapshot.html |
Page HTML at load-complete time |
traffic.json |
Manifest of all requests (url, method, status, content_type, file) |
0001_*.{ext} … |
Every response body saved as an individual file |
Captured file types include: HTML, CSS, JS, JSON, images (jpg, png, webp, gif, svg, avif, bmp, ico), audio (mp3, ogg, wav, aac, flac), and video (mp4, webm, ogv, mov).
[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)
Commands
Core
| Command | Description |
|---|---|
open [url] |
Open browser, optionally navigate to URL |
goto <url> |
Navigate to a URL |
click <ref> |
Click an element |
dblclick <ref> |
Double-click an element |
right-click <ref> |
Right-click an element |
type <text> [ref] |
Type text into element |
fill <ref> <text> [--submit] |
Clear and fill text (optionally press Enter) |
hover <ref> |
Hover over element |
drag <startRef> <endRef> |
Drag element to another |
select <ref> <value> |
Select dropdown option |
check <ref> / uncheck <ref> |
Check / uncheck a checkbox |
upload <ref> <file> |
Upload a file |
snapshot [ref] [--filename=f] |
Capture page or element snapshot |
eval <expr> [ref] |
Evaluate JavaScript on page or element |
run-code <code> [--filename=f] |
Run arbitrary DrissionPage Python code |
screenshot [ref] [--filename=f] |
Take a screenshot |
pdf [--filename=f] |
Save page as PDF |
resize <w> <h> |
Resize the browser window |
dialog-accept [text] |
Accept a dialog |
dialog-dismiss |
Dismiss a dialog |
close |
Close the browser |
Navigation
| Command | Description |
|---|---|
go-back |
Go back |
go-forward |
Go forward |
reload |
Reload page |
Keyboard & Mouse
| Command | Description |
|---|---|
press <key> |
Press a key (Enter, ArrowDown, Tab, etc.) |
mousemove <x> <y> |
Move mouse to coordinates |
mousedown [button] |
Press mouse button |
mouseup [button] |
Release mouse button |
scroll <dx> <dy> |
Scroll the page |
Tabs
| Command | Description |
|---|---|
tab-list |
List all tabs |
tab-new [url] |
Create new tab |
tab-close [index] |
Close a tab |
tab-select <index> |
Select a tab |
Cookies & Storage
| Command | Description |
|---|---|
cookie-list [--domain=d] |
List cookies |
cookie-get <name> |
Get a cookie |
cookie-set <name> <val> [opts] |
Set a cookie |
cookie-delete <name> |
Delete a cookie |
cookie-clear |
Clear all cookies |
localstorage-list|get|set|delete|clear |
Manage localStorage |
sessionstorage-list|get|set|delete|clear |
Manage sessionStorage |
state-save [filename] |
Save cookies + storage to JSON |
state-load <filename> |
Restore cookies + storage from JSON |
Session Management
| Command | Description |
|---|---|
list |
List all active sessions |
close |
Close current session's browser |
close-all |
Close all sessions |
kill-all |
Kill all browser processes |
delete-data [--reset-profile] |
Close session; optionally wipe the persistent profile |
Targeting Elements
DrissionPage supports rich locator syntax:
# CSS selector
drissionpage-cli click "css:#main > button.submit"
# XPath
drissionpage-cli click "xpath://button[@id='submit']"
# Text content
drissionpage-cli click "text:Submit"
# Tag name
drissionpage-cli click "tag:button"
# Attribute matching
drissionpage-cli click "@id=submit"
drissionpage-cli click "@class:btn" # contains
drissionpage-cli click "@name^=user" # starts with
drissionpage-cli click "@data-testid=login"
# Combined (AND)
drissionpage-cli click "@@tag()=button@@text()=Submit"
# Combined (OR)
drissionpage-cli click "@|id=btn1@id=btn2"
Named Sessions
Run multiple isolated browser instances concurrently:
drissionpage-cli -s=auth open https://app.example.com/login
drissionpage-cli -s=scrape open https://data.example.com
drissionpage-cli list
drissionpage-cli close-all
Or set a default session via environment variable:
DRISSIONPAGE_CLI_SESSION=myproject drissionpage-cli open https://example.com
Running Custom Code
Execute arbitrary DrissionPage Python code with run-code. The page variable is the active ChromiumPage instance. Set result to output a return value.
drissionpage-cli run-code "result = page.title"
drissionpage-cli run-code "
eles = page.eles('tag:a')
result = [{'text': a.text, 'href': a.link} for a in eles if a.link]
"
drissionpage-cli run-code --filename=myscript.py
Testing
The project includes two test suites:
Unit tests (no browser required)
python3 -m pytest tests/test_unit.py -v
Integration tests (browser required)
python3 -m pytest tests/test_integration.py -v
To skip integration tests in CI (no browser available):
SKIP_INTEGRATION=1 python3 -m pytest tests/ -v
Run all tests
python3 -m pytest tests/ -v
Project Structure
DrissionPage-cli/
drissionpage_cli/ # Main package
__init__.py # CLI entry point (59 commands)
skills/drissionpage-cli/ # Bundled skill files
SKILL.md
references/
element-locators.md
running-code.md
session-management.md
storage-state.md
screenshots-pdf.md
network-listening.md
dual-mode.md
pyproject.toml # Python packaging
requirements.txt # DrissionPage>=4.0.0
pytest.ini # Test configuration
README.md
LICENSE
scripts/
update.py # Skill update script
tests/
conftest.py # Shared fixtures
test_unit.py # Unit tests (mocked, no browser)
test_integration.py # Integration tests (real browser)
Environment Variables
| Variable | Description |
|---|---|
DRISSIONPAGE_CLI_SESSION |
Default session name (default: default) |
DRISSIONPAGE_CLI_DIR |
Override CLI data/profile directory (default: ~/.drissionpage-cli) |
DRISSIONPAGE_CLI_DEBUG |
Set to 1 for full tracebacks on errors |
SKIP_INTEGRATION |
Set to 1 to skip browser integration tests |
License
Apache-2.0
Metadata
Release files for drissionpage-cli 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| drissionpage_cli-0.2.0.tar.gz | 61.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| drissionpage_cli-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 115.2 kB
Release files / drissionpage_cli-0.2.0.tar.gz
| Download URL | drissionpage_cli-0.2.0.tar.gz |
|---|---|
| Size | 61.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1cf028c940a932812e90ee6c82e6d35aac2345280e05d82d8af02815726de946
|
|
BLAKE2b-256 checksum How to use checksums |
4a74507bfc0c88317bc4514e3bb404e438bcfac8815b2c610fac7506a600f040
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / drissionpage_cli-0.2.0-py3-none-any.whl
| Download URL | drissionpage_cli-0.2.0-py3-none-any.whl |
|---|---|
| Size | 53.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
96e170a0796391d8f4acebe330557923c7b42e948e378f9da22ac74404d60d9c
|
|
BLAKE2b-256 checksum How to use checksums |
298657c1a9b2813082945e506a9c17a39f491f85d9857a02401d8a257df0dbf3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|