---
title: "¿Scrapling guarda los datos extraídos en los checkpoints?"
canonical: https://wavect.io/es/blog/scrapling-checkpoints-scraped-items/
language: es
description: "¿Scrapling guarda los datos extraídos en sus checkpoints? Prueba reproducible de pausa, reanudación y repetición, con JSON, SQLite y registros perdidos."
image: "https://wavect.io/img/blog/headers/header_scrapling-checkpoints-scraped-items.png"
author: ["Kevin Riedl"]
published: "2026-11-03"
updated: "2026-11-03"
reviewed: "2026-11-03"
---

# ¿Scrapling guarda los datos extraídos en los checkpoints?

[**Volver**](/es/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/es/team/kevin-riedl/)

[Kevin Riedl](/es/team/kevin-riedl/) https://linkedin.com/in/wsdt

12 min de lectura · 3 nov 2026 Última revisión 3 de noviembre de 2026

[**Siguiente**](/es/blog/wigolo-local-web-intelligence-mcp-review/)

Resumen

Los checkpoints de Scrapling 0.5 guardan solicitudes pendientes y huellas, pero no los registros extraídos. En nuestra prueba local, reanudar en otro proceso devolvió B y C; exportar al mismo JSON eliminó A. Una base SQLite conservó los tres. La repetición deliberada duplicó escrituras, mientras las claves mantuvieron tres filas. Un fallo de escritura dejó un registro ausente pese a terminar el rastreo, con un manejador que solo registraba errores. Guarda los datos por separado y comprueba la colección antes de entregarla al agente.

Pausamos nuestro rastreo con Scrapling después de guardar el registro A. Al reanudar, la ejecución devolvió B y C. Exportamos ese resultado a la misma ruta JSON: el archivo se reemplazó y A desapareció de él.

**No. Los checkpoints (puntos de guardado) de Scrapling 0.5 no guardan los registros extraídos.** Conservan las solicitudes pendientes y las huellas de solicitudes ya registradas. Guarda los datos por separado, asígnales identidades estables y comprueba lo almacenado después de reanudar. La cola restaurada y la lista de registros de la siguiente ejecución cumplen funciones distintas, como muestra la [estructura del checkpoint](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/scrapling/spiders/checkpoint.py).

**Prueba realizada el 3 de noviembre de 2026.** Ejecutamos [Scrapling 0.5, publicado el 17 de octubre](https://github.com/D4Vinci/Scrapling/releases/tag/v0.5), contra tres páginas HTTP locales. Cinco procesos nuevos de Python cubrieron una ejecución sin interrupciones, una pausa ordenada, la reanudación, la repetición deliberada desde un checkpoint y un fallo de escritura provocado.

## ¿Qué aporta Scrapling al acceso web de un agente?

Scrapling es un framework de scraping web para Python. Reúne clientes HTTP, acceso mediante navegador, análisis de páginas y rastreadores concurrentes, llamados spiders. Una integración para agentes puede elegir distintos métodos de acceso para páginas estáticas o renderizadas y mantener la extracción en la misma biblioteca. Nuestra prueba se centra en lo que ocurre con los registros extraídos al reanudar un spider.

El [README de esta versión](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/README.md) documenta la simulación de la identidad del navegador, el renderizado de JavaScript, los reintentos, la rotación de proxies, la extracción por CLI y el acceso mediante MCP. El proyecto utiliza la [licencia BSD de tres cláusulas](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/LICENSE).

El análisis adaptativo vuelve a localizar elementos cuando cambia el HTML. La [guía de análisis adaptativo](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/docs/parsing/adaptive.md) explica las propiedades guardadas y la comparación por similitud. Recuperar un selector no guarda de forma persistente el registro extraído. Para decidir la arquitectura de recuperación web más amplia, consulta nuestro [análisis de la capa local de recuperación web de Wigolo](/es/blog/wigolo-local-web-intelligence-mcp-review/).

## ¿Qué datos contiene un checkpoint de Scrapling?

Un checkpoint de Scrapling 0.5 contiene solicitudes pendientes y huellas de solicitudes ya registradas. La lista de registros recopilados pertenece a la ejecución actual; tu aplicación gestiona cualquier base de datos o exportación adicional. En la versión revisada, el [motor de rastreo](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/scrapling/spiders/engine.py) vacía esa lista al iniciar una ejecución.

| Almacenamiento | Qué contiene | Qué esperar al reanudar |
| --- | --- | --- |
| Checkpoint de Scrapling | Solicitudes pendientes y huellas ya registradas | Las solicitudes restantes pueden continuar desde el estado guardado |
| `result.items` | Registros conservados durante esta ejecución | No incluye los registros recopilados en ejecuciones anteriores |
| Almacenamiento de la aplicación | Registros que tu código confirma en una base de datos u otro destino persistente | La conservación depende del destino y de tu política de escritura |

Esta diferencia importa si exportas después de cada ejecución. En la versión 0.5, `result.items.to_json(path)` escribe la lista actual en esa ruta. La [implementación de la exportación](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/scrapling/spiders/result.py) reemplaza el archivo; `to_jsonl(path)` también lo abre en modo escritura. Ninguno de los dos métodos combina las ejecuciones anteriores por ti.

Conserva exportaciones separadas por ejecución o guarda los registros en una base de datos. Nuestra prueba muestra qué ocurre al reutilizar una ruta de exportación.

## ¿Qué datos sobrevivieron a la pausa, la reanudación y la repetición?

Tras reanudar, la tabla de SQLite con claves únicas conservaba los tres registros esperados. El JSON que habíamos vuelto a exportar solo contenía B y C. Repetir deliberadamente desde el checkpoint guardado produjo B y C otra vez. El registro de escrituras acumuló cinco entradas; la tabla con claves únicas seguía teniendo tres filas.

El entorno de prueba sirve los registros inmutables A, B y C por HTTP en la interfaz local de bucle de retorno. Permite una solicitud simultánea, desactiva los checkpoints periódicos y se pausa después de confirmar A en la base de datos. Cada fase arranca en un proceso nuevo de Python. La secuencia de pausa y reanudación comparte base de datos y ruta de exportación; el control y la prueba de fallo usan directorios separados.

| Fase observada | Registros devueltos y JSON exportado | IDs guardados en SQLite | Resultado |
| --- | --- | --- | --- |
| Control sin interrupciones | A, B, C | A, B, C | Están todos los registros esperados |
| Pausa ordenada después de A | A | A | El checkpoint conserva B y C como pendientes |
| Reanudación en un proceso nuevo | B, C | A, B, C | Falta A en el JSON exportado a la misma ruta |
| Repetición deliberada desde nuestro checkpoint | B, C | A, B, C | Registro de escrituras: A una vez, B y C dos veces cada uno |
| Ejecución separada con fallo de escritura provocado en B | A, C | A, C | `completed=True`, un error de callback registrado y B ausente |

Para repetir, restauramos el checkpoint de la ejecución pausada después de que terminara el rastreo reanudado. Así comprobamos solicitudes repetidas. No simulamos una caída inesperada ni medimos qué sobrevive a un corte eléctrico.

En la prueba de fallo, nuestro hook de registros lanzó una excepción antes de escribir B, y `on_error` la registró sin reintentar. Scrapling terminó el resto del rastreo. La comparación con el manifiesto de registros esperados detectó que faltaba B.

[Descarga la prueba de checkpoints de Scrapling y sus resultados](/downloads/scrapling-checkpoints-scraped-items-fixture.zip). El paquete incluye las páginas locales, el manifiesto, el código de los procesos y del ejecutor, las versiones de dependencias, los informes JSON, los registros de escrituras y las exportaciones legibles de las bases de datos.

## ¿Cómo puedes reproducir la prueba de checkpoints?

Ejecuta el paquete descargado en un entorno nuevo de Python con el extra de fetchers de Scrapling. El ejecutor inicia un servidor HTTP local, lanza los cinco procesos y verifica por separado los archivos exportados y los registros de la base de datos. Este experimento utiliza únicamente HTTP: no necesita binarios de navegador, un cliente MCP ni un modelo de IA.

```
python3.12 -m venv .venv
mkdir -p .cache/pip .cache/tmp
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_CACHE_DIR="$PWD/.cache/pip" TMPDIR="$PWD/.cache/tmp" .venv/bin/python -m pip install -r requirements-tested.txt
.venv/bin/python run_fixture.py --output results-reproduced
.venv/bin/python verify_payloads.py --results results-reproduced
```

Ejecuta estos comandos en Linux desde el directorio del paquete extraído. La prueba registrada usó Python 3.12.14; `requirements-tested.txt` fija las versiones de sus paquetes. Antes de instalar, comprobamos que el [wheel de Scrapling 0.5](https://pypi.org/project/scrapling/0.5/#files) coincidía con su SHA-256 publicado:

```
366f0ec9f1e7e998900e6c5e3a4063ea34062326394ced64e5c389b690572726
```

Revisa `summary.json`, `payload-validation.json` y los informes de cada fase en el directorio de salida. El servidor sigue activo entre procesos para que las URL guardadas en el checkpoint continúen siendo válidas. Cada repetición del experimento genera su propio checkpoint; los identificadores de proceso, el puerto local y los bytes del checkpoint pueden variar. Las comprobaciones contrastan las identidades y el contenido de los registros con el manifiesto.

## ¿Dónde debes guardar los registros extraídos?

Guarda los registros de Scrapling en un destino gestionado por tu aplicación mediante `on_scraped_item`. Usa una identidad adecuada para la colección y confirma cada escritura correcta antes de retornar desde el hook. Scrapling espera a que termine antes de conservar el registro, pero el hook también necesita una política explícita de errores. Una clave única no recupera una escritura que nunca se confirmó.

La [API de hooks de Spider](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/scrapling/spiders/spider.py) ofrece ese punto de integración. Esta es la escritura ejecutada en nuestra prueba, sin el código de instrumentación que la rodea:

```
self.database.execute(
    "INSERT INTO items (collection_id, item_id, payload_json) VALUES (?, ?, ?) "
    "ON CONFLICT(collection_id, item_id) DO UPDATE SET payload_json=excluded.payload_json",
    (self.manifest["collection_id"], item["id"], json.dumps(item, sort_keys=True)),
)
self.database.commit()
```

La clave primaria es `(collection_id, item_id)`. Un upsert inserta una fila nueva o actualiza la que tiene la misma clave. Por eso, escribir A, B o C varias veces conserva una sola fila por registro dentro de esta colección inmutable. La descarga incluye el esquema y el hook completo.

Si los datos cambian, decide si las nuevas observaciones reemplazan las anteriores o crean versiones. Cuando necesites conservar el historial, incluye el ámbito de la observación en la identidad. De lo contrario, la eliminación de duplicados puede sobrescribir información que querías conservar.

Una integración en producción necesita un registro de escrituras fallidas que permita recuperarlas o una política explícita de reintentos, seguida de una comprobación de integridad. Valida esa política frente a los fallos de tu destino de almacenamiento. Esta prueba con SQLite no demuestra la recuperación de transacciones en otra base de datos.

## ¿Cómo compruebas que están todos los datos tras reanudar?

Contrasta la salida persistente de Scrapling con la colección que pretendías obtener: identidades esperadas y campos obligatorios. En nuestra prueba, el manifiesto independiente permite detectar sin ambigüedad la ausencia de A o B. En una web real, necesitas definir por separado el alcance y el método para descubrir la población esperada. Terminar la cola de solicitudes no resuelve esa definición.

| Pregunta de aceptación | Evidencia que debes revisar | Resultado de la prueba |
| --- | --- | --- |
| ¿Faltan registros esperados? | IDs esperados menos IDs almacenados | Faltaba A en el JSON reanudado y B tras el fallo de escritura provocado |
| ¿Se procesaron registros otra vez? | Número de emisiones o escrituras por ID | B y C se escribieron dos veces cada uno en la secuencia de repetición |
| ¿El destino final conserva un registro por cada clave prevista? | Filas de la base de datos bajo la identidad de colección elegida | Tres filas después de reanudar y de repetir deliberadamente |
| ¿Los valores obligatorios corresponden a los registros previstos? | Contenido almacenado comparado con el manifiesto de la prueba | Los IDs, nombres y URL de origen coincidían tras reanudar y repetir |
| ¿Quedan errores de escritura sin resolver? | Errores del hook y registros de recuperación | El fallo provocado en B impide aceptar los datos, aunque el rastreo haya terminado |

La [guía de rastreo avanzado](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/docs/spiders/advanced.md) documenta pausa, reanudación, streaming y hooks de salida. Usa esos componentes para conservar los datos y decide por separado cuándo entregar la colección al siguiente sistema.

Si un agente o un índice RAG consume únicamente el JSON de la ejecución reanudada en este ejemplo, recibe dos registros. Entrega la colección verificada desde el almacenamiento persistente. La recuperación del proceso es otra cuestión; nuestra [guía de recuperación y despliegue propio del runner de AX](/es/blog/google-ax-agent-executor-security-self-hosting/) cubre ese límite.

## ¿El servidor MCP cambia estas condiciones de persistencia?

El servidor MCP de Scrapling ofrece operaciones web y de navegador a agentes compatibles, pero este experimento utilizó la API de Spider en Python. Sus resultados sobre checkpoints no demuestran la persistencia de un flujo MCP. Define dónde guarda tu agente el contenido recibido y verifica ese destino ante las interrupciones que tu flujo deba soportar.

La [guía de MCP de la versión 0.5](https://github.com/D4Vinci/Scrapling/blob/3a8bf4e4d3ed91257ba0aa5b7dc66241d1e23840/docs/ai/mcp-server.md) enumera 16 herramientas: sesiones de solicitudes, acciones de navegador, extracción selectiva, capturas de pantalla, inspección de red y estado guardado del navegador, entre otras. Conservar una sesión autenticada y conservar los datos extraídos exige una gestión separada.

## ¿Cuándo usaríamos Scrapling para alimentar un agente?

Usaríamos Scrapling cuando una integración en Python aproveche sus funciones de acceso web, análisis y control del rastreo, y la aplicación también se encargue de guardar los registros. Empieza con una colección pequeña cuyo acceso esté autorizado. Elige las identidades, prueba la reanudación y la repetición, y revisa lo almacenado. Añade fallos de escritura realistas antes de que otros sistemas dependan de esos datos.

Utiliza páginas representativas, el esquema de registros necesario y los requisitos de reinicio para definir tu prueba de aceptación de la ingesta.

## Preguntas sobre los checkpoints de Scrapling

### ¿to_jsonl añade los registros a los de ejecuciones anteriores?

No. Scrapling 0.5 abre el archivo JSONL de destino en modo escritura. Llamar a to_jsonl con la misma ruta después de otra ejecución reemplaza el archivo por la lista actual. Conserva archivos separados y combínalos de forma explícita, o guarda los registros en un destino persistente durante el rastreo. La extensión JSONL no implica que se añadan datos al final.

### ¿Evitar solicitudes duplicadas impide que haya filas duplicadas?

La deduplicación de solicitudes y la identidad de los registros resuelven tareas distintas. Varias solicitudes pueden producir el mismo registro lógico; repetir desde un checkpoint puede volver a procesar sus solicitudes pendientes. En nuestra repetición controlada, B y C aparecieron dos veces en el registro de escrituras correctas. Una clave de colección y registro mantuvo tres filas finales, pero no evitó que se procesaran de nuevo.

### ¿El estado de sesión del navegador incluye los datos extraídos?

No. La exportación documentada del estado del navegador guarda cookies, almacenamiento local e IndexedDB. No contiene la colección de registros extraídos por el Spider. La guía también excluye pestañas, ajustes del navegador y sessionStorage. Trata el estado de autenticación y el destino de los registros como recursos separados de la aplicación. Nuestra prueba no ejecutó el guardado ni la restauración del estado de un navegador.

### ¿AutoThrottle conserva las esperas aprendidas al reanudar?

La guía oficial indica que las esperas aprendidas por AutoThrottle no se guardan en el checkpoint. Un rastreo reanudado empieza con la espera inicial configurada. Mantén la configuración prevista en tu spider y observa su comportamiento tras reiniciar. Es un límite documentado de la implementación: nuestra prueba con una sola solicitud simultánea no evaluó ni midió la adaptación de AutoThrottle.

### ¿Esta prueba demuestra la recuperación tras un corte eléctrico?

No. Usamos una pausa ordenada explícita, procesos nuevos de Python y la repetición deliberada desde nuestro propio checkpoint. No forzamos el cierre de un proceso mientras confirmaba una escritura en la base de datos, ni interrumpimos escrituras del almacenamiento ni cortamos la alimentación. El resultado muestra el comportamiento observado del checkpoint, la exportación y la tabla con claves en esos casos controlados. La durabilidad ante fallos abruptos requiere otra prueba con el almacenamiento y el entorno reales.

### ¿Un manifiesto demuestra que has encontrado todas las páginas de una web?

Un manifiesto permite comprobar que están todos los elementos de la población que enumera. Nuestra prueba define tres registros inmutables, así que podemos medir directamente qué identidades faltan. Una web desconocida puede tener paginación no descubierta, registros modificados o secciones inaccesibles. Define por separado el alcance y el método de descubrimiento, y después contrasta los registros exigidos por ese alcance. Superar una prueba de tres registros no demuestra la cobertura completa de otra web.

Modelos e infraestructura

## Qué leer después

Selección de modelos, economía de inferencia, despliegue local, compresión y serving.

[Empieza aquí**Alojar LLMs en la UE: Cuándo Salen a Cuenta los Open Weights**](/es/blog/self-hosting-llms-eu-cost/)

- [Cómo validar certificados de derivación de Open Ontologies](/es/blog/open-ontologies-proof-verification/)
- [Cue Turn Detection: teléfonos, benchmarks y límites](/es/blog/cue-turn-detection-phone-numbers/)
- [Google SAM ahora es Agent Mesh: MCP entre equipos](/es/blog/google-sam-agent-mesh-mcp-tools/)
- [EdgeQuake: GraphRAG en PostgreSQL y memoria MCP para agentes](/es/blog/edgequake-postgresql-graphrag-mcp-agent-memory/)
- [BitNet en CPU: 2B4T, requisitos de RAM y la cifra de 100B](/es/blog/bitnet-cpu-llm-ram-requirements/)

[Artículo anterior**Cómo validar certificados de derivación de Open Ontologies**](/es/blog/open-ontologies-proof-verification/) [Artículo siguiente**Cue Turn Detection: teléfonos, benchmarks y límites**](/es/blog/cue-turn-detection-phone-numbers/)

[**Volver**](/es/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/es/team/kevin-riedl/)

[Kevin Riedl](/es/team/kevin-riedl/) https://linkedin.com/in/wsdt

12 min de lectura · 3 nov 2026 Última revisión 3 de noviembre de 2026

[**Siguiente**](/es/blog/wigolo-local-web-intelligence-mcp-review/)
