Saltar al contenido
Herramienta básica1 credit

extract_text

Extraiga texto limpio y legible de HTML con análisis inteligente. Elimina automáticamente scripts, estilos y contenido repetitivo mientras conserva el contenido de texto principal.

Casos de uso

Extracción de artículos para LLMs

Extraiga texto limpio de artículos para resumir, analizar o procesar con IA

Análisis de contenido

Obtenga texto plano para conteo de palabras, análisis de legibilidad o detección de sentimiento

Texto limpio para resúmenes

Elimine el ruido HTML antes de pasarlo a los modelos de resumen

Eliminación de contenido repetitivo

Elimine anuncios, navegación y otros elementos que no son contenido

Endpoint

POST/api/v1/tools/extract_text
Auth Required
1 req/s en el plan Free
1 credit

Parameters

NameTypeRequiredDefaultDescription
html
stringOptional-
Contenido HTML del que extraer texto (proporcione html o url)
Example: <html><body><h1>Hello World</h1></body></html>
url
stringOptional-
URL para obtener y extraer texto (proporcione html o url)
Example: https://example.com/article
selector
stringOptional-
Selector CSS para apuntar a elementos específicos (predeterminado: toda la página)
Example: article, .content, #main
clean
booleanOptionaltrue
Reduce los espacios repetidos dentro de cada línea y elimina las líneas en blanco; se conservan los saltos de línea entre bloques. Solo se aplica con `output_format: "text"`.
Example: true
preserve_links
booleanOptionalfalse
Añade cada enlace como una línea `text (href)` después del texto extraído. Solo en la API REST —la herramienta MCP no tiene esta opción— y solo se aplica con `output_format: "text"`.
Example: false
preserve_formatting
booleanOptionalfalse
Conserva los saltos de párrafo y de encabezado del HTML de origen. Solo en la API REST —la herramienta MCP no tiene esta opción— y solo se aplica con `output_format: "text"`.
Example: false
max_length
numberOptional-
Longitud máxima del texto o markdown devuelto. Un resultado más largo se corta y termina en `...`, y `data.truncated` es `true`; `data.truncated` siempre está presente y vale `false` cuando no se cortó nada.
Example: 5000
output_format
stringOptionaltext
`"text"` (predeterminado) devuelve `data.text`, una línea por elemento de bloque: `<h1>Hi</h1><p>there</p>` se lee `Hi\nthere`. `"markdown"` devuelve `data.markdown` en su lugar: los elementos seleccionados (o el body) convertidos a Markdown con Turndown. En ambos casos `data` incluye `output_format`, `word_count` y `char_count`, con los mismos nombres que usa la herramienta MCP; un resultado markdown se cuenta sin sus caracteres de sintaxis Markdown (`#`, `*`, `_`, `[`, `]` y comillas invertidas). `clean`, `preserve_links` y `preserve_formatting` solo se aplican al texto; `max_length` se aplica a ambos.
Example: markdown
respect_robots
booleanOptionaltrue
Respeta el robots.txt del sitio de destino. Con el valor `true`, una ruta que robots.txt no permita a `CrawlForge` se rechaza con un 403 antes de descargar nada y no se cobran credits. 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
escalate
booleanOptionalfalse
Activa un único reintento automático a través del navegador stealth cuando la descarga simple de `url` encuentra un muro en lugar de la página: una página de desafío de Cloudflare, Amazon, DataDome, PerimeterX, Akamai o Vercel, un 403, 429 o 444 sin más, o un armazón vacío o una página de error servidos con un 2xx. La descarga simple siempre se ejecuta primero; un 404, un 5xx, un binario como un PDF o un host cuya ventana de `Retry-After` sigue abierta nunca escalan, y la entrada `html` nunca se descarga. El texto se extrae del HTML renderizado, de modo que la respuesta tiene la misma forma, más `escalated` (siempre que se indique este parámetro) y `stealth: { engine, vendor_detected }` cuando el renderizado se ejecutó. La escalada reutiliza la misma ruta stealth que [stealth_mode](/docs/api-reference/tools/stealth-mode) y la misma comprobación de robots.txt, y no añade ningún tratamiento nuevo de una defensa antibots; un muro en el que también se rechaza el renderizado sigue devolviéndose como página bloqueada con `escalated: true`, sin coste. Añade 5 credits, cobrados solo cuando el renderizado se ejecuta de verdad.
Example: true
escalate_engine
stringOptionalplaywright
Motor de navegador para la etapa de escalada: "playwright" (por defecto) o "camoufox" (basado en Firefox, con mayor resistencia a la detección; disponible solo donde esté instalado en el backend). Se ignora salvo que `escalate` sea `true` y la descarga simple haya quedado bloqueada.
Example: camoufox
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. `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

Descarga de una URL

  • La página se descarga una vez con un tiempo de espera de 15 segundos. Un 429 o 503 cuyo Retry-After sea de 10 segundos o menos se espera y se vuelve a descargar una vez; un Retry-After más largo o ausente no se reintenta.
  • Se leen HTML, XHTML, XML y cualquier tipo text/*, y una respuesta sin Content-Type se lee como HTML. Un PDF, una imagen u otro binario devuelve 415 UNSUPPORTED_CONTENT_TYPE con next_step: "process_document" y no cobra nada: léelo con process_document.
  • Un cuerpo JSON (application/json o *+json) se devuelve tal cual en text, con el aviso the target returned application/json; its body is returned as text. Con output_format: "markdown" se devuelve en markdown.
  • Una página que se renderiza en el cliente —menos de 200 caracteres de texto visible y un <div id="root">, "app" o "__next" vacío, o un texto que dice que la página necesita JavaScript ("Enable JavaScript…")— se devuelve con éxito, con rendered: false en data y el aviso page renders client-side; use scrape en warnings cuando no se ejecutó ningún renderizado stealth, para que un armazón vacío no se confunda con una página corta. La entrada html se comprueba igual.

Ejemplos de solicitud

cURL - Extraer desde URL

terminalBash
curl -X POST https://www.crawlforge.dev/api/v1/tools/extract_text \
  -H "X-API-Key: cf_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/article",
    "selector": "article",
    "clean": true,
    "max_length": 5000
  }'

TypeScript - Extraer desde HTML

extractText.tsTypescript
// npm install crawlforge-sdk
import { CrawlForge } from 'crawlforge-sdk';

const client = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });

const htmlContent =
  '<html><body>' +
  '<article>' +
  '<h1>Article Title</h1>' +
  '<p>This is the main content of the article.</p>' +
  '<a href="/related">Related Article</a>' +
  '</article>' +
  '</body></html>';

const result = await client.extractText({
  html: htmlContent,
  selector: 'article',
  clean: true,
  preserve_links: true,
});

// result.data is untyped in crawlforge-sdk 0.1 — its shape is the Response Example below.
const { text, metadata } = result.data as {
  text: string; metadata: { word_count: number; character_count: number };
};
console.log('Extracted text:', text);
console.log('Word count:', metadata.word_count);
console.log('Character count:', metadata.character_count);

Python - Extraer con selector

extract_text.pyPython
# pip install crawlforge
from crawlforge import CrawlForge

client = CrawlForge()  # reads CRAWLFORGE_API_KEY

result = client.extract_text(
    url='https://example.com/article',
    selector='article, .main-content',
    clean=True,
    preserve_formatting=True,
    max_length=10000,
)

# result.data is a plain dict — its shape is the Response Example below.
text = result.data['text']
metadata = result.data['metadata']

print(f"Title: {metadata['title']}")
print(f"Word count: {metadata['word_count']}")
print(f"Character count: {metadata['character_count']}")
print(f"\nExtracted text:\n{text[:500]}...")

Ejemplo de respuesta

200 OK180ms
{
"success": true,
"data": {
"text": "Article Title\nThis is the main content of the article. It contains useful information that has been extracted from the HTML.\nLinks:\nRelated Article (/related)",
"output_format": "text",
"word_count": 248,
"char_count": 1432,
"truncated": false,
"metadata": {
"title": "Article Title - Example Site",
"description": "Meta description of the article",
"word_count": 248,
"character_count": 1432,
"selector_used": "article",
"links_preserved": true,
"formatting_preserved": false
}
},
"credits_used": 1,
"credits_remaining": 999,
"processing_time": 180
}
Field Descriptions
data.textEl contenido de texto plano extraído
data.output_format"text" o "markdown"; una llamada markdown devuelve data.markdown en lugar de data.text
data.word_countPalabras del texto devuelto (con el mismo nombre que en la herramienta MCP)
data.char_countCaracteres del texto devuelto
data.truncatedtrue cuando max_length cortó el texto (entonces termina en ...); siempre presente
data.metadata.word_countNúmero total de palabras en el texto extraído
data.metadata.character_countNúmero total de caracteres
data.metadata.selector_usedEl selector CSS que se aplicó
credits_usedCredits descontados por esta solicitud (1 por cada extracción)

Manejo de errores

Entrada faltante (400 Bad Request)

No se proporcionó ni html ni url. Debe proporcionar al menos uno.

Selector no válido (400 Bad Request)

El selector CSS no es válido o no coincide con ningún elemento. Verifique la sintaxis de su selector.

Bloqueado por un muro antibots (403, 444 o 502)

El destino respondió con una página de desafío antibots en lugar del contenido, sea cual sea su código HTTP. La respuesta es success: false con error.code BLOCKED, un objeto blocked que nombra el vendor (por ejemplo cloudflare o akamai) y la evidence por la que se reconoció, y un next_step: extract_text with escalate:true, or stealth_mode operation:"scrape". El código es el propio del destino cuando es 403, 404, 410, 429, 444 o 451, y 502 en cualquier otro caso, incluido un muro servido con 200. No se cobra ningún credit. Con escalate: true el muro se renderiza una vez en el navegador stealth; si el renderizado también se rechaza, el mismo error lleva escalated: true y ningún next_step.

El destino respondió con un error (502 Bad Gateway)

El destino respondió con un error HTTP y sin un muro antibots reconocido. error.code es UPSTREAM_HTTP y el mensaje es Target answered HTTP <n>. Un 403, 404, 410, 429, 444 o 451 se devuelve tal cual como código de la respuesta; cualquier otro error (un 5xx, o un 400 o 401 del propio destino) es un 502, para que no se confunda con un problema de su solicitud o de su API key. Un 403, 429 o 444 incluye además next_step. No se cobra ningún credit.

Bloqueado por robots.txt (403 Forbidden)

El robots.txt del sitio de destino no permite esta ruta a CrawlForge. Establezca respect_robots: false para anularlo si tiene su propio acuerdo con el destino: 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, que se rechaza sea cual sea el valor de respect_robots.

Tipo de contenido no admitido (415 Unsupported Media Type)

El destino sirvió un PDF, una imagen u otro binario. error.code es UNSUPPORTED_CONTENT_TYPE, el mensaje es Unsupported content type <type>: extract_text reads HTML and text y next_step es process_document. El cuerpo no se lee, no se escala nada y no se cobra ningún credit.

Backend de escalada no configurado (503 TOOL_NOT_AVAILABLE)

escalate: true ejecuta su etapa stealth en el backend de ejecución de CrawlForge. Cuando ese backend no está configurado, la etapa devuelve 503 y no se cobra ningún credit.

Costo en credits

1 credit
1 credit por solicitud
Cada extracción de texto cuesta 1 credit, independientemente del tamaño del contenido o de la complejidad del selector. Con escalate: true una llamada se proyecta en hasta 6 credits y solo paga el suplemento de escalada de 5 credits cuando la descarga simple quedó bloqueada y el renderizado stealth se ejecutó; ningún fallo se cobra.

Herramientas relacionadas