Crea tu propio sistema de almacenamiento¶
Scrapling usa SQLite de forma predeterminada. En esta guía aprenderás a crear tu propio sistema para guardar las propiedades de los elementos que usa la función adaptive.
Por ejemplo, puedes usar Firebase para compartir una base de datos entre varios spiders en distintas máquinas. Una base de datos en línea permite que los spiders compartan los datos adaptativos.
Para que tu clase de almacenamiento funcione, debe cumplir tres requisitos:
- Heredar de la clase abstracta
scrapling.core.storage.StorageSystemMixiny aceptar un argumento de cadenaurl, para mantener la lógica de la biblioteca. - Usar el decorador
functools.lru_cachesobre la clase para seguir el patrón Singleton, igual que las otras clases. - Implementar los métodos
saveyretrievesegún sus anotaciones de tipo:- El método
saveno devuelve nada y recibe dos argumentos de la biblioteca:- El primero es el propio elemento, de tipo
lxml.html.HtmlElement. Debes convertirlo en un diccionario con la funciónelement_to_dictdel submóduloscrapling.core.utils._StorageToolspara conservar el mismo formato. Después puedes guardarlo en tu base de datos. - El segundo es una cadena con el identificador que se usa para recuperarlo. La combinación de este identificador y el argumento
urlrecibido al crear la instancia debe ser única para cada fila. Si no lo es, se mezclarán los datos deadaptive.
- El primero es el propio elemento, de tipo
- El método
retrieverecibe una cadena con el identificador. Usa ese identificador junto con laurlrecibida al crear la instancia para recuperar el diccionario del elemento. Devuelve el diccionario si existe, oNonesi no lo encuentra.
- El método
Puedes ver un ejemplo con SQLite3 en el archivo storage_adaptors.
Si tu clase cumple estos requisitos, el resto es sencillo. Si vas a usar la biblioteca en una aplicación con varios hilos, asegúrate de que tu clase los admita de forma segura. La clase predeterminada ya lo hace.
La clase abstracta también incluye funciones auxiliares que puedes usar. Puedes verlas en el código, que tiene muchos comentarios :)
Ejemplo práctico: almacenamiento con Redis¶
Este es un ejemplo práctico con Redis, generado por IA:
import redis
import orjson
from functools import lru_cache
from scrapling.core.storage import StorageSystemMixin
from scrapling.core.utils import _StorageTools
@lru_cache(None)
class RedisStorage(StorageSystemMixin):
def __init__(self, host='localhost', port=6379, db=0, url=None):
super().__init__(url)
self.redis = redis.Redis(
host=host,
port=port,
db=db,
decode_responses=False
)
def save(self, element, identifier: str) -> None:
# Convert element to dictionary
element_dict = _StorageTools.element_to_dict(element)
# Create key
key = f"scrapling:{self._get_base_url()}:{identifier}"
# Store as JSON
self.redis.set(
key,
orjson.dumps(element_dict)
)
def retrieve(self, identifier: str) -> dict | None:
# Get data
key = f"scrapling:{self._get_base_url()}:{identifier}"
data = self.redis.get(key)
# Parse JSON if exists
if data:
return orjson.loads(data)
return None