> For the complete documentation index, see [llms.txt](/llms.txt)

# Scrape API

Extract structured JSON from a fully rendered page using CSS selectors. Each request must include a `url` and an `elements` array that lists the selectors you want to capture.

**Endpoint**
- Method: `POST`
- Path: `/scrape`
- Auth: `token` query parameter (`?token=`)
- Content-Type: `application/json`
- Response: `application/json`

See the [OpenAPI reference](/open-api/chrome-scrape) for complete details.

- A Browserless API token from your [account dashboard](https://browserless.io/account/)

## Quickstart

  
**cURL:**

```sh
curl --request POST \
  --url 'https://production-sfo.browserless.io/scrape?token=YOUR_API_TOKEN_HERE' \
  --header 'content-type: application/json' \
  --data '{
  "url": "https://browserless.io/",
  "elements": [
    {
      "selector": "h1"
    }
  ]
}'
```

  
  
**Javascript:**

```js
const TOKEN = "YOUR_API_TOKEN_HERE";
const url = `https://production-sfo.browserless.io/scrape?token=${TOKEN}`;
const headers = {
  "Cache-Control": "no-cache",
  "Content-Type": "application/json"
};

const data = {
  url: "https://browserless.io/",
  elements: [
    { selector: "h1" }
  ]
};

const scrapeContent = async () => {
  const response = await fetch(url, {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(data)
  });

  const result = await response.json();
  console.log(result);
};

scrapeContent();
```

  
  
**Python:**

```python
import requests

TOKEN = "YOUR_API_TOKEN_HERE"
url = f"https://production-sfo.browserless.io/scrape?token={TOKEN}"
headers = {
    "Cache-Control": "no-cache",
    "Content-Type": "application/json"
}

data = {
    "url": "https://browserless.io/",
    "elements": [
        { "selector": "h1" }
    ]
}

response = requests.post(url, headers=headers, json=data)
result = response.json()

print(result)
```

  

**Response**

```json
{
  "data": [
    {
      "results": [
        {
          "attributes": [
            { "name": "class", "value": "..." }
          ],
          "height": 120,
          "html": "Headless browser automation, without the hosting headaches",
          "left": 32,
          "text": "Headless browser automation, without the hosting headaches",
          "top": 196,
          "width": 736
        }
      ],
      "selector": "h1"
    }
  ]
}
```

## How scraping works

The API uses `document.querySelectorAll` under the hood. Browserless loads the page, runs client-side JavaScript, and then waits (up to 30 seconds by default) for your selectors before scraping. Use more specific selectors to narrow down results.

## Bot detection troubleshooting

If scraped results are empty or missing expected elements, the site may be blocking automation. Signs include:

- Empty or missing `results` arrays in the response
- Partial page content missing key elements
- Different content compared to a regular browser
- Blocked requests or access denied messages

The [/unblock API](/rest-apis/unblock) is specifically designed to bypass bot detection mechanisms like Datadome and passive CAPTCHAs.

## Configuration options

The `/scrape` API supports shared [request configuration options](/rest-apis/request-configuration) that apply across REST endpoints. In addition to `elements` and selectors, you can:

- [**Waiting for things**](/rest-apis/request-configuration#waiting-for-things): Wait for [events](/rest-apis/request-configuration#waitforevent), [functions](/rest-apis/request-configuration#waitforfunction), [selectors](/rest-apis/request-configuration#waitforselector), or [timeouts](/rest-apis/request-configuration#waitfortimeout) before scraping
- [**Navigation options**](/rest-apis/request-configuration#navigation-options): Customize navigation behavior with `gotoOptions`
- [**Rejecting undesired requests**](/rest-apis/request-configuration#rejecting-undesired-requests): Block resources with `rejectResourceTypes` and `rejectRequestPattern`
- [**Continue on error**](/rest-apis/request-configuration#continue-on-error): Use `bestAttempt` to continue when async events fail or time out

## FAQ & Troubleshooting

<details>
<summary>How does the Browserless /scrape API work?</summary>

Send a POST request with a URL and an elements array defining CSS selectors and what to extract (text, HTML, attributes). The API returns structured JSON matching your selectors.

</details>

<details>
<summary>Can I scrape multiple elements from a single page?</summary>

Yes. The elements array accepts multiple selector definitions. Each entry can target a different element and extract different properties, all returned in a single API response.

</details>

<details>
<summary>Does the /scrape API handle JavaScript-rendered content?</summary>

Yes. The API renders the page in a real headless browser, waits for JavaScript to execute, and then applies your selectors. You can also add custom wait conditions to handle lazy-loaded content.

</details>

## Next steps

  <a href="/rest-apis/intro" className="next-step-card-link">
    
      <h3 className="next-step-card-title">REST API overview</h3>
      introduction to all available endpoints
    
  </a>
  <a href="/rest-apis/api-playground" className="next-step-card-link">
    
      <h3 className="next-step-card-title">API playground</h3>
      test endpoints interactively
    
  </a>