> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olostep.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scrape

> Convierte cualquier URL en Markdown, HTML, capturas de pantalla, PDFs o JSON estructurado listo para LLM.

A través del endpoint `/v1/scrapes` de Olostep puedes extraer Markdown, HTML, texto, capturas de pantalla o JSON estructurado amigable para LLM de cualquier URL en tiempo real.

* Genera markdown limpio, datos estructurados, capturas de pantalla o html
* Extrae JSON a través de [Parsers](/features/structured-content/parsers) o [extracción LLM](/features/structured-content/llm-extraction)
* Maneja contenido dinámico: sitios renderizados con js, flujos de inicio de sesión mediante acciones, PDFs

Para detalles del API, consulta la [Referencia del API del Endpoint de Scrape](/api-reference/scrapes/create).

## Raspado de una URL

Usa el endpoint `/v1/scrapes` para raspar una sola URL y elegir formatos de salida.

### Instalación

<CodeGroup>
  ```python Python theme={null}
  pip install olostep
  ```

  ```javascript Node theme={null}
  npm install olostep
  ```

  ```bash cURL theme={null}
  # curl está disponible por defecto en macOS, Linux y Windows
  ```

  ```javascript Node (API) theme={null}
  npm install node-fetch
  ```

  ```bash Python (API) theme={null}
  pip install requests
  ```
</CodeGroup>

### Uso

Puedes usar el endpoint para raspar una sola URL y elegir formatos de salida. Los parámetros obligatorios son `url_to_scrape` y `formats`.

Algunos otros parámetros comunes son `wait_before_scraping` (en milisegundos), `remove_css_selectors` (por defecto, ninguno, o un array de selectores), y `country`.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://en.wikipedia.org/wiki/Alexander_the_Great",
      formats=["markdown", "html"],
  )

  print(result.markdown_content)
  print(result.html_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://en.wikipedia.org/wiki/Alexander_the_Great',
    formats: ['markdown', 'html'],
  })

  console.log(result.markdown_content)
  console.log(result.html_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
      "formats": ["markdown", "html"]
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://en.wikipedia.org/wiki/Alexander_the_Great" \
    --formats markdown,html
  ```

  ```js Node (API) theme={null}
  const endpoint = 'https://api.olostep.com/v1/scrapes'
  const payload = {
    url_to_scrape: 'https://en.wikipedia.org/wiki/Alexander_the_Great',
    formats: ['markdown', 'html']
  }
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <YOUR_API_KEY>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  })
  const data = await res.json()
  console.log(data)
  ```

  ```python Python (API) theme={null}
  import requests
  import json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
      "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
      "formats": ["markdown", "html"]
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }

  response = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```
</CodeGroup>

### Respuesta

El API devuelve un objeto `scrape` en respuesta.

El `scrape` tiene algunas propiedades como `id` y `result`.

El objeto `result` tiene los siguientes campos (según el parámetro `formats` algunos podrían ser nulos):

* `html_content`: el contenido HTML de la página. Pasa `formats: ["html"]` para obtener esto.
* `markdown_content`: el contenido MD de la página. Pasa `formats: ["markdown"]` para obtener esto.
* `text_content`: el contenido de texto de la página. Pasa `formats: ["text"]` para obtener esto.
* `json_content`: el contenido JSON de la página. Pasa `formats: ["json"]` para obtener esto y también proporciona un parámetro `parser` o `llm_extract`.
* `screenshot_hosted_url`: la URL alojada de la captura de pantalla.
* `html_hosted_url`: la URL alojada del contenido HTML
* `markdown_hosted_url`: la URL alojada del contenido Markdown
* `json_hosted_url`: la URL alojada del contenido JSON
* `text_hosted_url`: la URL alojada del contenido de texto
* `links_on_page`: los enlaces en la página
* `page_metadata`: los metadatos de la página

```json theme={null}
{
  "id": "scrape_6h89o8u1kt",
  "object": "scrape",
  "created": 1745673871,
  "metadata": {},
  "retrieve_id": "6h89o8u1kt",
  "url_to_scrape": "https://en.wikipedia.org/wiki/Alexander_the_Great",
  "result": {
    "html_content": "<html...",
    "markdown_content": "## Alexander the Great...",
    "text_content": null,
    "json_content": null,
    "screenshot_hosted_url": null,
    "html_hosted_url": "https://olostep-storage.s3.us-east-1.amazonaws.com/text_6h89o8u1kt.txt",
    "markdown_hosted_url": "https://olostep-storage.s3.us-east-1.amazonaws.com/markDown_6h89o8u1kt.txt",
    "json_hosted_url": null,
    "text_hosted_url": null,
    "links_on_page": [],
    "page_metadata": { "status_code": 200, "title": "" }
  }
}
```

## Caché

Para optimizar la velocidad, Olostep ofrece una capa de caché compartida opcional para resultados de HTML, Markdown, texto y JSON analizado.

### Cómo funciona

Cuando se solicita un raspado, Olostep verifica si ya existe un raspado coincidente con los mismos parámetros. Si se encuentra una coincidencia lo suficientemente reciente, el contenido se sirve instantáneamente desde el almacenamiento de Olostep sin iniciar un nuevo raspado del navegador.

* **Caché compartida:** La caché se comparte globalmente. Si otra solicitud raspó exactamente la misma URL con la misma configuración dentro de tu ventana de frescura, te beneficias de la aceleración.
* **El post-procesamiento sigue en vivo:** Operaciones como `llm_extract` y filtros `links_on_page` se ejecutan *en el momento* sobre el documento en caché. Solo almacenas en caché la recuperación de la página principal, manteniendo tus extracciones estructuradas dinámicas.

### Frescura y `max_age`

Por defecto, el API de producción siempre realiza un raspado en vivo para garantizar la precisión en tiempo real. Puedes optar por el almacenamiento en caché usando el parámetro `max_age`.

| Parámetro | Tipo      | Predeterminado | Descripción                                                                                                                                   |
| --------- | --------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `max_age` | `integer` | `0`            | Edad aceptable del contenido en **segundos**. Si existe una copia en caché y es más reciente que `max_age` segundos, se sirve desde la caché. |

* **Comportamiento predeterminado del API (`max_age: 0`):** Cada solicitud al API desencadena un raspado nuevo.
* **Comportamiento predeterminado del Playground:** En el playground del panel, `max_age` predetermina a 24 horas (`86400` segundos) para evitar raspados redundantes y ahorrar créditos mientras construyes y pruebas.
* **Edad máxima:** La caché tiene un límite máximo de **7 días** (`604800` segundos). Cualquier `max_age` solicitado por encima de este límite volverá a un máximo de 7 días.

### Ejemplos de uso

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  # Optar por el almacenamiento en caché: Aceptar resultados de hasta 1 día (86400 segundos) de antigüedad
  result = client.scrapes.create(
      url_to_scrape="https://example.com",
      formats=["markdown"],
      max_age=86400
  )
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  // Optar por el almacenamiento en caché: Aceptar resultados de hasta 1 día (86400 segundos) de antigüedad
  const result = await client.scrapes.create({
    url: 'https://example.com',
    formats: ['markdown'],
    maxAge: 86400,
  })
  ```

  ```bash cURL theme={null}
  # Optar por el almacenamiento en caché: Aceptar resultados de hasta 1 hora (3600 segundos) de antigüedad
  curl -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://example.com",
      "formats": ["markdown"],
      "max_age": 3600
    }'
  ```

  ```js Node (API) theme={null}
  const endpoint = 'https://api.olostep.com/v1/scrapes'
  const payload = {
    url_to_scrape: 'https://example.com',
    formats: ['markdown'],
    max_age: 86400 // Aceptar resultados de hasta 1 día (86400 segundos) de antigüedad
  }
  const res = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <YOUR_API_KEY>',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  })
  const data = await res.json()
  console.log(data)
  ```

  ```python Python (API) theme={null}
  import requests
  import json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
      "url_to_scrape": "https://example.com",
      "formats": ["markdown"],
      "max_age": 86400 # Aceptar resultados de hasta 1 día (86400 segundos) de antigüedad
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }

  response = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(response.json(), indent=2))
  ```
</CodeGroup>

### ¿Cuándo se omite la caché?

La caché se omite automáticamente (forzando un raspado en vivo) para funciones que requieren sesiones únicas, salidas visuales en tiempo real o manejo de archivos personalizados:

* **Sesiones interactivas:** Solicitudes que usan `session_id` o cargan un `context` de navegador personalizado.
* **Visuales:** Herramientas de visualización y capturas de pantalla (`htmlVisualizer`).
* **Tipos de archivos especiales:** Descargas de archivos binarios o renderizado de PDF en bruto.
* **Depuración y Red:** Captura de `network_calls` o uso de trabajos de parser asíncronos.

## Extracción de enlaces

Pasa un objeto `links_on_page` en la solicitud para recopilar los enlaces encontrados en la página. Todos los enlaces se devuelven como URLs absolutas.

```json theme={null}
"links_on_page": {
  "include_links": ["/blog/*"],
  "exclude_links": ["*.pdf"],
  "query_to_order_links_by": "pricing"
}
```

* `include_links` / `exclude_links`: patrones glob que se comparan con la **ruta** de la URL de cada enlace.
* `query_to_order_links_by`: reordena los enlaces devueltos por relevancia a este texto.

<Note>
  Los patrones glob coinciden con segmentos de ruta. Un solo `*` **no** cruza `/`, por lo que `"/blog/*"` coincide con `"/blog/post-1"` pero **no** con el índice `"/blog"` en sí mismo — y nunca coincide con `"/blog?tag=x"` porque las cadenas de consulta no son parte de la ruta. Para incluir también el índice, usa `"/blog*"` o `"{/blog,/blog/**}"`.
</Note>

## Formatos de Scrape

Elige uno o más formatos de salida a través de `formats`:

* `markdown`: markdown amigable para LLM
* `html`: HTML limpio
* `text`: texto plano
* `json`: salida estructurada (a través de parser o llm\_extract)
* `raw_pdf`: bytes de PDF en bruto extraídos a URL alojada
* `screenshot`: configurado a través de acciones para capturar una captura de pantalla y devolver una URL alojada

Las claves de salida se devuelven dentro de `result` como campos `*_content` y también un `*_hosted_url`.

## Extraer datos estructurados

Puedes extraer JSON estructurado de dos maneras: usando Parsers o extracción LLM.

### Usando un Parser (recomendado para escala)

Define `formats: ["json"]` y proporciona un `id` de parser.

<CodeGroup>
  ```python Python theme={null}
  from olostep import Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
      formats=["json"],
      parser="@olostep/google-search",
  )

  print(result.json_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://www.google.com/search?q=alexander+the+great&gl=us&hl=en',
    formats: ['json'],
    parser: '@olostep/google-search',
  })

  console.log(result.json_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
      "formats": ["json"],
      "parser": {"id": "@olostep/google-search"}
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en" \
    --formats json \
    --payload-json '{"parser":{"id":"@olostep/google-search"}}'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://www.google.com/search?q=alexander+the+great&gl=us&hl=en',
      formats: ['json'],
      parser: { id: '@olostep/google-search' }
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://www.google.com/search?q=alexander+the+great&gl=us&hl=en",
    "formats": ["json"],
    "parser": { 
      "id": "@olostep/google-search" 
    }
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>", 
      "Content-Type": "application/json"
  }

  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

Olostep tiene algunos parsers preconstruidos para [sitios web populares](https://www.olostep.com/store) pero también puedes crear tus propios parsers a través del panel o pedirle a nuestro equipo que lo haga por ti.

Los parsers son auto-reparables y se actualizarán a la última versión del sitio web.

### Usando extracción LLM (esquema y/o prompt)

Proporciona `llm_extract` con un Esquema JSON (`schema`) y/o una instrucción en lenguaje natural (`prompt`). Puedes pasar ambos parámetros, pero si ambos se proporcionan, `schema` tiene prioridad.

En cambio, si solo pasas un `prompt`, el LLM extraerá los datos basándose en el prompt y decidirá la estructura de datos por sí mismo.

<CodeGroup>
  ```python Python theme={null}
  from olostep import LLMExtract, Olostep

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://www.berklee.edu/events/stefano-marchese-friends",
      formats=["markdown", "json"],
      llm_extract=LLMExtract(
          schema={
              "event": {
                  "type": "object",
                  "properties": {
                      "title": {"type": "string"},
                      "date": {"type": "string"},
                      "description": {"type": "string"},
                      "venue": {"type": "string"},
                      "address": {"type": "string"},
                      "start_time": {"type": "string"},
                  },
              }
          }
      ),
  )

  print(result.json_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://www.berklee.edu/events/stefano-marchese-friends',
    formats: ['markdown', 'json'],
    llmExtract: {
      schema: {
        event: {
          type: 'object',
          properties: {
            title: { type: 'string' },
            date: { type: 'string' },
            description: { type: 'string' },
            venue: { type: 'string' },
            address: { type: 'string' },
            start_time: { type: 'string' },
          },
        },
      },
    },
  })

  console.log(result.json_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://www.berklee.edu/events/stefano-marchese-friends",
      "formats": ["json"],
      "llm_extract": {
        "prompt": "Extract the event title, date, description, venue, address, and start time from the page."
      }
    }'
  ```

  ```bash CLI theme={null}
  olostep scrape "https://www.berklee.edu/events/stefano-marchese-friends" \
    --formats json \
    --payload-json '{"llm_extract":{"prompt":"Extract the event title, date, description, venue, address, and start time from the page."}}'
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://www.berklee.edu/events/stefano-marchese-friends',
      formats: ['json'],
      llm_extract: {
        prompt: 'Extract the event title, date, description, venue, address, and start time from the page.'
      }
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://www.berklee.edu/events/stefano-marchese-friends",
    "formats": ["markdown", "json"],
    "llm_extract": {
      "schema": {
        "event": {
          "type": "object",
          "properties": {
            "title": {"type": "string"},
            "date": {"type": "string"},
            "description": {"type": "string"},
            "venue": {"type": "string"},
            "address": {"type": "string"},
            "start_time": {"type": "string"}
          }
        }
      }
    }
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>",
      "Content-Type": "application/json"
  }
  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

Nota: `result.json_content` devuelve un JSON en forma de cadena. Analízalo en tu código si necesitas un objeto.

**Precios:** `llm_extract` cuesta 10 créditos por raspado. Para reducir el costo, puedes traer tus propias claves de API o habilitar precios basados en uso. Contacta a [info@olostep.com](mailto:info@olostep.com) para obtener acceso.

## Extraer enlaces en la página

Con la opción `links_on_page`, puedes extraer todos los enlaces presentes en la página que raspas. Acepta los siguientes parámetros para ayudar a filtrar y ordenar los enlaces extraídos:

* `absolute_links` (booleano, por defecto: `true`): Cuando es verdadero, devuelve URLs completas (por ejemplo, `https://example.com/page`) en lugar de rutas relativas (por ejemplo, `/page`).
* `query_to_order_links_by` (cadena): Ordena los enlaces devueltos por su similitud con el texto de consulta proporcionado, priorizando las coincidencias más relevantes primero.
* `include_links` (array de cadenas): Filtra los enlaces extraídos usando patrones glob. Usa patrones como `*.pdf` para coincidir con extensiones de archivo, `/blog/*` para rutas específicas, o URLs completas como `https://example.com/*`. Soporta comodines (`*`), clases de caracteres (`[a-z]`), y alternancia (`{pattern1,pattern2}`).
* `exclude_links` (array de cadenas): Excluye enlaces específicos usando patrones glob, siguiendo la misma sintaxis que `include_links`.

## Interactuar con la página con Acciones

Realiza acciones antes de raspar para interactuar con sitios dinámicos. Acciones soportadas:

* `wait` con `milliseconds`
* `click` con `selector`
* `fill_input` con `selector` y `value`
* `scroll` con `direction` y `amount`

A menudo es útil usar `wait` antes/después de otras acciones para permitir que la página se cargue.

### Ejemplo

<CodeGroup>
  ```python Python theme={null}
  from olostep import FillInputAction, Olostep, WaitAction

  client = Olostep(api_key="YOUR_REAL_KEY")

  result = client.scrapes.create(
      url_to_scrape="https://example.com/login",
      formats=["markdown"],
      actions=[
          FillInputAction(selector="input[type=email]", value="john@example.com"),
          WaitAction(milliseconds=500),
          FillInputAction(selector="input[type=password]", value="secret"),
          {"type": "click", "selector": "button[type=\"submit\"]"},
          WaitAction(milliseconds=1500),
      ],
  )

  print(result.markdown_content)
  ```

  ```js Node theme={null}
  import Olostep from 'olostep'

  const client = new Olostep({ apiKey: 'YOUR_REAL_KEY' })

  const result = await client.scrapes.create({
    url: 'https://example.com/login',
    formats: ['markdown'],
    actions: [
      { type: 'fill_input', selector: 'input[type=email]', value: 'john@example.com' },
      { type: 'wait', milliseconds: 500 },
      { type: 'fill_input', selector: 'input[type=password]', value: 'secret' },
      { type: 'click', selector: 'button[type="submit"]' },
      { type: 'wait', milliseconds: 1500 },
    ],
  })

  console.log(result.markdown_content)
  ```

  ```bash cURL theme={null}
  curl -s -X POST "https://api.olostep.com/v1/scrapes" \
    -H "Authorization: Bearer $OLOSTEP_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url_to_scrape": "https://example.com/login",
      "formats": ["markdown"],
      "actions": [
        { "type": "fill_input", "selector": "input[type=email]", "value": "john@example.com" },
        { "type": "wait", "milliseconds": 500 },
        { "type": "fill_input", "selector": "input[type=password]", "value": "secret" },
        { "type": "click", "selector": "button[type=\"submit\"]" },
        { "type": "wait", "milliseconds": 1500 }
      ]
    }'
  ```

  ```bash CLI theme={null}
  # Para opciones complejas como acciones, usa --payload-file con un archivo JSON
  olostep scrape "https://example.com/login" \
    --formats markdown \
    --payload-file actions.json

  # Donde actions.json contiene:
  # {
  #   "actions": [
  #     {"type": "fill_input", "selector": "input[type=email]", "value": "john@example.com"},
  #     {"type": "wait", "milliseconds": 500},
  #     {"type": "fill_input", "selector": "input[type=password]", "value": "secret"},
  #     {"type": "click", "selector": "button[type=\"submit\"]"},
  #     {"type": "wait", "milliseconds": 1500}
  #   ]
  # }
  ```

  ```js Node (API) theme={null}
  const res = await fetch('https://api.olostep.com/v1/scrapes', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer <YOUR_API_KEY>', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url_to_scrape: 'https://example.com/login',
      formats: ['markdown'],
      actions: [
        { type: 'fill_input', selector: 'input[type=email]', value: 'john@example.com' },
        { type: 'wait', milliseconds: 500 },
        { type: 'fill_input', selector: 'input[type=password]', value: 'secret' },
        { type: 'click', selector: 'button[type="submit"]' },
        { type: 'wait', milliseconds: 1500 }
      ]
    })
  })
  console.log(await res.json())
  ```

  ```python Python (API) theme={null}
  import requests, json

  endpoint = "https://api.olostep.com/v1/scrapes"
  payload = {
    "url_to_scrape": "https://example.com/login",
    "formats": ["markdown"],
    "actions": [
      {"type": "fill_input", "selector": "input[type=email]", "value": "john@example.com"},
      {"type": "wait", "milliseconds": 500},
      {"type": "fill_input", "selector": "input[type=password]", "value": "secret"},
      {"type": "click", "selector": "button[type=\"submit\"]"},
      {"type": "wait", "milliseconds": 1500}
    ]
  }
  headers = {
      "Authorization": "Bearer <YOUR_API_KEY>", 
      "Content-Type": "application/json"
  }
  res = requests.post(endpoint, json=payload, headers=headers)
  print(json.dumps(res.json(), indent=2))
  ```
</CodeGroup>

La respuesta incluirá cualquier formato solicitado (por ejemplo, `markdown_content`).

## Casos de Uso

A continuación se presentan algunas aplicaciones prácticas de clientes que utilizan el endpoint `/scrapes`.

### Análisis de Contenido e Investigación

* **Análisis Competitivo**: Extrae detalles de productos, precios y características de sitios web de la competencia
* **Investigación de Mercado**: Analiza páginas de aterrizaje, descripciones de productos y testimonios de clientes
* **Investigación Académica**: Recopila datos específicos de publicaciones científicas o portales de investigación
* **Documentación Legal**: Extrae estudios de caso, regulaciones o precedentes legales de sitios web oficiales

### Comercio Electrónico y Retail

* **Estrategias de Precios Dinámicos**: Obtén precios de productos en tiempo real de tiendas competidoras
* **Gestión de Información de Productos**: Extrae especificaciones detalladas y descripciones
* **Monitoreo de Stock/Inventario**: Verifica la disponibilidad de productos en otros minoristas
* **Análisis de Reseñas**: Recopila comentarios de consumidores y sentimientos para productos específicos

### Marketing y Creación de Contenido

* **Curación de Contenido**: Extrae artículos relevantes y publicaciones de blog para boletines
* **Análisis SEO**: Examina el uso de palabras clave, descripciones meta y estructura de página de los competidores
* **Generación de Leads**: Extrae información de contacto de directorios de empresas o páginas de compañías
* **Investigación de Influencers**: Recopila métricas de compromiso y estilos de contenido de perfiles de influencers
* **Generación Personalizada de Redes Sociales**: Crea marketing en redes sociales impulsado por IA analizando sitios web de clientes

### Aplicaciones de Datos

* **Recolección de Datos de Entrenamiento de IA**: Recopila ejemplos específicos para modelos de aprendizaje automático
* **Construcción de Base de Conocimiento Personalizada**: Extrae documentación o instrucciones de sitios de software
* **Archivos de Datos Históricos**: Preserva el contenido del sitio web en puntos específicos en el tiempo
* **Extracción de Datos Estructurados**: Transforma contenido web en conjuntos de datos formateados para análisis

### Monitoreo y Alertas

* **Monitoreo de Cumplimiento Regulatorio**: Rastrea cambios en sitios web legales o regulatorios
* **Gestión de Crisis**: Monitorea sitios de noticias para menciones de eventos o organizaciones específicas
* **Seguimiento de Eventos**: Extrae detalles sobre eventos próximos de sitios de lugares u organizadores
* **Monitoreo de Estado de Servicio**: Verifica páginas de estado de servicio para plataformas o herramientas específicas

### Publicación y Medios

* **Agregación de Noticias**: Extrae noticias de última hora de fuentes oficiales
* **Monitoreo de Medios**: Rastrea temas específicos en sitios de noticias
* **Verificación de Contenido**: Extrae información para verificar afirmaciones o declaraciones
* **Extracción Multimedia**: Recopila videos, imágenes o audio incrustados para bibliotecas de medios

### Aplicaciones Financieras

* **Investigación de Inversiones**: Extrae estados financieros o informes anuales de sitios web de empresas
* **Indicadores Económicos**: Recopila datos económicos de sitios web gubernamentales o de instituciones financieras
* **Datos de Criptomonedas**: Extrae información de precios en tiempo real y capitalización de mercado
* **Análisis de Noticias Financieras**: Monitorea sitios de noticias financieras para señales de mercado específicas

### Aplicaciones Técnicas

* **Extracción de Documentación de API**: Recopila documentación técnica para referencia
* **Pruebas de Integración**: Extrae elementos del sitio web para verificar integraciones de terceros
* **Pruebas de Accesibilidad**: Analiza la estructura del sitio web para cumplir con los estándares de accesibilidad
* **Creación de Archivos Web**: Captura el contenido completo del sitio web para preservación histórica

### Escenarios de Integración

* **Sistemas CRM**: Mejora los perfiles de clientes con datos de sitios web de empresas o Linkedin
* **Sistemas de Gestión de Contenidos**: Importa contenido externo relevante
* **Herramientas de Inteligencia de Negocios**: Complementa datos internos con información de mercado externa
* **Software de Gestión de Proyectos**: Extrae especificaciones o requisitos de sitios web de clientes
* **Dashboards Personalizados**: Muestra datos extraídos junto a métricas internas

## Manejo de Errores

Todos los errores siguen una forma de sobre compartida. Verifica `error.type` y `error.code` para ramificar programáticamente:

```json theme={null}
{
  "id": "error_abc123",
  "object": "error",
  "created": 1745673871,
  "url": "https://example.com",
  "metadata": {},
  "error": {
    "type": "...",
    "code": "...",
    "message": "..."
  }
}
```

| HTTP | `error.type`            | `error.code`            | Significado                                                                                                          |
| ---- | ----------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| 400  | `invalid_request_error` | `dns_resolution_failed` | El dominio no existe o la URL tiene un error tipográfico.                                                            |
| 400  | `invalid_request_error` | `invalid_url`           | La URL está mal formada.                                                                                             |
| 502  | `invalid_request_error` | `tls_error`             | El sitio web tiene un certificado TLS/SSL inválido o incompatible. `error.detail` lleva el código SSL de bajo nivel. |
| 504  | `request_timeout`       | `scrape_poll_timeout`   | El raspado no se completó dentro del presupuesto de espera de \~55 segundos.                                         |

### Falla de DNS (400)

El dominio no se resuelve. Verifica la URL por errores tipográficos.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "dns_resolution_failed",
    "message": "La URL contiene un error tipográfico, o el dominio no existe."
  }
}
```

### Error TLS/SSL (502)

El sitio web de destino tiene una configuración HTTPS rota o incompatible. `error.detail` proporciona el código de error SSL específico para diagnósticos; `error.code` siempre es `tls_error`.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "tls_error",
    "detail": "err_ssl_tlsv1_alert_internal_error",
    "message": "El sitio web cerró o rechazó el handshake TLS. El servidor puede estar mal configurado o usar una versión SSL/TLS no compatible."
  }
}
```

### Tiempo de espera de la solicitud (504)

El raspado no se completó dentro del presupuesto de espera. La página puede ser lenta, estar protegida contra bots o estar temporalmente no disponible. Esta respuesta es segura para reintentar.

```json theme={null}
{
  "error": {
    "type": "request_timeout",
    "code": "scrape_poll_timeout",
    "message": "La solicitud agotó el tiempo de espera mientras se esperaba el resultado del raspado. La página puede ser lenta, bloqueada para nuestros fetchers, o estar temporalmente no disponible."
  }
}
```

## Precios

El raspado cuesta 1 crédito por defecto. Si también pasas [parsers](/features/structured-content/parsers), los costos varían según el parser (1-5 créditos). Si usas [extracción LLM](/features/structured-content/llm-extraction), cuesta 10 créditos.
