Saltar al contenido
Herramienta avanzada5 credits

batch_scrape

Descargue muchas URL en una sola llamada con un grupo compartido de trabajadores. La solicitud es síncrona (devuelve los resultados terminados, no un identificador de trabajo) y cada URL vuelve con su propio estado, así que una página caída nunca hunde el lote. Los resultados también se almacenan durante 24 horas y se pueden releer con get_batch_results.

Casos de uso

Barridos de precios de la competencia

Extraiga el mismo campo CSS de cincuenta páginas de producto en una sola solicitud, en lugar de cincuenta viajes de ida y vuelta.

Comprobaciones de salud de enlaces

Envíe una lista de URL y lea http_status en cada entrada. Todo lo inalcanzable vuelve como failed con el motivo adjunto.

Inventarios de contenido

Alimente el lote con un sitemap y recopile todos los títulos y URL canónicas para una hoja de cálculo de auditoría.

Verificación tras el despliegue

Compruebe que un conjunto de páginas críticas sigue devolviendo 200 y sigue conteniendo el elemento que espera.

Construcción de conjuntos de datos

Recopile los primeros 5.000 caracteres del texto del body de una lista de URL como entrada para un pipeline posterior.

Recogida diferida

Ejecute el lote ahora y recupere después los resultados almacenados desde otro proceso con get_batch_results.

Endpoint

POST/api/v1/tools/batch_scrape
Auth Required
1 req/s en el plan Free
5 credits

Parameters

NameTypeRequiredDefaultDescription
urls
arrayRequired-
Las URL que se descargarán. Entre 1 y 50 entradas; una lista más larga se rechaza en lugar de truncarse.
Example: [{ "url": "https://example.com/widget-a", "id": "a" }]
batch_config
objectOptional-
Ajustes de ejecución del lote.
Example: { "concurrency": 5 }
extraction_template
objectOptional-
Campos que se extraerán de cada página del lote.
Example: { "fields": [{ "name": "price", "selector": ".price" }] }
output_config
objectOptional-
Se acepta y se ignora por completo. Las respuestas siempre son JSON con la forma que se muestra abajo; `format`, `include_metadata`, `include_errors` y `flatten_results` no tienen efecto.
Example: { "format": "json" }
options
objectOptional-
Se acepta y se ignora, salvo que `javascript_enabled: true` añade una línea explicativa a `notes`. `user_agent`, `follow_redirects`, `respect_robots_txt` y `rate_limit_per_domain` no cambian la descarga en la API REST alojada.
Example: { "javascript_enabled": false }
respect_robots
booleanOptionaltrue
Respeta el robots.txt de cada sitio de destino. Con el valor `true`, una URL que robots.txt no permita a `CrawlForge` se omite y el resto del lote continúa: la solicitud sigue devolviendo 200 con un conjunto de resultados parcial en lugar de un 403, y una URL omitida no se cobra. Póngalo en `false` solo para destinos con los que tenga su propio acuerdo: la respuesta incluye entonces una entrada `warnings` y la anulación queda registrada en su API key.
Example: true
max_inline_chars
numberOptional40000
Tamaño máximo del resultado que se devuelve en línea, en caracteres de su JSON (de 1.000 a 10.000.000). Por encima, la respuesta incluye `preview` (los primeros `max_inline_chars` caracteres del JSON formateado), `result_handle`, `total_chars`, `truncated: true` y `expires_at`, y [read_result](/docs/api-reference/tools/read-result) lee el resto por 1 credit por llamada. Los resultados almacenados se conservan 1 hora.
Example: 40000
redact_pii
boolean | objectOptionalfalse
Elimine los datos personales del texto que devuelve esta llamada, antes de que el resultado se almacene o se envíe de vuelta. Se aplica al texto de todas las URL del lote y a la copia almacenada que pagina [get_batch_results](/docs/api-reference/tools/get-batch-results). `true` es la forma abreviada de `{ mode: "fast" }`: las cuatro clases de expresiones regulares, etiquetadas. Siempre que pida redacción, la respuesta lleva `redaction: { entities, count, mode }` dentro de `data`, incluso cuando no hubo coincidencias (`count: 0`), de modo que «no se encontró nada» nunca se confunde con «se ignoró el parámetro»; una clase sin coincidencias se omite en lugar de informarse como `0`. La redacción se ejecuta **antes** de almacenar el resultado, así que un resultado grande que se lea después con [read_result](/docs/api-reference/tools/read-result) ya viene redactado. Dos límites deliberados: las direcciones (`url`, `link`, `href`, `canonical_url`) nunca se redactan, y los contadores derivados del texto (`content_length`, `word_count`, `character_count`) lo describen tal como se extrajo, antes de la redacción.
Example: true

Modelo de ejecución

Conviene saberlo antes de dimensionar un lote: este endpoint se ejecuta dentro de una función serverless de 30 segundos.

Síncrono
Una solicitud entra, resultados terminados salen. No hay un id de trabajo que consultar ni webhook: batch_id es una clave de recuperación, no un identificador de trabajo.
Presupuesto de descarga de 20 s
Las URL que no se hayan iniciado antes de agotarse el presupuesto vuelven con estado skipped y no se cobran. Cada descarga individual expira a los 8 s.
Los fallos son por URL
Un 404, un tiempo de espera agotado, un cuerpo ilegible, o un PDF u otro binario servido en lugar de una página marcan esa entrada como failed; el error de un binario remite a process_document. La llamada en sí sigue devolviendo 200.
Sin JavaScript
Las páginas se descargan, no se renderizan. Para páginas renderizadas en el cliente use scrape_with_actions o el servidor MCP de CrawlForge.

Ejemplos de solicitud

terminalBash
curl -X POST https://crawlforge.dev/api/v1/tools/batch_scrape \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      { "url": "https://example.com/widget-a", "id": "a" },
      { "url": "https://example.com/widget-b", "id": "b" }
    ],
    "batch_config": { "concurrency": 5 },
    "extraction_template": {
      "fields": [
        { "name": "price", "selector": ".price" },
        { "name": "canonical", "selector": "link[rel=canonical]", "attribute": "href" }
      ]
    }
  }'

Ejemplo de respuesta

200 OK3,140ms
{
"success": true,
"data": {
"batch_id": "fd599a27-9ca9-4022-9a57-b02af57c387b",
"total": 3,
"succeeded": 2,
"failed": 1,
"skipped": 0,
"results": [
{
"id": "a",
"url": "https://example.com/widget-a",
"status": "success",
"http_status": 200,
"title": "Widget A — Acme",
"text": "Widget A\n$24.00\nIn stock and ready to ship.",
"fields": {
"price": "$24.00",
"canonical": "https://example.com/widget-a",
"sku": null
},
"field_notes": [
"sku: xpath selectors are not supported on the hosted REST API — use a CSS selector"
]
},
{
"id": "b",
"url": "https://example.com/widget-b",
"status": "success",
"http_status": 200,
"title": "Widget B — Acme",
"text": "Widget B\n$31.50\nBackordered until March.",
"fields": {
"price": "$31.50",
"canonical": "https://example.com/widget-b",
"sku": null
}
},
{
"id": "c",
"url": "https://example.com/gone",
"status": "failed",
"http_status": 404,
"error": "HTTP 404"
}
],
"notes": [
"Results are stored for 24h and retrievable with get_batch_results (batch_id: fd599a27-9ca9-4022-9a57-b02af57c387b)."
],
"completed_at": "2026-08-27T02:09:44.001Z"
},
"credits_used": 15,
"credits_remaining": 990,
"processing_time": 3140
}
Field Descriptions
data.batch_idPáselo a [get_batch_results](/docs/api-reference/tools/get-batch-results) dentro de las 24 horas para releer el conjunto completo
data.totalEntradas enviadas: siempre igual a la longitud de `results`
data.skippedURL que el presupuesto de tiempo nunca alcanzó. No se cobran
data.results[].idSu `id` si lo proporcionó; en caso contrario, el índice del array como cadena
data.results[].status`success`, `failed` o `skipped`: compruebe esto en cada entrada, no el estado HTTP
data.results[].textTexto visible del body con los scripts y estilos eliminados, una línea por elemento de bloque, cortado a 5.000 caracteres
data.results[].fieldsUna clave por cada campo de la plantilla. `null` significa que el selector no coincidió con nada
data.results[].field_notesSolo aparece cuando un campo no se pudo aplicar: un selector xpath, o CSS que el analizador rechazó
data.notesObservaciones a nivel de lote, incluido todo lo que haya pedido y que la API alojada no hace
credits_used5 por cada URL intentada: aquí 3 URL, ninguna omitida, así que 15

Manejo de errores

Lote no válido (400 Bad Request)

VALIDATION_ERROR. Se produce con un array urls vacío, más de 50 entradas, una URL mal formada o un concurrency fuera de 1-10. No se descarga nada y no se cobra nada.

Almacenamiento no disponible (503 Service Unavailable)

STORAGE_UNAVAILABLE. Los resultados se guardan antes de facturar, así que si no se puede acceder a ese almacén el lote se rechaza en lugar de ejecutarse y perderse. No se cobra nada. Reintente.

El lote falló (500 Internal Server Error)

TOOL_ERROR. Un fallo inesperado. Los problemas de una URL concreta nunca aparecen aquí: se muestran como entradas failed dentro de una respuesta 200.

No permitido por robots.txt (sin error: la URL se omite)

Una URL que robots.txt no permite a CrawlForge se deja fuera del lote en lugar de hacerlo fallar: la llamada sigue devolviendo 200 con un conjunto de resultados parcial y la URL omitida no se cobra, así que revise los resultados por URL antes de dar el lote por completo. Establezca respect_robots: false para anularlo en destinos con los que tenga su propio acuerdo: la anulación queda registrada en su API key. La anulación no alcanza a un host incluido en la lista de exclusión permanente de CrawlForge: ese se rechaza sea cual sea el valor de respect_robots, y se omite y no se cobra igual que los demás, con el host indicado en el campo error de ese resultado. data.notes resume cuántas URLs se omitieron y por qué.

Costo en credits

5 credits
5 credits por cada URL intentada
Un lote de 10 URL cuesta 50 credits. Las URL que vuelven como skipped porque se agotó el presupuesto de tiempo no se cobran, y un lote rechazado en la validación no cuesta nada. Las URL fallidas sí se cobran: la descarga se intentó.

Qué incluye:

Hasta 50 URL por llamada, descargadas de forma concurrente

Título y texto del body por página (5.000 caracteres)

Extracción de campos CSS con notas por campo

Estado y código HTTP por URL

Almacenamiento de resultados durante 24 horas para get_batch_results

Recomendaciones por plan:

Plan Free: 1,000 credits de prueba por única vez = 200 URL

Plan Hobby: 5,000 credits = 1,000 URL ($19/mo)

Plan Professional: 100,000 credits = 20,000 URL ($99/mo)

Herramientas relacionadas