Ein eigenes Speichersystem schreiben¶
Scrapling verwendet standardmäßig SQLite. Diese Anleitung zeigt, wie Sie ein eigenes Speichersystem für die Elementeigenschaften der Funktion adaptive schreiben.
Vielleicht möchten Sie zum Beispiel Firebase verwenden und eine Datenbank zwischen Spidern auf verschiedenen Rechnern teilen. Mit einer solchen Onlinedatenbank können die Spider ihre adaptiven Daten gemeinsam nutzen.
Ihre Speicherklasse muss zuerst drei Anforderungen erfüllen:
- Sie erbt von der abstrakten Klasse
scrapling.core.storage.StorageSystemMixinund nimmt das String-Argumenturlan, damit die Logik der Bibliothek erhalten bleibt. - Sie verwendet den Dekorator
functools.lru_cacheüber der Klasse, um wie die anderen Klassen dem Singleton-Entwurfsmuster zu folgen. - Sie implementiert die Methoden
saveundretrieve, wie in den Typannotationen angegeben:- Die Methode
savegibt nichts zurück und erhält zwei Argumente von der Bibliothek.- Das erste ist das Element selbst, vom Typ
lxml.html.HtmlElement. Es muss mit der Funktionelement_to_dictaus dem Untermodulscrapling.core.utils._StorageToolsin ein Dictionary umgewandelt werden. So bleibt das Format gleich. Danach speichern Sie es in Ihrer Datenbank. - Das zweite ist ein String mit der Kennung zum späteren Abrufen. Die Kombination dieser Kennung mit dem bei der Initialisierung übergebenen Argument
urlmuss für jede Zeile eindeutig sein. Sonst werden die Daten füradaptivefalsch zugeordnet.
- Das erste ist das Element selbst, vom Typ
- Die Methode
retrieveerhält die Kennung als String. Zusammen mit der bei der Initialisierung übergebenenurlruft sie das Dictionary des Elements aus der Datenbank ab und gibt es zurück. Wenn kein Eintrag vorhanden ist, gibt sieNonezurück.
- Die Methode
Falls die Schritte noch unklar sind, sehen Sie sich meine SQLite3-Implementierung in der Datei storage_adaptors an.
Wenn Ihre Klasse diese Anforderungen erfüllt, ist der Rest einfach. Soll die Bibliothek in einer Anwendung mit mehreren Threads laufen, muss Ihre Klasse das unterstützen. Die Standardklasse ist threadsicher.
Die abstrakte Klasse enthält auch einige Hilfsfunktionen, die Sie verwenden können. Sehen Sie sich am besten den ausführlich kommentierten Code an :)
Praxisbeispiel: Redis als Speicher¶
Hier ist ein praktisches, von KI erstelltes Beispiel mit Redis:
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