Communitygithub.com

harwal2000/skills

Úsalo cuando el usuario quiera extraer sus propios datos de un sitio web en el que inicie sesión: historial de pedidos, viajes, reservas, transacciones, historial de reproducciones o escuchas, facturas, estados de cuenta, artículos guardados; y no haya una exportación útil, o un repositorio de scraping existente esté desactualizado, roto, o solicite su contraseña.

¿Qué es skills?

Esta habilidad permite extraer datos de cuentas de usuario desde sitios web donde no existe una exportación nativa útil o los scrapers existentes están obsoletos o rotos. Funciona abriendo un navegador Playwright para que el usuario inicie sesión manualmente, luego intercepta y reproduce las solicitudes XHR/fetch, GraphQL o HTML renderizado por el servidor que el propio sitio utiliza para mostrar datos, guardando las respuestas sin procesar en disco. El asistente nunca maneja credenciales; solo guía al usuario para que inicie sesión en el navegador. Soporta paginación, partición de listas por filtros (año, pestañas), verificación de integridad de datos y generación de resúmenes de insights. Está diseñado para herramientas como Claude Code, Cursor o Codex, y sigue un flujo de trabajo seguro: ignora archivos de salida con datos sensibles, no reenvía solicitudes de mutación, y verifica la integridad de los datos mediante comprobaciones cruzadas con otras fuentes como exportaciones oficiales o recibos.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/harwal2000/skills/tree/HEAD/skills/scraping-account-data

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Scraping de Datos de Cuenta

Resumen

El usuario inicia sesión con sus propias manos en el navegador Playwright; tú encuentras la fuente de datos que el propio sitio usa en sus páginas y la reproduces dentro de la página (cookies de sesión + encabezados reales), guardando las respuestas sin procesar en disco. Nunca manejes credenciales.

Cuándo Usarlo

  • "Obtén mi historial de ", "extrae mis pedidos/viajes/reservas", "usa este repositorio de scraping"
  • Repositorios de scraping antiguos (requests + contraseña/OTP): léelos en GitHub solo para nombres de endpoints y selectores. Nunca los ejecutes: las comprobaciones de bots (cuerpo vacío HTTP 202, captchas) los rompen y solicitan la contraseña.

Exportación oficial primero. Google Takeout, "Descarga tus datos", solicitudes GDPR/DPDP, APIs públicas, recibos por correo electrónico. Las exportaciones lentas tardan días: pídele al usuario que solicite una al inicio, luego haz scraping ahora y verifica de forma cruzada por ID cuando llegue.

Flujo de Trabajo

  1. Ignorar el directorio de salida antes de escribir nada (data/<servicio>/ o su equivalente en el proyecto); confirma con git check-ignore. Los datos sin procesar contienen direcciones, teléfonos, GPS.
  2. Navegar, delegar inicio de sesión. Abre la página de la cuenta; dile al usuario que escriba teléfono/contraseña/OTP en la ventana del navegador y responda cuando termine. Nunca pidas códigos en el chat.
  3. Descubrir la fuente (browser-snippets.md §1). Recarga con un listener y clasifica:
    • JSON XHR/fetch (mejor) — anota el endpoint de la lista, la forma de paginación (next_url/cursor, page_number, offset = último id, endOfList), y el endpoint de detalle (abre un elemento).
    • GraphQL — un POST /graphql; registra el cuerpo completo de la solicitud (operationName, query o hash de consulta persistida, variables).
    • HTML renderizado por servidor — los datos llegan en la respuesta del document; obtén las páginas de lista y detalle dentro de la página y analízalas con DOMParser; guarda también el HTML sin procesar para poder re-analizarlo.
    • Listas particionadas — si la lista está dividida por un filtro (selector de año, rango de fechas, pestañas como archivado/cancelado/digital), lee cada valor de filtro y pagina cada uno.
  4. Autenticación. Prueba primero con fetch(url, {credentials: 'include'}). Si devuelve 401/403/vacío, copia los encabezados no del navegador de una solicitud en vivo (§2): copia, nunca adivines valores. Registra solo los nombres de los encabezados; nunca imprimas ni guardes valores.
  5. Paginar en segundo plano dentro de la página (§2): window.__x = {running, pages, error}, 1.5s entre solicitudes, reintentos, sondea con evaluaciones cortas. Cada respuesta: si es una página de inicio de sesión/captcha (la URL contiene signin/captcha, o HTML en lugar del JSON esperado), establece error y detente — estas a menudo llegan como 200.
  6. Guardar antes de navegar (§3). Cualquier goto/recarga borra window. browser_evaluate con una ruta absoluta de filename, devolviendo un objeto (JSON.stringify codifica dos veces). ~5 MB por archivo está bien; divide por lote más allá de eso.
  7. Solicitudes firmadas/no reproducibles (encabezados de firma de solicitud, cuerpos con nonce, consultas persistentes que rechazan ediciones): visita cada página de detalle y captura pasivamente sus respuestas (§4).
  8. Construir + verificar (abajo) con un script analizador fuera del directorio de datos, luego una nota de insights. Sigue el diseño existente del repositorio si lo hay (ej. tools/<servicio>/build_db.py, notas junto a los datos); de lo contrario, pregunta.

Solo lectura. Reproduce solo lo que la propia página solicita para mostrar datos. GraphQL: juzga por operación (query/Get*/List*), nunca mutation. Nunca reordenes, canceles, califiques, archives, elimines.

Verificación — haz todo esto

ComprobaciónPor qué
La paginación terminó porque el cursor/lista se agotó, no por un error o redirección de inicio de sesiónTruncamiento silencioso
Busca el texto "ver pedidos anteriores en la app" al finalLas vistas web limitan el historial (Swiggy: ~11 meses)
No confíes solo en el endpoint de conteo o encabezado del sitioBlinkit decía 40; la lista tenía 83
Los componentes suman al total por fila (artículos + tarifas − descuentos = pagado)Detecta desviación del analizador; si el sitio omite líneas para registros antiguos, dilo — no lo fuerces
Los precios de los artículos suman al total de artículosConfusión entre precio por unidad y total de línea
IDs únicos; elimina duplicados exactosLas exportaciones y recibos listan dos veces
Verifica de forma cruzada otra fuente por ID (exportación, recibos)Prueba la cobertura
Cada lista/pestaña/filtro fue cubierto (archivado, cancelado, otros años, subservicios)"Todos los pedidos" a menudo abarca varias listas

Notas de análisis

  • APIs de IU impulsadas por servidor (snippets, widgets, widget_type, layout): recorre los widgets en orden, recopila los campos text de cada widget, asigna según etiquetas conocidas. Un widget de un solo texto suele ser una etiqueta para el siguiente: crea una lista blanca de nombres de etiquetas o cada campo se desplazará.
  • Los montos pueden ser en paisa/centavos; "GRATIS" = 0; "-" inicial = descuento; elimina símbolos de moneda y agrupación de comas indias. Mantén las monedas separadas.
  • Marcas de tiempo: compras → zona horaria del usuario; viajes/desplazamientos → hora local del registro.
  • Mantén los archivos sin procesar fechados (pedidos-crudos-YYYY-MM-DD.json) junto al SQLite construido.

Git

Confirma solo: la línea de gitignore, el script analizador, cualquier fila de README/índice. Los archivos sin procesar y el SQLite se quedan locales. Prepara rutas explícitas (nunca git add -A en un árbol sucio); confirma solo cuando se te pida.

Errores Comunes

  • Un bucle de evaluación síncrono largo — se agota el tiempo; ejecútalo en segundo plano y sondea.
  • Devolver datos masivos al chat en lugar de filename.
  • Listeners de fragmentos dejados adjuntos — elimínalos con page.off, o las ejecuciones repetidas acumulan manejadores.
  • Filtrar el descubrimiento a xhr/fetch en un sitio renderizado con HTML y concluir "no hay fuente de datos".

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados