Cómo crear un scraper de Shopify con Playwright
Lead Scraping Automation Engineer
TL;DR:
- Un scraper de Shopify debería descubrir las URLs de producto antes de extraer campos. Los enlaces de producto de mismo origen son más duraderos que las clases de estilo de un tema.
- Los datos públicos de producto estructurados pueden exponer variantes sin hacer clic en cada muestra. Verifica la respuesta en la tienda objetivo antes de confiar en ella.
- Playwright puede preservar el contexto del navegador mientras lee datos del escaparate. Mantén las solicitudes de producto y divisa dentro de ese mismo contexto.
- El ejemplo local devuelve identificadores de variantes y valores de precio sin procesar. La conversión de divisas y la coincidencia entre tiendas siguen siendo tareas separadas.
- Gratis para comenzar. Las nuevas cuentas de Scrapeless incluyen tiempo de ejecución gratuito de Scraping Browser: regístrate en app.scrapeless.com.
Introducción: Las tarjetas de producto no describen todas las variantes
La tarjeta de producto de un escaparate a menudo resume varias variantes comprables. Leer el precio mostrado en la tarjeta es útil para el descubrimiento, pero no puede establecer el precio y la disponibilidad de todas las tallas o colores.
Este tutorial de extracción de datos de productos de Shopify usa Playwright para abrir un escaparate público, descubrir un enlace de producto y leer datos estructurados de variantes en el contexto del navegador de la página. El ejemplo está deliberadamente acotado a un producto. Puedes inspeccionar los campos devueltos antes de construir un trabajo de catálogo más grande.
Playwright controla el navegador; tu contrato de extracción decide qué significa un registro válido. El flujo de alertas de bajada de precio explica cómo las observaciones registradas pueden convertirse en eventos posteriores.
Elige la fuente de extracción antes del selector
La fuente más útil es la superficie pública más estable que contenga los campos requeridos.
| Superficie | Buen encaje | Limitación a comprobar |
|---|---|---|
| Respuesta pública de producto | IDs de variantes, matrices de opciones, campos de precio | El acceso y la exhaustividad varían según el escaparate |
| Datos estructurados incrustados | Identidad del producto y una oferta descrita | Puede resumir solo la oferta seleccionada |
| Controles de producto renderizados | Estado después de seleccionar una talla, mercado u opción de compra | Requiere inspección específica de la tienda |
| Patrón de URL de enlace de producto | Descubrimiento y desduplicación | Los escaparates sin cabeza pueden usar otra forma de ruta |
El ejemplo usa un enlace /products/<handle> observado y luego lee la respuesta pública .js del producto. La interfaz Ajax de producto de Shopify documenta esta ruta y las solicitudes con reconocimiento de configuración regional. Su matriz de variantes tiene un límite documentado; no afirmes una cobertura total de un catálogo de variantes grande solo porque la solicitud tuvo éxito.
Cuando un escaparate necesita interacción para exponer una oferta, inspecciona sus controles y espera un marcador de estado específico del producto después de la interacción. Un selector de precios genérico puede elegir accidentalmente una tarjeta de recomendación, un importe de financiación o el precio de la variante anterior.
Prerrequisitos e instalación
El ejemplo local necesita Node.js, pnpm y el tiempo de ejecución Chromium de Playwright.
Usa una versión de Node.js compatible con el paquete de Playwright instalado. El entorno verificado usó Node.js 24. La extensión en la nube requiere además una cuenta activa de Scrapeless y una clave de API de servicio en SCRAPELESS_API_KEY; esa credencial es un prerrequisito y no se requiere para el colector local.
Ejecuta estos comandos en un nuevo directorio de trabajo:
bash
pnpm add playwright @scrapeless-ai/sdk
pnpm exec playwright install chromium
La instalación de la biblioteca del navegador de Playwright separa el paquete de la descarga del navegador. Guarda los ejemplos de JavaScript como archivos .mjs para que Node.js los trate como módulos ES. La extensión en la nube usa el SDK de Node.js de Scrapeless.
Crea el colector local de descubrimiento y extracción
El colector encuentra un ancla de producto comprobada y devuelve cada variante desde una respuesta estructurada.
Guarda esto como shopify.mjs y ejecuta node shopify.mjs. El producto específico es un ejemplo público, así que vuelve a comprobar la URL y la política de la tienda antes de reutilizarlo. El script informa de una ancla de descubrimiento ausente en lugar de cambiar silenciosamente a otro elemento.
javascript
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
try {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://www.taylorstitch.com/', {
waitUntil: 'domcontentloaded', timeout: 45000
});
const result = await page.evaluate(async () => {
const link = Array.from(document.querySelectorAll('a[href]'))
.map(a => new URL(a.href))
.find(u => u.origin === location.origin &&
/^\/products\/jack-in-valley-plaid-waffle-2610\/?$/.test(u.pathname));
if (!link) throw new Error('Expected product anchor is absent');
const root = window.Shopify.routes.root;
const productResponse = await fetch(link.pathname.replace(/\/$/, '') + '.js');
const cartResponse = await fetch(root + 'cart.js');
if (!productResponse.ok || !cartResponse.ok) {
throw new Error('Product or currency response unavailable');
}
const product = await productResponse.json();
const cart = await cartResponse.json();
if (!product.id || !Array.isArray(product.variants) || !cart.currency) {
throw new Error('Incomplete public product response');
}
return {
product_id: String(product.id), title: product.title,
source_url: link.href, currency: cart.currency,
observed_at: new Date().toISOString(),
variants: product.variants.map(v => ({
variant_id: String(v.id), options: v.options,
price_raw: v.price, compare_at_price_raw: v.compare_at_price ?? null,
available: v.available, sku: v.sku ?? null
}))
};
});
console.log(JSON.stringify(result, null, 2));
} finally {
await browser.close();
}
domcontentloaded es el límite de navegación, más que una promesa de que cada widget ha terminado. La página de inicio comprobada expone el ancla del producto en ese límite. Para otro tema, espera el enlace real o el control de producto que necesites antes de extraerlo.
La solicitud de carrito de solo lectura identifica la divisa de presentación para ese contexto de navegador. No añade un artículo ni inicia el pago. Las lecturas de producto y divisa siguen ocurriendo en instantes diferentes; no las describas como una instantánea de inventario atómica.
Conserva el contrato de variantes devuelto
El resultado es un sobre de producto con un arreglo de variantes, no un historial de precios de competidores listo para usar.
| Campo | Significado | Regla de validación |
|---|---|---|
product_id |
Identificador de producto de la tienda, serializado como texto | Debe estar presente |
source_url |
URL pública del producto descubierta | Mantener el host del escaparate |
currency |
Moneda reportada en el contexto actual del navegador | Debe conocerse antes de la comparación |
observed_at |
Momento de captura del recolector | Mantener junto a los campos cambiantes |
variant_id |
Identificador de variante de la tienda | Debe permanecer vinculado a su padre |
options |
Valores de opciones de origen | Conservar orden y valores |
price_raw |
Valor monetario en la unidad nativa de la respuesta | Confirmar la semántica de la unidad antes de mostrar |
compare_at_price_raw |
Importe de comparación anulable | Nulo no significa cero |
available |
Señal pública de posibilidad de compra | No es una cantidad de inventario |
sku |
SKU de comerciante opcional de la fuente | No es un identificador de producto universal |
El producto revisado contenía seis variantes y el contexto reportaba USD. Esas observaciones establecen que esta ruta extrae datos reales de producto de la fuente seleccionada; no establecen que todas las tiendas Shopify usen el mismo tema o configuración de acceso.
El vocabulario de producto es útil para distinguir atributos de identidad y descriptivos de los campos comerciales cambiantes de una oferta. Preserva ese límite al aplanar variantes en filas de almacén.
Empieza a hacer scraping con Scrapeless
Potencia tu flujo de trabajo de web scraping y automatización con Scrapeless.
Regístrate hoy y obtén 5 USD de crédito gratuito — no se requiere tarjeta de crédito.Reclama tu crédito gratuito ahora en el Panel de Scrapeless.
Amplía el descubrimiento sin perder el límite del catálogo
El descubrimiento de catálogo necesita una regla de parada explícita y un conjunto persistente de URL visitadas.
Para un scraper basado en colecciones, inspecciona el enlace real a la página siguiente o el mecanismo de paginación documentado del escaparate. Mantén el descubrimiento de colecciones separado de la extracción de productos. Elimina duplicados de rutas canónicas de producto para que un artículo que aparece en varias colecciones no se convierta en varios productos.
Registra si una ejecución es un ámbito completo aprobado o una muestra parcial. El ejemplo de un solo producto es una muestra; no puede establecer el tamaño del catálogo de la tienda. Un límite en el arreglo de variantes, una colección filtrada o una página inaccesible deberían aparecer como una limitación de cobertura en tu salida.
Para hacer scraping de páginas dinámicas de productos de Shopify, conserva la selección exacta de opciones y el estado visible cuando la fuente estructurada sea insuficiente. No copies el precio mínimo del padre en cada fila de variante. Detente cuando la oferta seleccionada no pueda identificarse con confianza.
La extensión en la nube para Playwright
Scrapeless Agent Browser puede ejecutar una sesión de Playwright de forma remota mientras tu recolector conserva su propia lógica de validación.
Utiliza la conexión Playwright documentada cuando el alojamiento local del navegador se convierta en una carga operativa. El SDK crea la sesión de navegador; Playwright se adjunta a su endpoint devuelto.
Nota: La siguiente conexión en la nube requiere una clave de API de servicio activa de Scrapeless en
SCRAPELESS_API_KEY. El ejemplo de recolección local se ejecuta de forma independiente. Este paso dependiente de credenciales debe ejecutarse en tu cuenta antes de desplegar la ruta en la nube.
javascript
import { Scrapeless } from '@scrapeless-ai/sdk';
import { chromium } from 'playwright';
const client = new Scrapeless();
const { browserWSEndpoint } = await client.browser.create({
sessionName: 'shopify-public-product',
sessionTTL: 180,
proxyCountry: 'US'
});
const browser = await chromium.connectOverCDP(browserWSEndpoint);
try {
const page = await browser.newPage();
await page.goto('https://www.taylorstitch.com/', {
waitUntil: 'domcontentloaded'
});
console.log(await page.title());
} finally {
await browser.close();
}
Tras confirmar la conexión, aplica la misma rutina de descubrimiento y extracción dentro de esa sesión. El enrutamiento de país es un parámetro del navegador; verifica la moneda y la configuración regional del escaparate en lugar de inferirlas solo a partir de la configuración del proxy. Evalúa Agent Browser y los precios de ejecución en relación con tu calendario de recolección.
Soluciona datos faltantes en el límite de la fuente
Los datos faltantes deben diagnosticarse antes de que se conviertan en un registro de producto almacenado.
| Síntoma | Verificación | Disposición segura |
|---|---|---|
| Sin ancla de producto | Ruta canónica y pertenencia actual a colección | Marcar descubrimiento incompleto |
| HTML en lugar de JSON | Desafío de acceso o comportamiento de endpoint diferente | Mantener la extracción en espera |
| Variante ausente | Límite de respuesta y producto seleccionado | Marcar cobertura incompleta |
| Moneda cambiada | Configuración regional, cookies y selección de mercado | Iniciar una serie de contexto distinta |
| Precio vacío | Semántica del campo de oferta seleccionada y fuente | Mantener desconocido; nunca insertar cero |
Revisa las reglas de acceso de la tienda antes de programar el trabajo. El estándar de exclusión de rastreadores describe las preferencias de los robots, mientras que los términos y permisos gobiernan el límite de acceso más amplio.
Conclusión: Mantén el descubrimiento, el contexto y la salida juntos
Un scraper de Shopify con Playwright es más fácil de mantener cuando el descubrimiento de productos usa enlaces duraderos y la extracción de variantes utiliza una fuente estructurada verificada. Conserva el contexto del navegador, mantén los campos de dinero explícitos y valida el resultado antes de almacenarlo. Amplía más allá del ejemplo solo después de verificar la paginación, los límites de acceso y la completitud de variantes para la tienda de destino.
¿Listo para crear tu flujo de trabajo de colecciones de Shopify?
Únete a nuestra comunidad para obtener un plan gratuito y conectarte con desarrolladores que trabajan en la recopilación de comercio electrónico basada en navegador: Discord · Telegram.
Regístrate en app.scrapeless.com y aplica el contrato de extracción verificado a tus fuentes de productos aprobadas.
Preguntas frecuentes
P: ¿Es legal extraer datos públicos de productos de Shopify?
La respuesta depende de tu jurisdicción, de los términos de la tienda, de tu método de acceso y del uso previsto. Revisa esas condiciones y consulta con un abogado cuando sea necesario. Mantén el flujo de trabajo en superficies de productos públicas y permitidas.
P: ¿Necesitas un proxy para crear un scraper de Shopify?
El ejemplo local verificado lee una fuente pública accesible sin un proxy. La extensión en la nube establece proxyCountry en EE. UU. para un enrutamiento coherente; la selección de moneda y mercado aún requiere una validación por separado.
P: ¿Cómo debe el scraper manejar una página de WAF o de Acceso denegado?
Trata el resultado como una colección no confirmada, no como datos de producto. Para un flujo de trabajo en la nube autorizado, abre primero la página de inicio en la misma sesión y luego espera un marcador de producto real. Detente cuando la tienda no permita el acceso solicitado.
P: ¿Qué cambia cuando un tema de Shopify rota sus clases DOM?
Inspecciona de nuevo el marcado en vivo y conserva la URL de producto estable o la fuente estructurada cuando sea posible. Actualiza los selectores solo después de confirmar que apuntan al producto y la variante seleccionados.
P: ¿Se puede ejecutar esto sin un agente de IA?
Sí. El script local se ejecuta directamente con Node.js. Un agente puede ayudar a inspeccionar otra tienda, pero no es necesario para ejecutar el recolector.
P: ¿Cómo se deben manejar la concurrencia y las URL de productos?
Empieza con un trabajador por tienda y la URL canónica descubierta a partir de sus enlaces públicos. Si la tienda permite la recopilación en paralelo, usa un límite inicial de tres trabajadores por host o su límite más estricto. Mantén la selección de variantes separada de la identidad canónica del producto.
En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.



