En esta guía aprenderás:
- Qué es
llm-scraper
- Cómo utilizarlo paso a paso
- Cómo utilizarlo para generar código
- ¿Cuáles son las principales alternativas para el scraping basado en LLM?
- Sus principales limitaciones y cómo superarlas
Sumerjámonos.
¿Qué es llm-scraper?
llm-scraper
es una librería TypeScript que utiliza LLMs para extraer datos estructurados de cualquier página web.
En lugar de escribir una lógica de análisis personalizada para cada sitio, basta con definir un esquema y el paquete emplea un LLM para rellenarlo de forma inteligente analizando el contenido de la página.
La biblioteca se publicó por primera vez a mediados de 2024, por lo que aún es bastante nueva. Sin embargo, ya ha conseguido más de 4.000 estrellas en GitHub, lo que demuestra lo rápido que se está popularizando:
Es ideal para sitios web dinámicos o incoherentes (como los de comercio electrónico), donde los raspadores tradicionales suelen fallar. En esos casos, el raspado LLM brilla con luz propia.
En concreto, las principales funciones que ofrece llm-scraper
son:
- Integración con múltiples proveedores de LLM: Funciona con modelos locales (como Ollama o GGUF) y proveedores en la nube (como OpenAI y Vercel AI SDK).
- Extracción de datos basada en esquemas: Defina lo que desea extraer utilizando esquemas Zod para una estructura y validación sólidas.
- Seguridad tipográfica total: Diseñado para TypeScript, por lo que obtendrá una comprobación de tipos completa en tiempo de compilación.
- Construido sobre Playwright: Utiliza Playwright bajo el capó para controlar el navegador y obtener el contenido de la página.
- Soporte de streaming: Puede transmitir objetos durante el raspado en lugar de esperar a que se complete toda la extracción.
- Generación de código: Puede generar código de raspado dinámicamente basado en su esquema y objetivo.
- Múltiples opciones de formato del contenido de la página: Puede elegir cómo enviar el contenido de la página al LLM
Cómo utilizar llm-scraper para Web Scraping
En esta sección del tutorial, aprenderá a utilizar la biblioteca llm-scraper
para crear un scraper basado en IA. El sitio de destino será una página de productos de comercio electrónico del sitio web ToScrape:
Este es un buen ejemplo porque el scraping de sitios de comercio electrónico puede ser complicado. Las estructuras de sus páginas cambian a menudo, y los distintos productos pueden tener diseños e información diferentes. Por eso, escribir una lógica de análisis estática es difícil y poco eficaz. Por eso, la IA puede ser de gran ayuda.
Sigue los pasos que se indican a continuación para crear un rascador con tecnología LLM.
Requisitos previos
Para seguir este tutorial, necesitarás
- Node.js instalado en su máquina
- Una clave de API de OpenAI (o una clave de un proveedor similar como Groq)
- Conocimientos básicos de TypeScript y programación asíncrona
Paso nº 1: Configuración del proyecto
Antes de empezar, asegúrate de que tienes la última versión LTS de Node.js instalada localmente. Si no es así, descárgala del sitio oficial e instálala.
Ahora, crea un proyecto para tu scraper y navega hasta él en el terminal:
mkdir llm-scraper-project
cd llm-scraper-project
Dentro de tu proyecto, ejecuta el siguiente comando para inicializar un proyecto Node.js en blanco:
npm init -y
Abra el archivo package.json
creado por el comando anterior y asegúrese de que contiene:
"type": "module"
Cargue la carpeta del proyecto llm-scraper-project
en su IDE TypeScript favorito, como Visual Studio Code.
A continuación, instala TypeScript como dependencia de desarrollo:
npm install typescript --save-dev
Con TypeScript instalado, inicialice su proyecto TypeScript ejecutando:
npx tsc --init
Aparecerá un archivo tsconfig.json
en la carpeta de su proyecto. Ábralo y sustitúyalo por:
{
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"skipLibCheck": true
}
}
Ahora, añade un archivo scraper.ts
a tu proyecto:
Este archivo pronto contendrá tu lógica de extracción de datos llm-scraper
. Dado que el script utilizará lógica TypeScript asíncrona, inicializa una función asíncrona dentro de él:
async function llmScraping() {
// your LLM scraping logic...
}
llmScraping()
¡Maravilloso! Usted está completamente configurado y listo para comenzar a construir su raspador impulsado por IA.
Paso 2: Instalar las bibliotecas raspadas
Para funcionar, llm-scraper
depende de las dos bibliotecas adicionales siguientes:
- Zod: Una biblioteca de validación y declaración de esquemas basada en TypeScript.
- Playwright: Una biblioteca para automatizar los navegadores Chromium, Firefox y WebKit con una única API.
Instálelos junto con llm-scraper
utilizando el siguiente comando:
npm install zod playwright llm-scraper
Playwright requiere algunas dependencias adicionales (como los binarios del navegador). Instálelos con:
npx playwright install
Ahora, importa Zod y Playwright en scraper.ts
:
import { z } from "zod"
import { chromium } from "playwright"
import LLMScraper from "llm-scraper"
¡Genial! Ahora tienes todas las librerías necesarias para empezar con LLM web scraping en TypeScript.
Paso 3: Configurar OpenAI
llm-scraper
soporta varios proveedores LLM, incluyendo OpenAI, Groq, Ollama y GGUF. En este caso, vamos a utilizar OpenAI. Si aún no lo has hecho, asegúrate de obtener tu clave API de OpenAI.
En primer lugar, instala el cliente OpenAI JavaScript:
npm install @ai-sdk/openai
A continuación, impórtalo en tu código y utilízalo para inicializar tu modelo LLM dentro de la función llmScraping()
:
// other imports...
import { openai } from "@ai-sdk/openai"
// ...
const llm = openai.chat("gpt-4o")
Para una integración diferente, consulte la documentación oficial de llm-scraper`
.
Para evitar la codificación de la clave OpenAI en su código, instale dotenv
:
npm install dotenv
Importa dotenv
en tu archivo scraper.ts
y llama a dotenv.config()
para cargar las variables de entorno:
// other imports...
import * as dotenv from "dotenv"
// ...
dotenv.config()
Esto te permite cargar variables de entorno, como tu clave de API de OpenAI, desde un archivo .env
. Por lo tanto, añade un archivo .
env a tu proyecto:
Ábrelo y añade tu clave API de OpenAI de esta forma:
OPENAI_API_KEY="<YOUR_OPENAI_KEY>"
Sustituya por el valor de su clave Open AI
Tenga en cuenta que no es necesario leer manualmente la variable en su código. Esto se debe a que @ai-sdk/openai
intenta leer automáticamente la variable de entorno OPENAI_KEY
.
¡Asombroso! Integración LLM completada.
Paso 4: Conectarse a la página de destino
llm-scraper
se basa en Playwright como motor de automatización del navegador para extraer el contenido HTML de las páginas web. Para empezar, añada las siguientes líneas de código dentro de llmScraping()
a:
- Inicializar un navegador Chromium
- Abrir una nueva página
- Indique a Playwright que visite la página de destino
Consíguelo con:
const browser = await chromium.launch()
const page = await browser.newPage()
await page.goto("https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html")
Al final, no olvides cerrar el navegador y liberar sus recursos:
await page.close()
await browser.close()
Si no está familiarizado con este proceso, lea nuestra guía sobre el web scraping de Playwright.
Paso nº 5: Definir el esquema de datos
Ahora, llm-scraper
funciona alimentando el modelo LLM subyacente con un prompt-operando sobre el contenido extraído de la página a través de Playwright-para extraer datos estructurados tal y como se definen en un modelo de datos específico.
Aquí es donde entra Zod, ayudándote a especificar ese modelo de datos en TypeScript. Para entender cómo debería ser el esquema de tus datos raspados, abre el sitio de destino en tu navegador y empieza analizando el nivel superior de la página:
A partir de aquí, debes centrarte en extraer los siguientes datos:
- Título
- Precio
- Estado de las existencias
- Cantidad
- Descripción
A continuación, pase a la última sección de la página:
Aquí le interesará:
- UPC (Código Universal de Producto)
- Tipo de producto
- Impuesto
- Número de opiniones
Si lo juntamos todo, obtendremos el siguiente esquema de producto:
const productSchema = z.object({
title: z.string().describe("The name of the product"),
price: z.string().describe("The price of the product, typically formatted as a string like '£19.99'"),
stock: z.string().describe("The availability status of the product, such as 'In Stock' or 'Out of Stock'"),
quantity: z.string().describe("The specific quantity of products available in stock"),
description: z.string().describe("A detailed description of the product, including features and specifications"),
upc: z.string().describe("The Universal Product Code (UPC) to uniquely identify the product"),
productType: z.string().describe("The category or type of the product, such as 'Books', 'Clothing', etc."),
tax: z.string().describe("Information about the applicable tax amount for the product"),
reviews: z.number().describe("The number of reviews the product has received"),
})
Consejo: No olvide describir su esquema, ya que esto ayuda al modelo LLM a entender lo que debe hacer con los datos.
¡Fantástico! Ya está listo para iniciar la tarea de raspado con IA en llm-scraper
.
Paso 6: Ejecutar la tarea de raspado
Utilice la integración LLM que definió en el paso 3 para crear un objeto LLMScraper
:
const scraper = new LLMScraper(llm)
Este es el objeto principal expuesto por la biblioteca llm-scraper
, y es responsable de realizar las tareas de raspado basadas en IA.
A continuación, lanza el rascador de la siguiente manera:
const { data } = await scraper.run(page, productSchema, {
format: "markdown",
})
El parámetro de formato
define cómo se pasa el contenido de la página al LLM. Los valores posibles son:
"html"
: El HTML en bruto de la página."texto"
: Todo el contenido de texto extraído de la página.- “
markdown"
: El contenido HTML convertido a Markdown. - “
limpieza"
: Una versión limpiada del texto extraído de la página. "Imagen"
: Una captura de pantalla de la página.
Nota: También puede proporcionar una función personalizada para controlar el formato del contenido si es necesario.
Como se explica en la guía “¿Por qué los nuevos agentes de IA eligen Markdown en lugar de HTML?“, utilizar el formato Markdown es una elección inteligente porque ayuda a ahorrar tokens y a acelerar el proceso de scraping.
Por último, la función scraper.run()
devuelve un objeto que coincide con el esquema Zod esperado.
¡Perfecto! Su tarea de raspado con IA está completa.
Paso 7: Exportar los datos extraídos
Actualmente, los datos raspados se almacenan en un objeto JavaScript. Para facilitar el acceso a los datos, analizarlos y compartirlos, expórtelos a un archivo JSON como se indica a continuación:
const jsonData = JSON.stringify(data, null, 4)
await fs.writeFile("product.json", jsonData, "utf8")
Ten en cuenta que no necesitas ninguna librería externa para esto. Sólo asegúrese de añadir la siguiente importación en la parte superior de su archivo scraper.ts
:
import { promises as fs } from "fs"
Paso 8: Póngalo todo junto
scraper.ts
debería contener ahora:
import { z } from "zod"
import { chromium } from "playwright"
import LLMScraper from "llm-scraper"
import { openai } from "@ai-sdk/openai"
import * as dotenv from "dotenv"
import { promises as fs } from "fs"
// load the environment variables from the local .env file
dotenv.config()
async function llmScraping() {
// initialize the LLM engine
const llm = openai.chat("gpt-4o")
// launch a browser instance and open a new page
const browser = await chromium.launch()
const page = await browser.newPage()
// navigate to the target e-commerce product page
await page.goto("https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html")
// define the product schema
const productSchema = z.object({
title: z.string().describe("The name of the product"),
price: z.string().describe("The price of the product, typically formatted as a string like '£19.99'"),
stock: z.string().describe("The availability status of the product, such as 'In Stock' or 'Out of Stock'"),
quantity: z.string().describe("The specific quantity of products available in stock"),
description: z.string().describe("A detailed description of the product, including features and specifications"),
upc: z.string().describe("The Universal Product Code (UPC) to uniquely identify the product"),
productType: z.string().describe("The category or type of the product, such as 'Books', 'Clothing', etc."),
tax: z.string().describe("Information about the applicable tax amount for the product"),
reviews: z.number().describe("The number of reviews the product has received"),
})
// create a new LLMScraper instance
const scraper = new LLMScraper(llm)
// run the LLM scraper
const { data } = await scraper.run(page, productSchema, {
format: "markdown", // or "html", "text", etc.
})
// conver the scraped data to a JSON string
const jsonData = JSON.stringify(data, null, 4)
// populate an output file with the JSON string
await fs.writeFile("product.json", jsonData, "utf8")
// close the page and the browser and release their resources
await page.close()
await browser.close()
}
llmScraping()
Como puede ver, llm-scraper
le permite definir un script de scraping basado en JavaScript en un puñado de líneas de código.
Compila tu script de TypeScript a JavaScript con este comando:
npx tsc
Un archivo scraper.js
aparecerá en la carpeta de tu proyecto. Ejecútalo con:
node scraper.js
Cuando el script termine de ejecutarse, aparecerá un archivo llamado product.json
en la carpeta del proyecto.
Ábrelo y verás algo así:
{
"title": "A Light in the Attic",
"price": "£51.77",
"stock": "In Stock",
"quantity": "22",
"description": "It's hard to imagine a world without A Light in the Attic. This now-classic collection of poetry and drawings from Shel Silverstein celebrates its 20th anniversary with this special edition. Silverstein's humorous and creative verse can amuse the dowdiest of readers. Lemon-faced adults and fidgety kids sit still and read these rhythmic words and laugh and smile and love that Silverstein. Need proof of his genius? Rockabye Rockabye baby, in the treetop Don't you know a treetop Is no safe place to rock? And who put you up there, And your cradle, too? Baby, I think someone down here's Got it in for you. Shel, you never sounded so good.",
"upc": "a897fe39b1053632",
"productType": "Books",
"tax": "£0.00",
"reviews": 0
}
Este archivo contiene exactamente la información que se muestra en la página del producto que ha seleccionado. Como puede ver, los datos se extrajeron sin necesidad de una lógica de análisis personalizada, gracias a la potencia de los LLM. ¡Buen trabajo!
Extra: Generación de código con llm-scraper
llm-scraper
también tiene la capacidad de generar la lógica subyacente de análisis de datos de Playwright, dado el esquema. Esto es posible gracias a la función generate()
.
Vea un ejemplo en el siguiente fragmento:
const { code } = await scraper.generate(page, productSchema)
Como puede ver, toma el objeto de página Playwright y el esquema Zod, y devuelve una cadena que contiene el código Playwright generado. En este caso, la salida es:
(function() {
function extractData() {
const title = document.querySelector('h1').innerText;
const price = document.querySelector('.price_color').innerText;
const stockText = document.querySelector('.instock.availability').innerText.trim();
const stock = stockText.includes('In stock') ? 'In Stock' : 'Out of Stock';
const quantityMatch = stockText.match(/\d+/);
const quantity = quantityMatch ? quantityMatch[0] : '0';
const description = document.querySelector('#product_description ~ p').innerText;
const upc = document.querySelector('th:contains("UPC") + td').innerText;
const productType = document.querySelector('th:contains("Product Type") + td').innerText;
const tax = document.querySelector('th:contains("Tax") + td').innerText;
const reviews = parseInt(document.querySelector('th:contains("Number of reviews") + td').innerText, 10);
return {
title,
price,
stock,
quantity,
description,
upc,
productType,
tax,
reviews
};
}
const data = extractData();
console.log(data);
})()
A continuación, puede ejecutar este código JavaScript generado mediante programación y analizar el resultado con:
const result = await page.evaluate(code)
const data = schema.parse(result)
El objeto de datos
contendrá el mismo resultado que los datos
producidos en el paso nº 6 del capítulo anterior.
llm-scraper
Alternativas para LLM Scraping
llm-scraper
no es la única biblioteca disponible para el raspado basado en LLM. Otras alternativas dignas de mención son:
- Crawl4AI: Una librería Python para construir agentes de rastreo web y pipelines de datos ultrarrápidos y preparados para IA. Es altamente flexible y está optimizada para que los desarrolladores la desplieguen con velocidad y precisión. Puedes verlo en acción en nuestro tutorial sobre rastreo de Crawl4AI.
- ScrapeGraphAI: Una librería Python de scraping web que combina LLMs y lógica gráfica directa para construir pipelines de scraping para sitios web y documentos locales (como XML, HTML, JSON y Markdown). Descúbrelo en nuestra guía sobre scraping con ScrapeGraphAI.
Limitaciones de este enfoque del Web Scraping
ToScrape, el sitio de destino que utilizamos en este artículo, es -como su nombre indica- un sandbox de scraping que acepta scripts de scraping. Desafortunadamente, cuando se utiliza llm-scraper
contra sitios web del mundo real, es probable que las cosas se pongan mucho más difíciles…
¿Por qué? Porque las empresas de comercio electrónico y los negocios en línea saben lo valiosos que son sus datos y hacen todo lo posible por protegerlos. Esto es cierto incluso si esos datos están disponibles públicamente en las páginas de sus productos.
Como resultado, la mayoría de las plataformas de comercio electrónico implementan medidas anti-bot y anti-scraping para bloquear los rastreadores automatizados. Estas técnicas pueden detener incluso a los scrapers basados en herramientas de automatización de navegadores como Playwright, al igual que llm-scraper
.
Estamos hablando de defensas como el infame CAPTCHA de Amazon, que basta para detener a la mayoría de los bots:
Ahora bien, incluso si consigue evitar los CAPTCHA con Playwright, otros problemas como las prohibiciones de IP causadas por demasiadas solicitudes automatizadas pueden bloquear su operación de scraping.
Llegados a este punto, la solución no consiste en retocar sin cesar el guión para hacerlo más complejo. Se trata de utilizar las herramientas adecuadas.
Al integrar Playwright con un navegador diseñado específicamente para el raspado web, como Scraping Browser, todoresulta mucho más sencillo. Esta solución es un navegador basado en la nube optimizado para el scraping. Se encarga de la rotación de IP, los reintentos automáticos, los mecanismos avanzados de evasión anti-bot e incluso la resolución de CAPTCHA incorporada, todo ello sin necesidad de gestionar la infraestructura usted mismo.
Integra Scraping Browser con Playwright en llm-scraper
como cualquier otro navegador tal y como se explica en nuestros docs.
Conclusión
En esta entrada de blog, aprendiste lo que llm-scraper
tiene para ofrecer y cómo usarlo para construir un script de scraping potenciado por IA en TypeScript. Gracias a su integración con LLMs, puedes hacer scraping de sitios con estructuras de página complejas o dinámicas.
Como ya hemos comentado, la forma más eficaz de evitar ser bloqueado es utilizarlo junto con el Scraping Browser de Bright Data, que viene con un solucionador CAPTCHA incorporado y muchas otras capacidades de evasión anti-bot.
Si está interesado en construir un agente de IA directamente basado en esa solución, eche un vistazo a Agent Browser. Esta solución ejecuta flujos de trabajo basados en agentes en navegadores remotos que nunca se bloquean. Es infinitamente escalable y se alimenta de la red proxy más fiable del mundo.
Cree hoy mismo una cuenta gratuita en Bright Data y explore nuestras soluciones de datos y scraping para impulsar su viaje hacia la IA.
No se requiere tarjeta de crédito