When to Use
- Price monitoring: Target
.product-price or [data-price] selectors to extract prices from e-commerce pages into a structured dataset for comparison workflows.
- Lead generation: Scrape contact names, email addresses, and job titles from directory or profile pages using targeted CSS selectors.
- News and content aggregation: Extract article titles, publication dates, and summary text from news sites by selector without dealing with full HTML parsing.
- Inventory and availability tracking: Poll a supplier's product page for stock-status element text and trigger alerts when it changes to "Out of Stock".
- Job board monitoring: Scrape job listings by selector to feed a downstream AI classification or filtering node.
scrape vs. content: scrape returns only the targeted element data as structured JSON — ideal when you know your selectors in advance. Use
content when you need the full HTML and will parse it in a subsequent node or AI step.
Configuration
Connection
| Field | Required | Description |
BaseUrl | Required | Browserless instance URL. |
Token | Optional | API token for cloud Browserless. |
Operation
| Field | Required | Description |
url | Required | The page URL to scrape. Supports BizFirst expressions. |
elements | Required | Array of element descriptor objects. Each object must have a selector (CSS selector string) and optionally a timeout (ms to wait for the selector to appear). Multiple selectors can be listed to extract several fields in a single request. |
gotoOptions | Optional | Navigation options JSON: waitUntil and timeout. |
waitForSelector | Optional | Wait for a specific selector before beginning element extraction. |
waitForTimeout | Optional | Fixed delay in milliseconds after page load before extraction. |
waitForFunction | Optional | JavaScript expression to poll before extraction. |
debug | Optional | Debug object — when set, Browserless includes additional diagnostic data alongside results. Useful during development to verify selector matches. |
setExtraHTTPHeaders | Optional | Additional request headers. |
cookies | Optional | Cookies to set before navigation. |
rejectResourceTypes | Optional | Resource types to block to speed up page load. |
blockAds | Optional | Default true. |
bestAttempt | Optional | Default true. Return partial results even if some sub-resources failed. |
useCustomBody | Optional | Send customBodyJson verbatim as the request body. |
customBodyJson | Optional | Raw JSON body when useCustomBody is true. |
Sample Configuration
{
"operation": "scrape",
"baseUrl": "https://chrome.browserless.io",
"token": "{{ $env.BROWSERLESS_TOKEN }}",
"url": "https://store.example.com/products/{{ $input.productSlug }}",
"elements": [
{ "selector": ".product-title", "timeout": 8000 },
{ "selector": ".product-price", "timeout": 8000 },
{ "selector": ".product-availability","timeout": 5000 },
{ "selector": ".product-rating span", "timeout": 5000 }
],
"gotoOptions": { "waitUntil": "networkidle2", "timeout": 20000 },
"rejectResourceTypes": ["image", "media", "font"],
"blockAds": true
}
Validation Errors
| Error Code | Cause |
VAL_MISSING_URL | url is empty and no html source was provided. |
VAL_MISSING_ELEMENTS | The elements array is empty or not provided. |
CFG_INVALID | Node settings could not be resolved to a scrape configuration. |
BROWSERLESS_BAD_REQUEST | customBodyJson is not valid JSON or does not match the scrape request shape. |
Output
Success Port
| Field | Type | Description |
status | string | Always "success". |
errorCode | string | Always empty on success. |
operation | string | Always "scrape". |
url | string | URL that was scraped. |
count | int | Total number of element result records across all selectors. |
items | array | Array of result objects. Each object has: selector (the CSS selector that matched), text (trimmed text content), html (inner HTML), attributes (array of attribute name/value pairs). |
Error Port
| Field | Type | Description |
status | string | Always "error". |
errorCode | string | Machine-readable error code. |
errorMessage | string | Human-readable failure description. |
operation | string | Always "scrape". |
httpStatusCode | int | HTTP status code from Browserless, if available. |
Sample Output
{
"status": "success",
"errorCode": "",
"operation": "scrape",
"url": "https://store.example.com/products/widget-pro",
"count": 4,
"items": [
{
"selector": ".product-title",
"text": "Widget Pro 2026 Edition",
"html": "<h1 class=\"product-title\">Widget Pro 2026 Edition</h1>",
"attributes": [{ "name": "class", "value": "product-title" }]
},
{
"selector": ".product-price",
"text": "$49.99",
"html": "<span class=\"product-price\" data-currency=\"USD\">$49.99</span>",
"attributes": [
{ "name": "class", "value": "product-price" },
{ "name": "data-currency", "value": "USD" }
]
},
{
"selector": ".product-availability",
"text": "In stock",
"html": "<span class=\"product-availability in-stock\">In stock</span>",
"attributes": [{ "name": "class", "value": "product-availability in-stock" }]
},
{
"selector": ".product-rating span",
"text": "4.7",
"html": "<span>4.7</span>",
"attributes": []
}
]
}
Expression Reference
| Expression | Value |
{{ $output.BrowserlessNode.count }} | Total number of extracted element records. |
{{ $output.BrowserlessNode.items }} | Full array of item objects. |
{{ $output.BrowserlessNode.items[0].text }} | Text of the first matched element. |
{{ $output.BrowserlessNode.items[0].selector }} | CSS selector that produced the first item. |
{{ $output.BrowserlessNode.items[1].attributes[1].value }} | Value of the second attribute of the second item. |
{{ $output.BrowserlessNode.url }} | URL that was scraped. |
Node Policies & GuardRails
| Policy | Recommendation | Severity |
| Terms of service compliance | Always review the target website's robots.txt and terms of service before building scraping workflows. Scraping some sites may violate their policies. | High |
| URL validation | Validate and allowlist target domains to prevent SSRF when URLs come from user input. | High |
| Token storage | Store the API token in a workflow secret. | Critical |
| Selector fragility | CSS selectors break when sites redesign their markup. Build alerting for empty items arrays and monitor scrape results over time. | Medium |
| Rate limiting | Avoid hammering a target site — introduce a Delay node between loop iterations to respect crawl rates and avoid IP bans. | Medium |
Examples
Example 1 — E-commerce product data extraction
{
"operation": "scrape",
"baseUrl": "https://chrome.browserless.io",
"token": "{{ $env.BROWSERLESS_TOKEN }}",
"url": "{{ $input.productUrl }}",
"elements": [
{ "selector": "h1.product-name", "timeout": 8000 },
{ "selector": "[data-price]", "timeout": 8000 },
{ "selector": ".stock-badge", "timeout": 5000 }
],
"gotoOptions": { "waitUntil": "networkidle2", "timeout": 20000 },
"rejectResourceTypes": ["image", "media", "font", "stylesheet"],
"blockAds": true
}
Example 2 — Scrape a table of job listings
{
"operation": "scrape",
"baseUrl": "https://chrome.browserless.io",
"token": "{{ $env.BROWSERLESS_TOKEN }}",
"url": "https://jobs.example.com/listings?category={{ $input.category }}",
"elements": [
{ "selector": ".job-card .job-title", "timeout": 10000 },
{ "selector": ".job-card .company-name", "timeout": 10000 },
{ "selector": ".job-card .location", "timeout": 10000 }
],
"gotoOptions": { "waitUntil": "networkidle0", "timeout": 25000 }
}
Example 3 — Scrape with authentication cookies
{
"operation": "scrape",
"baseUrl": "https://chrome.browserless.io",
"token": "{{ $env.BROWSERLESS_TOKEN }}",
"url": "https://portal.example.com/account/usage",
"elements": [
{ "selector": ".usage-current", "timeout": 8000 },
{ "selector": ".usage-limit", "timeout": 8000 }
],
"cookies": [
{ "name": "auth_session", "value": "{{ $env.PORTAL_SESSION }}", "domain": "portal.example.com" }
],
"gotoOptions": { "waitUntil": "networkidle2", "timeout": 20000 }
}