browserless-agent
# Browserless Agent 🌐
A comprehensive web automation skill for OpenClaw that provides 30+ browser actions including navigation, data extraction, form filling, screenshot capture, PDF generation, file handling, and advanced web scraping capabilities.
## 🚀 Features
- **Navigation**: Full control over page navigation, redirects, and history
- **Data Extraction**: Get text, attributes, HTML, computed styles, and structured data
- **Form Automation**: Type text, click buttons, select options, upload files
- **Visual Capture**: Screenshots (full page, element-only, viewport)
- **Content Generation**: Save pages as PDF with custom options
- **Advanced Interactions**: Hover, drag-drop, keyboard shortcuts, scrolling
- **Multi-tab Support**: Manage multiple pages and windows
- **Network Control**: Intercept requests, modify headers, block resources
- **Storage Access**: Manage cookies, localStorage, sessionStorage
- **Dynamic Content**: Wait for selectors, network idle, custom conditions
- **iFrames**: Interact with nested frame content
- **Browser State**: Emulate devices, set geolocation, handle dialogs
## 🔧 Configuration
This skill requires the `BROWSERLESS_URL` environment variable to be configured in OpenClaw.
Optionally, you can also set `BROWSERLESS_TOKEN` for authentication.
**To set it up:**
1. Open OpenClaw settings
2. Navigate to Skills → browserless-agent
3. Enter your Browserless base URL in the API Key field
4. (Optional) Add BROWSERLESS_TOKEN in the env section for token 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
```
The skill will automatically:
- Add `/playwright/chromium` if endpoint is not specified
- Append token as query parameter if `BROWSERLESS_TOKEN` is set
- Work with or without authentication token
Get your Browserless service at: [browserless.io](https://browserless.io)
Get your Browserless service at: [browserless.io](https://browserless.io)
## 📖 Available Actions
### Navigation & Page Control
#### `navigate`
Navigate to a URL.
```json
{"url": "https://example.com"}
```
#### `go_back`
Navigate to previous page in history.
```json
{}
```
#### `go_forward`
Navigate to next page in history.
```json
{}
```
#### `reload`
Reload the current page.
```json
{"hard": false}
```
#### `wait_for_load`
Wait for page to finish loading.
```json
{"timeout": 30000}
```
### Data Extraction
#### `get_text`
Extract text content from element(s).
```json
{"selector": "h1", "all": false}
```
#### `get_attribute`
Get attribute value from element(s).
```json
{"selector": "img", "attribute": "src", "all": false}
```
#### `get_html`
Get inner or outer HTML of element(s).
```json
{"selector": "article", "outer": false, "all": false}
```
#### `get_value`
Get input value from form element(s).
```json
{"selector": "input[name='email']"}
```
#### `get_style`
Get computed CSS style property.
```json
{"selector": ".box", "property": "background-color"}
```
#### `get_multiple`
Extract multiple pieces of data at once.
```json
{
"extractions": [
{"name": "title", "selector": "h1", "type": "text"},
{"name": "image", "selector": "img", "type": "attribute", "attribute": "src"},
{"name": "price", "selector": ".price", "type": "text"}
]
}
```
### Interaction & Input
#### `type_text`
Type text into an element.
```json
{"selector": "input[type='search']", "text": "hello world", "delay": 0, "clear": true}
```
#### `click`
Click on an element.
```json
{"selector": "button.submit", "force": false, "delay": 0}
```
#### `double_click`
Double-click on an element.
```json
{"selector": ".item"}
```
#### `right_click`
Right-click (context menu) on an element.
```json
{"selector": ".context-target"}
```
#### `hover`
Move mouse over an element.
```json
{"selector": ".menu-item"}
```
#### `focus`
Focus on an element.
```json
{"selector": "input"}
```
#### `select_option`
Select option(s) in a dropdown.
```json
{"selector": "select", "values": ["option1", "option2"]}
```
#### `check`
Check a checkbox or radio button.
```json
{"selector": "input[type='checkbox']"}
```
#### `uncheck`
Uncheck a checkbox.
```json
{"selector": "input[type='checkbox']"}
```
#### `upload_file`
Upload file(s) to file input.
```json
{"selector": "input[type='file']", "files": ["path/to/file.pdf"]}
```
#### `press_key`
Press keyboard key(s).
```json
{"key": "Enter"}
```
Common keys: Enter, Tab, Escape, ArrowDown, Control+A, etc.
#### `keyboard_type`
Type text with keyboard (supports shortcuts).
```json
{"text": "Hello World"}
```
### Scrolling & Position
#### `scroll_to`
Scroll to specific position.
```json
{"x": 0, "y": 500}
```
#### `scroll_into_view`
Scroll element into viewport.
```json
{"selector": ".footer"}
```
#### `scroll_to_bottom`
Scroll to bottom of page.
```json
{}
```
#### `scroll_to_top`
Scroll to top of page.
```json
{}
```
### Visual & Capture
#### `screenshot`
Take screenshot of page or element.
```json
{
"path": "screenshot.png",
"full_page": true,
"selector": null,
"quality": 90,
"type": "png"
}
```
#### `pdf`
Generate PDF from current page.
```json
{
"path": "page.pdf",
"format": "A4",
"landscape": false,
"margin": {"top": "1cm", "right": "1cm", "bottom": "1cm", "left": "1cm"},
"print_background": true
}
```
### Evaluation & Execution
#### `evaluate`
Execute JavaScript in page context.
```json
{"expression": "document.title"}
```
#### `evaluate_function`
Execute JavaScript function with arguments.
```json
{
"function": "(x, y) => x + y",
"args": [5, 10]
}
```
### Waiting & Timing
#### `wait_for_selector`
Wait for element to appear.
```json
{"selector": ".dynamic-content", "timeout": 10000, "state": "visible"}
```
States: visible, hidden, attached, detached
#### `wait_for_timeout`
Wait for specified milliseconds.
```json
{"timeout": 2000}
```
#### `wait_for_function`
Wait for JavaScript expression to return truthy.
```json
{
"expression": "() => document.readyState === 'complete'",
"timeout": 10000
}
```
#### `wait_for_navigation`
Wait for navigation to complete.
```json
{"timeout": 30000, "wait_until": "networkidle"}
```
wait_until options: load, domcontentloaded, networkidle
### Element State Checking
#### `is_visible`
Check if element is visible.
```json
{"selector": ".modal"}
```
#### `is_enabled`
Check if element is enabled.
```json
{"selector": "button"}
```
#### `is_checked`
Check if checkbox/radio is checked.
```json
{"selector": "input[type='checkbox']"}
```
#### `element_exists`
Check if element exists in DOM.
```json
{"selector": ".optional-element"}
```
#### `element_count`
Count elements matching selector.
```json
{"selector": ".list-item"}
```
### Storage & Cookies
#### `get_cookies`
Get all cookies or specific cookie.
```json
{"name": "session_id"}
```
#### `set_cookie`
Set a cookie.
```json
{
"name": "user_preference",
"value": "dark_mode",
"domain": "example.com",
"path": "/",
"expires": 1735689600,
"httpOnly": false,
"secure": true,
"sameSite": "Lax"
}
```
#### `delete_cookies`
Delete cookies.
```json
{"name": "session_id"}
```
Omit name to delete all cookies.
#### `get_local_storage`
Get localStorage item.
```json
{"key": "user_data"}
```
#### `set_local_storage`
Set localStorage item.
```json
{"key": "theme", "value": "dark"}
```
#### `clear_local_storage`
Clear all localStorage.
```json
{}
```
### Network & Requests
#### `set_extra_headers`
Set extra HTTP headers for all requests.
```json
{
"headers": {
"Authorization": "Bearer token123",
"X-Custom-Header": "value"
}
}
```
#### `block_resources`
Block specific resource types.
```json
{"types": ["image", "stylesheet", "font"]}
```
Types: document, stylesheet, image, media, font, script, xhr, fetch, other
#### `get_page_info`
Get comprehensive page information.
```json
{}
```
Returns: title, url, html (optional), viewport size, etc.
### iFrame Handling
#### `get_frame_text`
Get text from element inside iframe.
```json
{
"frame_selector": "iframe#content",
"selector": "h1"
}
```
#### `click_in_frame`
Click element inside iframe.
```json
{
"frame_selector": "iframe#content",
"selector": "button"
}
```
### Multi-Page/Tab
#### `new_page`
Open a new page/tab.
```json
{"url": "https://example.com"}
```
#### `close_page`
Close a specific page.
```json
{"index": 1}
```
#### `switch_page`
Switch to a different page.
```json
{"index": 0}
```
#### `list_pages`
List all open pages.
```json
{}
```
### Browser Context
#### `set_viewport`
Set viewport size.
```json
{"width": 1920, "height": 1080}
```
#### `emulate_device`
Emulate mobile device.
```json
{"device": "iPhone 12"}
```
Common devices: iPhone 12, iPad Pro, Galaxy S21, Pixel 5
#### `set_geolocation`
Set geolocation.
```json
{
"latitude": 37.7749,
"longitude": -122.4194,
"accuracy": 100
}
```
#### `set_user_agent`
Set custom user agent.
```json
{"user_agent": "Mozilla/5.0..."}
```
### Advanced Automation
#### `drag_and_drop`
Drag element and drop on target.
```json
{
"source": ".draggable",
"target": ".drop-zone"
}
```
#### `fill_form`
Fill multiple form fields at once.
```json
{
"fields": {
"input[name='email']": "user@example.com",
"input[name='password']": "secret123",
"select[name='country']": "US"
}
}
```
#### `extract_table`
Extract data from HTML table.
```json
{
"selector": "table.data",
"headers": true
}
```
#### `extract_links`
Extract all links from page.
```json
{
"selector": "a",
"filter": "^https://example\\.com"
}
```
#### `handle_dialog`
Set how to handle JavaScript dialogs (alert/confirm/prompt).
```json
{
"action": "accept",
"text": "Optional prompt response"
}
```
Actions: accept, dismiss
## 💡 Usage Examples
### Example 1: Web Scraping
```bash
python main.py get_multiple '{
"url": "https://news.ycombinator.com",
"extractions": [
{"name": "titles", "selector": ".titleline > a", "type": "text", "all": true},
{"name": "links", "selector": ".titleline > a", "type": "attribute", "attribute": "href", "all": true}
]
}'
```
### Example 2: Form Automation
```bash
python main.py fill_form '{
"url": "https://example.com/contact",
"fields": {
"input[name='name']": "John Doe",
"input[name='email']": "john@example.com",
"textarea[name='message']": "Hello!"
}
}'
```
### Example 3: Screenshot with Element Highlight
```bash
python main.py screenshot '{
"url": "https://example.com",
"selector": ".hero-section",
"path": "hero.png",
"full_page": false
}'
```
### Example 4: PDF Generation
```bash
python main.py pdf '{
"url": "https://example.com/report",
"path": "report.pdf",
"format": "A4",
"margin": {"top": "2cm", "bottom": "2cm"}
}'
```
## 🎯 OpenClaw Integration
To use this skill from OpenClaw, the agent can automatically invoke these actions. Examples:
**User:** "Take a screenshot of example.com"
**Agent:** Executes `screenshot` action with the URL
**User:** "What's the title of wikipedia.org?"
**Agent:** Navigates to Wikipedia and extracts text from the title element
**User:** "Search for 'Python' on Google and get the first result link"
**Agent:** Navigates to Google, types in search, clicks search, extracts first result
## 🔒 Security Notes
- Browserless connection uses WebSocket over TLS (wss://)
- Credentials are never logged or exposed in responses
- All browser actions are isolated in the Browserless container
- No local browser installation required
## 🐛 Troubleshooting
**Connection fails:**
- Verify `BROWSERLESS_WS` URL is correct
- Check if token is valid and not expired
- Ensure network allows WebSocket connections
**Timeout errors:**
- Increase timeout values for slow-loading pages
- Use `wait_for_selector` before interacting with dynamic content
- Consider using `wait_until: "networkidle"` for AJAX-heavy sites
**Element not found:**
- Verify selector using browser DevTools
- Wait for element to load with `wait_for_selector`
- Check if element is inside an iframe
## 📚 Resources
- [Playwright Documentation](https://playwright.dev)
- [CSS Selectors Reference](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)
- [Browserless Documentation](https://docs.browserless.io)
标签
skill
ai