feat(spiders): add simple export system for the results

This commit is contained in:
Karim shoair
2026-01-12 01:21:05 +02:00
parent a17bb1d976
commit 72c3c2792a
2 changed files with 41 additions and 5 deletions
+3 -3
View File
@@ -5,7 +5,7 @@ from anyio import create_task_group, CapacityLimiter
from scrapling.core.utils import log
from scrapling.spiders.request import Request
from scrapling.spiders.result import CrawlStats
from scrapling.spiders.result import CrawlStats, ItemList
from scrapling.spiders.scheduler import Scheduler
from scrapling.spiders.session import SessionManager
from scrapling.core._types import Dict, TYPE_CHECKING, Any
@@ -33,7 +33,7 @@ class CrawlerEngine:
self._active_tasks: int = 0
self._running: bool = False
self._items: list[dict[str, Any]] = []
self._items: ItemList = ItemList()
def _is_domain_allowed(self, request: Request) -> bool:
"""Check if the request's domain is in allowed_domains."""
@@ -161,6 +161,6 @@ class CrawlerEngine:
return self.stats
@property
def items(self) -> list[dict[str, Any]]:
def items(self) -> ItemList:
"""Access scraped items."""
return self._items
+38 -2
View File
@@ -1,6 +1,42 @@
from pathlib import Path
from dataclasses import dataclass, field
from scrapling.core._types import Any, Iterator, Dict, List, Tuple
import orjson
from scrapling.core.utils import log
from scrapling.core._types import Any, Iterator, Dict, List, Tuple, Union
class ItemList(list):
"""A list of scraped items with export capabilities."""
def to_json(self, path: Union[str, Path], *, indent: bool = False):
"""Export items to a JSON file.
:param path: Path to the output file
:param indent: Pretty-print with 2-space indentation (slightly slower)
:return: Number of items written
"""
options = orjson.OPT_SERIALIZE_NUMPY
if indent:
options |= orjson.OPT_INDENT_2
file = Path(path)
file.parent.mkdir(parents=True, exist_ok=True)
file.write_bytes(orjson.dumps(list(self), option=options))
log.info("Saved %d items to %s", len(self), path)
def to_jsonl(self, path: Union[str, Path]):
"""Export items as JSON Lines (one JSON object per line).
:param path: Path to the output file
"""
Path(path).parent.mkdir(parents=True, exist_ok=True)
with open(path, "wb") as f:
for item in self:
f.write(orjson.dumps(item, option=orjson.OPT_SERIALIZE_NUMPY))
f.write(b"\n")
log.info("Saved %d items to %s", len(self), path)
@dataclass
@@ -73,7 +109,7 @@ class CrawlResult:
"""Complete result from a spider run."""
stats: CrawlStats
items: list[dict[str, Any]]
items: ItemList
def __len__(self) -> int:
return len(self.items)