browserless-agent
This skill provides web automation via Browserless with actions for navigation, scraping, form automation, screenshots and PDF generation. It reads BROWSERLESS_URL and BROWSERLESS_TOKEN and connects to external WebSocket endpoints such as wss://chrome.browserless.io; install/run examples (pip install -r requirements.txt, python main.py ...) are included.
Browserless Agent - OpenClaw Skill 🌐
A professional, production-ready web automation skill for OpenClaw with 50+ browser actions.
🚀 Quick Start
1. Install Dependencies
pip install -r requirements.txt
playwright install chromium
2. Configure OpenClaw
This skill will automatically prompt you to configure BROWSERLESS_URL in the OpenClaw UI:
- Open OpenClaw Settings
- Go to Skills → browserless-agent
- Enter your Browserless base URL in the API Key field
- (Optional) Add
BROWSERLESS_TOKENin the env section for authentication
Configuration Examples:
Cloud Service (with token):
BROWSERLESS_URL=wss://chrome.browserless.io
BROWSERLESS_TOKEN=your-token-here
Local Service (no token):
BROWSERLESS_URL=ws://localhost:3000
Custom Endpoint:
BROWSERLESS_URL=wss://your-host.com/playwright/chromium
BROWSERLESS_TOKEN=optional-token
3. Get Browserless Service
Option A: Cloud Service (Recommended)
- Sign up at browserless.io
- Free tier available
- Get your base URL and token from dashboard
Option B: Self-Hosted
docker run -p 3000:3000 browserless/chrome
# Base URL: ws://localhost:3000
# No token needed
📖 Features
Navigation & Pages (10 actions)
navigate- Go to URLgo_back/go_forward- Browser historyreload- Refresh pagenew_page/close_page/switch_page- Multi-tab supportwait_for_load/wait_for_navigation- Smart waiting
Data Extraction (7 actions)
get_text- Extract text contentget_attribute- Get element attributesget_html- Get inner/outer HTMLget_value- Get form valuesget_style- Get computed CSSget_multiple- Batch extractionget_page_info- Page metadata
Interaction (13 actions)
click/double_click/right_clicktype_text- Type with optionshover/focusselect_option- Dropdownscheck/uncheck- Checkboxesupload_file- File uploadspress_key/keyboard_type- Keyboard controldrag_and_drop- Drag & drop
Visual Capture (2 actions)
screenshot- PNG/JPEG screenshotspdf- Generate PDFs
Form Automation (1 action)
fill_form- Fill multiple fields at once
Scrolling (4 actions)
scroll_to/scroll_into_viewscroll_to_bottom/scroll_to_top
Waiting & Timing (4 actions)
wait_for_selector- Wait for elementswait_for_timeout- Fixed delayswait_for_function- Wait for conditions
Element State (5 actions)
is_visible/is_enabled/is_checkedelement_exists/element_count
Storage & Cookies (6 actions)
get_cookies/set_cookie/delete_cookiesget_local_storage/set_local_storage/clear_local_storage
Network Control (3 actions)
set_extra_headers- Custom headersblock_resources- Block images/CSS/fonts- Request interception
Advanced (7 actions)
extract_table- Parse HTML tablesextract_links- Get all links with filteringevaluate/evaluate_function- Run JavaScripthandle_dialog- Alert/confirm handlingget_frame_text/click_in_frame- iFrame support
Browser Context (3 actions)
set_viewport- Screen sizeset_geolocation- GPS locationset_user_agent- User agent spoofing
💡 Usage Examples
From Command Line
# Navigate to a website
python main.py navigate '{"url": "https://example.com"}'
# Take a screenshot
python main.py screenshot '{"url": "https://example.com", "path": "page.png", "full_page": true}'
# Extract data
python main.py get_multiple '{
"url": "https://news.ycombinator.com",
"extractions": [
{"name": "titles", "selector": ".titleline > a", "type": "text", "all": true}
]
}'
# Fill a form
python main.py fill_form '{
"url": "https://example.com/contact",
"fields": {
"input[name=\"email\"]": "user@example.com",
"textarea[name=\"message\"]": "Hello!"
}
}'
# Generate PDF
python main.py pdf '{
"url": "https://example.com",
"path": "page.pdf",
"format": "A4",
"margin": {"top": "1cm", "bottom": "1cm"}
}'
From OpenClaw
The agent will automatically use this skill when you ask questions like:
User: "Take a screenshot of google.com"
Action: screenshot
Args: {"url": "https://google.com", "path": "google.png"}
User: "What's the title of wikipedia.org?"
Action: navigate → get_text
Args: {"url": "https://wikipedia.org", "selector": "h1"}
User: "Search for 'Python' on GitHub and get the first 5 repository names"
Action: navigate → type_text → press_key → wait_for_selector → get_multiple
User: "Fill out the contact form on example.com with my email"
Action: fill_form
Args: {
"url": "https://example.com/contact",
"fields": {"input[type='email']": "your@email.com"}
}
🎯 Real-World Use Cases
1. Web Scraping
# Extract product catalog
python main.py get_multiple '{
"url": "https://store.com/products",
"extractions": [
{"name": "names", "selector": ".product-name", "type": "text", "all": true},
{"name": "prices", "selector": ".price", "type": "text", "all": true},
{"name": "images", "selector": ".product-img", "type": "attribute", "attribute": "src", "all": true}
]
}'
2. Automated Testing
# Test login flow
python main.py fill_form '{
"url": "https://app.com/login",
"fields": {
"input[name=\"username\"]": "testuser",
"input[name=\"password\"]": "testpass"
}
}'
python main.py click '{"selector": "button[type=\"submit\"]"}'
python main.py wait_for_selector '{"selector": ".dashboard", "timeout": 5000}'
python main.py screenshot '{"path": "dashboard.png"}'
3. Content Monitoring
# Check for changes
python main.py navigate '{"url": "https://news.com"}'
python main.py get_text '{"selector": ".headline", "all": true}'
# Compare with previous results
4. Report Generation
# Generate PDF report
python main.py navigate '{"url": "https://analytics.com/report"}'
python main.py wait_for_selector '{"selector": ".chart-loaded"}'
python main.py pdf '{
"path": "monthly-report.pdf",
"format": "Letter",
"landscape": true,
"margin": {"top": "2cm", "bottom": "2cm"}
}'
5. Form Automation
# Batch form submission
python main.py fill_form '{
"url": "https://survey.com",
"fields": {
"input[name=\"name\"]": "John Doe",
"input[name=\"email\"]": "john@example.com",
"select[name=\"rating\"]": "5",
"textarea[name=\"feedback\"]": "Great service!"
}
}'
python main.py click '{"selector": "button.submit"}'
🔧 Advanced Configuration
Custom Wait Strategies
# Wait for network to be idle (good for AJAX sites)
python main.py navigate '{"url": "https://spa-app.com", "wait_until": "networkidle"}'
# Wait for specific element
python main.py wait_for_selector '{
"selector": ".dynamic-content",
"timeout": 15000,
"state": "visible"
}'
Block Resources (Speed Up)
# Block images and CSS for faster scraping
python main.py block_resources '{"types": ["image", "stylesheet", "font"]}'
python main.py navigate '{"url": "https://example.com"}'
Custom Headers (Authentication)
python main.py set_extra_headers '{
"headers": {
"Authorization": "Bearer token123",
"X-Custom-Header": "value"
}
}'
Mobile Emulation
python main.py set_viewport '{"width": 375, "height": 667}'
python main.py set_user_agent '{"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)"}'
🐛 Troubleshooting
Connection Failed
Error: Timeout occurred: connect ETIMEDOUT
Solutions:
- Verify
BROWSERLESS_URLis correct - Check if
BROWSERLESS_TOKENis set (if required by your service) - Check if Browserless service is running
- Test connection:
curl -I https://your-browserless-host.com - Ensure firewall allows WebSocket connections
Element Not Found
Error: waiting for selector ".my-button" failed
Solutions:
- Use browser DevTools to verify selector
- Wait for element:
wait_for_selectorbefore interaction - Check if element is in iframe: use
click_in_frame - Increase timeout:
"timeout": 30000
Slow Performance
Solutions:
- Block unused resources:
block_resources - Use
wait_until: "domcontentloaded"instead ofload - Avoid full page screenshots for large pages
- Use specific selectors instead of
get_all
JavaScript Errors
Error: Evaluation failed
Solutions:
- Wrap in try-catch:
evaluate '{"expression": "try { myFunc() } catch(e) { e.message }"}' - Wait for page load before evaluation
- Check browser console in Browserless debugger
📚 API Reference
Common Parameters
All functions support:
url(optional): Navigate before actiontimeout(optional): Custom timeout in millisecondsselector: CSS selector (use DevTools to find)
Selector Tips
/* ID */
#my-button
/* Class */
.button-primary
/* Attribute */
input[name="email"]
a[href*="github"]
/* Hierarchy */
div.container > button
nav a.active
/* Pseudo-classes */
button:not(.disabled)
li:first-child
Return Format
All actions return JSON:
{
"status": "success|error",
"action": "action_name",
"message": "error message if failed",
"...": "action-specific data"
}
🔒 Security
- ✅ Credentials never logged
- ✅ TLS encryption (wss://)
- ✅ Isolated browser containers
- ✅ No local browser required
- ⚠️ Be careful with sensitive data in screenshots
- ⚠️ Validate user input before navigation
- ⚠️ Use authentication headers securely
📦 Dependencies
playwright>=1.40.0
🤝 Contributing
Found a bug or want a new feature? Open an issue!
📄 License
MIT License - Use freely and modify as needed.
🌟 Tips & Best Practices
-
Always wait for dynamic content
python main.py wait_for_selector '{"selector": ".loaded"}' -
Use batch operations
# Better: One call with get_multiple # Instead of: Multiple get_text calls -
Handle errors gracefully
# Check if element exists first python main.py element_exists '{"selector": ".optional"}' -
Optimize for speed
# Block unnecessary resources python main.py block_resources '{"types": ["image", "font"]}' -
Use specific selectors
# Good: button[data-test-id="submit"] # Bad: div > div > button
🎓 Learning Resources
Made with ❤️ for OpenClaw
Need help? Ask your OpenClaw agent: "How do I use the browserless-agent skill?"