From 6a73f9dcd78ab81be81b01f3d09cf29602d777fe Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 00:52:06 +0200 Subject: [PATCH 01/80] refactor: internal API changes to be easily used as indicators for spiders --- scrapling/engines/_browsers/_base.py | 12 ++++---- scrapling/engines/_browsers/_controllers.py | 9 ++++-- scrapling/engines/_browsers/_stealth.py | 5 ++- scrapling/engines/static.py | 34 ++++++++++++--------- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index bb14b5f..cbbdc24 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -37,14 +37,14 @@ class SyncSession: self._max_wait_for_page = 60 self.playwright: Playwright | Any = None self.context: BrowserContext | Any = None - self._closed = False + self._is_alive = False def start(self): pass def close(self): # pragma: no cover """Close all resources""" - if self._closed: + if not self._is_alive: return if self.context: @@ -55,7 +55,7 @@ class SyncSession: self.playwright.stop() self.playwright = None # pyright: ignore - self._closed = True + self._is_alive = False def __enter__(self): self.start() @@ -137,7 +137,7 @@ class AsyncSession: self._max_wait_for_page = 60 self.playwright: AsyncPlaywright | Any = None self.context: AsyncBrowserContext | Any = None - self._closed = False + self._is_alive = False self._lock = Lock() async def start(self): @@ -145,7 +145,7 @@ class AsyncSession: async def close(self): """Close all resources""" - if self._closed: # pragma: no cover + if not self._is_alive: # pragma: no cover return if self.context: @@ -156,7 +156,7 @@ class AsyncSession: await self.playwright.stop() self.playwright = None # pyright: ignore - self._closed = True + self._is_alive = False async def __aenter__(self): await self.start() diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index ff21438..285bb32 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -31,7 +31,6 @@ class DynamicSession(SyncSession, DynamicSessionMixin): "_max_wait_for_page", "playwright", "context", - "_closed", ) def __init__(self, **kwargs: Unpack[PlaywrightSession]): @@ -82,6 +81,8 @@ class DynamicSession(SyncSession, DynamicSessionMixin): if self._config.cookies: # pragma: no cover self.context.add_cookies(self._config.cookies) + + self._is_alive = True else: raise RuntimeError("Session has been already started") @@ -104,7 +105,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): :return: A `Response` object. """ params = _validate(kwargs, self, PlaywrightConfig) - if self._closed: # pragma: no cover + if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") referer = ( @@ -211,6 +212,8 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): if self._config.cookies: await self.context.add_cookies(self._config.cookies) # pyright: ignore + + self._is_alive = True else: raise RuntimeError("Session has been already started") @@ -234,7 +237,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): """ params = _validate(kwargs, self, PlaywrightConfig) - if self._closed: # pragma: no cover + if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") referer = ( diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 912d38e..1cce675 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -39,7 +39,6 @@ class StealthySession(SyncSession, StealthySessionMixin): "_max_wait_for_page", "playwright", "context", - "_closed", ) def __init__(self, **kwargs: Unpack[StealthSession]): @@ -191,7 +190,7 @@ class StealthySession(SyncSession, StealthySessionMixin): :return: A `Response` object. """ params = _validate(kwargs, self, StealthConfig) - if self._closed: # pragma: no cover + if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") referer = ( @@ -404,7 +403,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): """ params = _validate(kwargs, self, StealthConfig) - if self._closed: # pragma: no cover + if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") referer = ( diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index c7afa79..2386820 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -62,6 +62,7 @@ class _ConfigurationLogic(ABC): "_default_cert", "_default_http3", "selector_config", + "_is_alive", ) def __init__(self, **kwargs: Unpack[RequestsSession]): @@ -80,6 +81,7 @@ class _ConfigurationLogic(ABC): self._default_cert = kwargs.get("cert") or None self._default_http3 = kwargs.get("http3", False) self.selector_config = kwargs.get("selector_config") or {} + self._is_alive = False @staticmethod def _get_param(kwargs: Dict, key: str, default: Any) -> Any: @@ -183,10 +185,11 @@ class _SyncSessionLogic(_ConfigurationLogic): def __enter__(self): """Creates and returns a new synchronous Fetcher Session""" - if self._curl_session: + if self._is_alive: raise RuntimeError("This FetcherSession instance already has an active synchronous session.") self._curl_session = CurlSession() + self._is_alive = True return self def __exit__(self, exc_type, exc_val, exc_tb): @@ -201,7 +204,9 @@ class _SyncSessionLogic(_ConfigurationLogic): self._curl_session.close() self._curl_session = None - def __make_request(self, method: SUPPORTED_HTTP_METHODS, stealth: Optional[bool] = None, **kwargs) -> Response: + self._is_alive = False + + def _make_request(self, method: SUPPORTED_HTTP_METHODS, stealth: Optional[bool] = None, **kwargs) -> Response: """ Perform an HTTP request using the configured session. """ @@ -267,7 +272,7 @@ class _SyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("GET", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("GET", stealth=stealthy_headers, url=url, **kwargs) def post(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Response: """ @@ -299,7 +304,7 @@ class _SyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("POST", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("POST", stealth=stealthy_headers, url=url, **kwargs) def put(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Response: """ @@ -331,7 +336,7 @@ class _SyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("PUT", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("PUT", stealth=stealthy_headers, url=url, **kwargs) def delete(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Response: """ @@ -365,7 +370,7 @@ class _SyncSessionLogic(_ConfigurationLogic): # Careful of sending a body in a DELETE request, it might cause some websites to reject the request as per https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5, # But some websites accept it, it depends on the implementation used. stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("DELETE", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("DELETE", stealth=stealthy_headers, url=url, **kwargs) class _ASyncSessionLogic(_ConfigurationLogic): @@ -377,10 +382,11 @@ class _ASyncSessionLogic(_ConfigurationLogic): async def __aenter__(self): # pragma: no cover """Creates and returns a new asynchronous Session.""" - if self._async_curl_session: + if self._is_alive: raise RuntimeError("This FetcherSession instance already has an active asynchronous session.") self._async_curl_session = AsyncCurlSession() + self._is_alive = True return self async def __aexit__(self, exc_type, exc_val, exc_tb): @@ -395,9 +401,9 @@ class _ASyncSessionLogic(_ConfigurationLogic): await self._async_curl_session.close() self._async_curl_session = None - async def __make_request( - self, method: SUPPORTED_HTTP_METHODS, stealth: Optional[bool] = None, **kwargs - ) -> Response: + self._is_alive = False + + async def _make_request(self, method: SUPPORTED_HTTP_METHODS, stealth: Optional[bool] = None, **kwargs) -> Response: """ Perform an HTTP request using the configured session. """ @@ -465,7 +471,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("GET", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("GET", stealth=stealthy_headers, url=url, **kwargs) def post(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Awaitable[Response]: """ @@ -497,7 +503,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("POST", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("POST", stealth=stealthy_headers, url=url, **kwargs) def put(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Awaitable[Response]: """ @@ -529,7 +535,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): :return: A `Response` object. """ stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("PUT", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("PUT", stealth=stealthy_headers, url=url, **kwargs) def delete(self, url: str, **kwargs: Unpack[DataRequestParams]) -> Awaitable[Response]: """ @@ -563,7 +569,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): # Careful of sending a body in a DELETE request, it might cause some websites to reject the request as per https://www.rfc-editor.org/rfc/rfc7231#section-4.3.5, # But some websites accept it, it depends on the implementation used. stealthy_headers = kwargs.pop("stealthy_headers", None) - return self.__make_request("DELETE", stealth=stealthy_headers, url=url, **kwargs) + return self._make_request("DELETE", stealth=stealthy_headers, url=url, **kwargs) class FetcherSession: From 9eb5f68fcb530a36ca5bf5e6ad4169a67a653ec3 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 00:52:35 +0200 Subject: [PATCH 02/80] test: update tests accordingly --- tests/fetchers/async/test_dynamic_session.py | 2 +- tests/fetchers/async/test_stealth_session.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fetchers/async/test_dynamic_session.py b/tests/fetchers/async/test_dynamic_session.py index c403017..95bb289 100644 --- a/tests/fetchers/async/test_dynamic_session.py +++ b/tests/fetchers/async/test_dynamic_session.py @@ -43,7 +43,7 @@ class TestAsyncDynamicSession: assert stats["total_pages"] <= 3 # After exit, should be closed - assert session._closed is True + assert session._is_alive is False # Should raise RuntimeError when used after closing with pytest.raises(RuntimeError): diff --git a/tests/fetchers/async/test_stealth_session.py b/tests/fetchers/async/test_stealth_session.py index 140742d..db79002 100644 --- a/tests/fetchers/async/test_stealth_session.py +++ b/tests/fetchers/async/test_stealth_session.py @@ -44,7 +44,7 @@ class TestAsyncStealthySession: assert stats["total_pages"] <= 3 # After exit, should be closed - assert session._closed is True + assert session._is_alive is False # Should raise RuntimeError when used after closing with pytest.raises(RuntimeError): From 6553d90e0f72e7d8342b8ecf232bd24d9f15d971 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 00:53:29 +0200 Subject: [PATCH 03/80] ops: update workflows to run for this branch --- .github/workflows/code-quality.yml | 1 + .github/workflows/tests.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 8d15d0c..6e15d6a 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -5,6 +5,7 @@ on: branches: - main - dev + - v4 paths-ignore: - '*.md' - '**/*.md' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index be3bbca..22d8b8b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,6 +4,7 @@ on: branches: - main - dev + - v4 paths-ignore: - '*.md' - '**/*.md' From 08f3e6efad48b426bdc1dfc6619622e33753b120 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 01:01:00 +0200 Subject: [PATCH 04/80] fix: add missing line --- scrapling/engines/_browsers/_stealth.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 1cce675..e191059 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -96,6 +96,8 @@ class StealthySession(SyncSession, StealthySessionMixin): if self._config.cookies: # pragma: no cover self.context.add_cookies(self._config.cookies) + + self._is_alive = True else: raise RuntimeError("Session has been already started") @@ -308,6 +310,8 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): if self._config.cookies: await self.context.add_cookies(self._config.cookies) # pyright: ignore + + self._is_alive = True else: raise RuntimeError("Session has been already started") From 3a360acced3f97893a2feb9d43e8fbb65a960b57 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 01:37:47 +0200 Subject: [PATCH 05/80] build: pump version up temporary --- pyproject.toml | 2 +- scrapling/__init__.py | 2 +- setup.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f6fb8ab..e16895c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "scrapling" # Static version instead of a dynamic version so we can get better layer caching while building docker, check the docker file to understand -version = "0.3.14" +version = "0.4beta" description = "Scrapling is an undetectable, powerful, flexible, high-performance Python library that makes Web Scraping easy and effortless as it should be!" readme = {file = "docs/README.md", content-type = "text/markdown"} license = {file = "LICENSE"} diff --git a/scrapling/__init__.py b/scrapling/__init__.py index 2425686..ce26cba 100644 --- a/scrapling/__init__.py +++ b/scrapling/__init__.py @@ -1,5 +1,5 @@ __author__ = "Karim Shoair (karim.shoair@pm.me)" -__version__ = "0.3.14" +__version__ = "0.4beta" __copyright__ = "Copyright (c) 2024 Karim Shoair" from typing import Any, TYPE_CHECKING diff --git a/setup.cfg b/setup.cfg index 23fdc33..e4b4fc0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = scrapling -version = 0.3.14 +version = 0.4beta author = Karim Shoair author_email = karim.shoair@pm.me description = Scrapling is an undetectable, powerful, flexible, high-performance Python library that makes Web Scraping easy and effortless as it should be! From f80e8828f78177d2248224141554816834abc431 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 8 Jan 2026 01:53:48 +0200 Subject: [PATCH 06/80] refactor: internal API changes --- scrapling/engines/static.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index 2386820..ca7c7a6 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -600,6 +600,7 @@ class FetcherSession: "_default_http3", "selector_config", "_client", + "_is_alive", ) def __init__( @@ -653,6 +654,7 @@ class FetcherSession: self._default_cert = cert self._default_http3 = http3 self.selector_config = selector_config or {} + self._is_alive = False self._client: _SyncSessionLogic | _ASyncSessionLogic | None = None def __enter__(self) -> _SyncSessionLogic: @@ -663,6 +665,7 @@ class FetcherSession: config["stealthy_headers"] = self._stealth config["selector_config"] = self.selector_config self._client = _SyncSessionLogic(**config) + self._is_alive = True return self._client.__enter__() raise RuntimeError("This FetcherSession instance already has an active synchronous session.") @@ -670,6 +673,7 @@ class FetcherSession: if self._client is not None and isinstance(self._client, _SyncSessionLogic): self._client.__exit__(exc_type, exc_val, exc_tb) self._client = None + self._is_alive = False return raise RuntimeError("Cannot exit invalid session") @@ -681,6 +685,7 @@ class FetcherSession: config["stealthy_headers"] = self._stealth config["selector_config"] = self.selector_config self._client = _ASyncSessionLogic(**config) + self._is_alive = True return await self._client.__aenter__() raise RuntimeError("This FetcherSession instance already has an active asynchronous session.") @@ -688,6 +693,7 @@ class FetcherSession: if self._client is not None and isinstance(self._client, _ASyncSessionLogic): await self._client.__aexit__(exc_type, exc_val, exc_tb) self._client = None + self._is_alive = False return raise RuntimeError("Cannot exit invalid session") From 0634f5796cd3d7231feea94332def90578507791 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 10 Jan 2026 20:39:43 +0200 Subject: [PATCH 07/80] feat(spiders): Add follow function to the response --- scrapling/core/_types.py | 1 + scrapling/engines/toolbelt/custom.py | 55 +++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/scrapling/core/_types.py b/scrapling/core/_types.py index d7c1f8b..c897954 100644 --- a/scrapling/core/_types.py +++ b/scrapling/core/_types.py @@ -12,6 +12,7 @@ from typing import ( Callable, Dict, Generator, + AsyncGenerator, Generic, Iterable, List, diff --git a/scrapling/engines/toolbelt/custom.py b/scrapling/engines/toolbelt/custom.py index d1f95b7..754d9f2 100644 --- a/scrapling/engines/toolbelt/custom.py +++ b/scrapling/engines/toolbelt/custom.py @@ -10,12 +10,19 @@ from scrapling.core._types import ( Dict, cast, List, - Optional, Tuple, + Union, + Optional, + Callable, + TYPE_CHECKING, + AsyncGenerator, ) from scrapling.core.custom_types import MappingProxyType from scrapling.parser import Selector, SQLiteStorageSystem +if TYPE_CHECKING: + from scrapling.spiders import Request + class Response(Selector): """This class is returned by all engines as a way to unify the response type between different libraries.""" @@ -50,6 +57,52 @@ class Response(Selector): # For easier debugging while working from a Python shell log.info(f"Fetched ({status}) <{method} {url}> (referer: {request_headers.get('referer')})") + self.meta: Dict[str, Any] = {} + self.request: Optional["Request"] = None # Will be set by crawler + + def follow( + self, + url: str, + sid: str = "", + callback: Callable[["Response"], AsyncGenerator[Union[Dict[str, Any], "Request", None], None]] | None = None, + priority: int | None = None, + dont_filter: bool = False, + meta: dict[str, Any] | None = None, + **kwargs: Any, + ) -> Any: + """Create a Request to follow a URL. + + This is a helper method for spiders to easily follow links found in pages. + + **IMPORTANT**: The below arguments if left empty, the corresponding value from the previous request will be used. The only exception is `dont_filter`. + + :param url: The URL to follow (can be relative, will be joined with current URL) + :param sid: The session id to use + :param callback: Spider callback method to use + :param priority: The priority number to use, the higher the number, the higher priority to be processed first. + :param dont_filter: If this request has been done before, disable the filter to allow it again. + :param meta: Additional meta data to included in the request + :param kwargs: Additional Request arguments + :return: Request object ready to be yielded + """ + from scrapling.spiders import Request + + if not self.request or not isinstance(self.request, Request): + raise TypeError("This response has no request set yet.") + + return Request( + url=self.urljoin(url), + sid=sid or self.request.sid, + callback=callback or self.request.callback, + priority=priority if priority is not None else self.request.priority, + dont_filter=dont_filter, + meta={**(self.meta or {}), **(meta or {})}, + **(kwargs if kwargs else self.request._session_kwargs), + ) + + def __str__(self) -> str: + return f"<{self.status} {self.url}>" + class BaseFetcher: __slots__ = () From 8e3696217763c5b1656354d6daaefeaa5dda42f5 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 10 Jan 2026 20:41:23 +0200 Subject: [PATCH 08/80] ops: add local Claude files to gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 7890c42..0cd51e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# AI related files +.claude/* +CLAUDE.md + # cached files __pycache__/ *.py[cod] From c5bc82deb8134bc96db88c26a0a6fb1062422d99 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 03:21:03 +0200 Subject: [PATCH 09/80] fix(browsers): solve a bug with setting referer on the request level --- scrapling/core/_types.py | 1 + scrapling/engines/_browsers/_controllers.py | 10 ++++++++-- scrapling/engines/_browsers/_stealth.py | 10 ++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/scrapling/core/_types.py b/scrapling/core/_types.py index c897954..48a2eec 100644 --- a/scrapling/core/_types.py +++ b/scrapling/core/_types.py @@ -19,6 +19,7 @@ from typing import ( Set, Literal, Optional, + Iterator, Pattern, Sequence, Tuple, diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index 285bb32..aef197a 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -108,8 +108,11 @@ class DynamicSession(SyncSession, DynamicSessionMixin): if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") + request_headers_keys = {h.lower() for h in params.extra_headers.keys()} if params.extra_headers else set() referer = ( - generate_convincing_referer(url) if (params.google_search and "referer" not in self._headers_keys) else None + generate_convincing_referer(url) + if (params.google_search and "referer" not in request_headers_keys) + else None ) page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) @@ -240,8 +243,11 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") + request_headers_keys = {h.lower() for h in params.extra_headers.keys()} if params.extra_headers else set() referer = ( - generate_convincing_referer(url) if (params.google_search and "referer" not in self._headers_keys) else None + generate_convincing_referer(url) + if (params.google_search and "referer" not in request_headers_keys) + else None ) page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index e191059..6883fdf 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -195,8 +195,11 @@ class StealthySession(SyncSession, StealthySessionMixin): if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") + request_headers_keys = {h.lower() for h in params.extra_headers.keys()} if params.extra_headers else set() referer = ( - generate_convincing_referer(url) if (params.google_search and "referer" not in self._headers_keys) else None + generate_convincing_referer(url) + if (params.google_search and "referer" not in request_headers_keys) + else None ) page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) @@ -410,8 +413,11 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") + request_headers_keys = {h.lower() for h in params.extra_headers.keys()} if params.extra_headers else set() referer = ( - generate_convincing_referer(url) if (params.google_search and "referer" not in self._headers_keys) else None + generate_convincing_referer(url) + if (params.google_search and "referer" not in request_headers_keys) + else None ) page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) From aa4817f34969be3e49cba7061c827037ea2c2f2e Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 03:22:20 +0200 Subject: [PATCH 10/80] feat: Change logger to be flexible enough for the spiders classes --- scrapling/core/utils/__init__.py | 2 ++ scrapling/core/utils/_utils.py | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/scrapling/core/utils/__init__.py b/scrapling/core/utils/__init__.py index 6ae80fe..77766c3 100644 --- a/scrapling/core/utils/__init__.py +++ b/scrapling/core/utils/__init__.py @@ -1,5 +1,7 @@ from ._utils import ( log, + set_logger, + reset_logger, __CONSECUTIVE_SPACES_REGEX__, flatten, _is_iterable, diff --git a/scrapling/core/utils/_utils.py b/scrapling/core/utils/_utils.py index 2f57cfa..a2fa6ca 100644 --- a/scrapling/core/utils/_utils.py +++ b/scrapling/core/utils/_utils.py @@ -1,6 +1,7 @@ import logging from itertools import chain from re import compile as re_compile +from contextvars import ContextVar, Token from lxml import html @@ -36,7 +37,25 @@ def setup_logger(): return logger -log = setup_logger() +_current_logger: ContextVar[logging.Logger] = ContextVar("scrapling_logger", default=setup_logger()) + + +class LoggerProxy: + def __getattr__(self, name: str): + return getattr(_current_logger.get(), name) + + +log = LoggerProxy() + + +def set_logger(logger: logging.Logger) -> Token: + """Set the current context logger. Returns token for reset.""" + return _current_logger.set(logger) + + +def reset_logger(token: Token) -> None: + """Reset logger to previous state using token.""" + _current_logger.reset(token) def flatten(lst: Iterable[Any]) -> List[Any]: From 1443a469a31dd40363f0a8879c3b4a07e36340e6 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 03:22:51 +0200 Subject: [PATCH 11/80] fix: handle a bug with response follow referer flow argument --- scrapling/engines/static.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index ca7c7a6..46eab23 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -136,6 +136,9 @@ class _ConfigurationLogic(ABC): "retries", "retry_delay", "selector_config", + # Browser session params (ignored by HTTP sessions) + "extra_headers", + "google_search", } for k, v in method_kwargs.items(): if k not in skip_keys and v is not None: From dd5c30c5212203aa40ccaac546a61c90649aa81e Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 03:24:30 +0200 Subject: [PATCH 12/80] feat(response): Option to set the referer as the previous response url. --- scrapling/engines/toolbelt/custom.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scrapling/engines/toolbelt/custom.py b/scrapling/engines/toolbelt/custom.py index 754d9f2..f5b8f62 100644 --- a/scrapling/engines/toolbelt/custom.py +++ b/scrapling/engines/toolbelt/custom.py @@ -68,6 +68,7 @@ class Response(Selector): priority: int | None = None, dont_filter: bool = False, meta: dict[str, Any] | None = None, + referer_flow: bool = True, **kwargs: Any, ) -> Any: """Create a Request to follow a URL. @@ -82,6 +83,7 @@ class Response(Selector): :param priority: The priority number to use, the higher the number, the higher priority to be processed first. :param dont_filter: If this request has been done before, disable the filter to allow it again. :param meta: Additional meta data to included in the request + :param referer_flow: Enabled by default, set the current response url as referer for the new request url. :param kwargs: Additional Request arguments :return: Request object ready to be yielded """ @@ -90,6 +92,22 @@ class Response(Selector): if not self.request or not isinstance(self.request, Request): raise TypeError("This response has no request set yet.") + # Merge original session kwargs with new kwargs (new takes precedence) + session_kwargs = {**self.request._session_kwargs, **kwargs} + + if referer_flow: + # For requests + headers = session_kwargs.get("headers", {}) + headers["referer"] = self.url + session_kwargs["headers"] = headers + + # For browsers + extra_headers = session_kwargs.get("extra_headers", {}) + extra_headers["referer"] = self.url + session_kwargs["extra_headers"] = extra_headers + + session_kwargs["google_search"] = False + return Request( url=self.urljoin(url), sid=sid or self.request.sid, @@ -97,7 +115,7 @@ class Response(Selector): priority=priority if priority is not None else self.request.priority, dont_filter=dont_filter, meta={**(self.meta or {}), **(meta or {})}, - **(kwargs if kwargs else self.request._session_kwargs), + **session_kwargs, ) def __str__(self) -> str: From 059a708b6de381d9d4b0a705d1b45e648f246bf3 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 16:53:18 +0200 Subject: [PATCH 13/80] feat(spiders system): a prototype of the new spiders system - A modern spider design that uses AnyIO and asyncio, yet it's very similar to Scrapy spiders API because it's the easiest design for users, and to make it easier for new users. - Spiders can have multiple sessions per crawl, and users decide which session to use with each request. - A scheduler system that uses heapq logic. - The user can set the number of concurrent requests for a spider globally or per domain. - The user can set a download delay to control the speed of the spider more. - There's a global function that can be overridden to handle errors for all requests. (Similar to errback in scrapy). - There's a spider argument to set the allowed domains for the spider to stay in. - Each spider has a very detailed crawl stats that can be accessed right away from the code after the crawl finishes. Same case with scraped items. - The whole spider as written as any other script and you just run it. No command-line arguments, and no need to run it from the terminal through the library like other known alternatives. - Each spider has its own logger that forces sessions to use it. - Each spider has functions to override that run before start and after close. - There's a spider argument to set the logging level and another one to make the spider write to a log file. - This is only the start. A lot more features are coming in the way. --- scrapling/spiders/__init__.py | 20 ++++ scrapling/spiders/engine.py | 153 ++++++++++++++++++++++++ scrapling/spiders/request.py | 59 ++++++++++ scrapling/spiders/result.py | 82 +++++++++++++ scrapling/spiders/scheduler.py | 45 +++++++ scrapling/spiders/session.py | 129 +++++++++++++++++++++ scrapling/spiders/spider.py | 206 +++++++++++++++++++++++++++++++++ 7 files changed, 694 insertions(+) create mode 100644 scrapling/spiders/__init__.py create mode 100644 scrapling/spiders/engine.py create mode 100644 scrapling/spiders/request.py create mode 100644 scrapling/spiders/result.py create mode 100644 scrapling/spiders/scheduler.py create mode 100644 scrapling/spiders/session.py create mode 100644 scrapling/spiders/spider.py diff --git a/scrapling/spiders/__init__.py b/scrapling/spiders/__init__.py new file mode 100644 index 0000000..ee3c00c --- /dev/null +++ b/scrapling/spiders/__init__.py @@ -0,0 +1,20 @@ +from .spider import Spider, SessionConfigurationError, LogCounterHandler +from .request import Request +from .result import CrawlStats, CrawlResult +from .engine import CrawlerEngine +from .session import SessionManager +from .scheduler import Scheduler +from scrapling.engines.toolbelt.custom import Response + +__all__ = [ + "Spider", + "SessionConfigurationError", + "LogCounterHandler", + "Request", + "CrawlerEngine", + "CrawlStats", + "CrawlResult", + "SessionManager", + "Scheduler", + "Response", +] diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py new file mode 100644 index 0000000..e4210e9 --- /dev/null +++ b/scrapling/spiders/engine.py @@ -0,0 +1,153 @@ +"""Crawler engine that orchestrates the crawling process.""" + +import json + +import anyio +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.scheduler import Scheduler +from scrapling.spiders.session import SessionManager +from scrapling.core._types import Dict, TYPE_CHECKING, Any + +if TYPE_CHECKING: + from scrapling.spiders.spider import Spider + + +def _dump(obj: Dict) -> str: + return json.dumps(obj, indent=4) + + +class CrawlerEngine: + """Orchestrates the crawling process.""" + + def __init__(self, spider: "Spider", session_manager: SessionManager, scheduler: Scheduler | None = None): + self.spider = spider + self.session_manager = session_manager + self.scheduler = scheduler or Scheduler() + self.stats = CrawlStats() + + self._global_limiter = CapacityLimiter(spider.concurrent_requests) + self._domain_limiters: dict[str, CapacityLimiter] = {} + self._allowed_domains: set[str] = spider.allowed_domains or set() + + self._active_tasks: int = 0 + self._running: bool = False + self._items: list[dict[str, Any]] = [] + + def _is_domain_allowed(self, request: Request) -> bool: + """Check if the request's domain is in allowed_domains.""" + if not self._allowed_domains: + return True + + domain = request.domain + for allowed in self._allowed_domains: + if domain == allowed or domain.endswith("." + allowed): + return True + return False + + def _rate_limiter(self, domain: str) -> CapacityLimiter: + """Get or create a per-domain concurrency limiter if enabled, otherwise use the global limiter.""" + if self.spider.concurrent_requests_per_domain: + if domain not in self._domain_limiters: + self._domain_limiters[domain] = CapacityLimiter(self.spider.concurrent_requests_per_domain) + return self._domain_limiters[domain] + return self._global_limiter + + async def _process_request(self, request: Request) -> None: + """Download and process a single request.""" + async with self._rate_limiter(request.domain): + if self.spider.download_delay: + await anyio.sleep(self.spider.download_delay) + + if request._session_kwargs.get("proxy"): + self.stats.proxies.append(request._session_kwargs["proxy"]) + if request._session_kwargs.get("proxies"): + self.stats.proxies.append(dict(request._session_kwargs["proxies"])) + try: + response = await self.session_manager.fetch(request) + self.stats.increment_requests_count(request.sid) + self.stats.increment_response_bytes(request.domain, len(response.body)) + self.stats.increment_status(response.status) + + except Exception as e: + self.stats.failed_requests_count += 1 + await self.spider.on_error(request, e) + return + + # Process response through callback + callback = request.callback if request.callback else self.spider.parse + try: + async for result in callback(response): + if isinstance(result, Request): + if self._is_domain_allowed(result): + await self.scheduler.enqueue(result) + else: + self.stats.offsite_requests_count += 1 + log.debug(f"Filtered offsite request to: {result.url}") + elif isinstance(result, dict): + await self._handle_item(result) + log.debug(f"Scraped from {str(response)}\n{result}") + except Exception as e: + await self.spider.on_error(request, e) + + async def _handle_item(self, item: dict[str, Any]) -> None: + """Handle a scraped item. Override or extend for item pipelines.""" + self.stats.items_scraped += 1 + self._items.append(item) + + async def _task_wrapper(self, request: Request) -> None: + """Wrapper to track active task count.""" + try: + await self._process_request(request) + finally: + self._active_tasks -= 1 + + async def crawl(self) -> CrawlStats: + """Run the spider and return CrawlStats.""" + self._running = True + self._items.clear() + self.stats = CrawlStats(start_time=anyio.current_time()) + + async with self.session_manager: + self.stats.concurrent_requests = self.spider.concurrent_requests + self.stats.concurrent_requests_per_domain = self.spider.concurrent_requests_per_domain + self.stats.download_delay = self.spider.download_delay + await self.spider.on_start() + + try: + async for request in self.spider.start_requests(): + await self.scheduler.enqueue(request) + + # Process queue + async with create_task_group() as tg: + while self._running: + if self.scheduler.is_empty: + # Empty queue + no active tasks = done + if self._active_tasks == 0: + self._running = False + log.debug("Spider idle") + break + + # Brief wait for callbacks to enqueue new requests + await anyio.sleep(0.05) + continue + + request = await self.scheduler.dequeue() + self._active_tasks += 1 + tg.start_soon(self._task_wrapper, request) + + finally: + await self.spider.on_close() + + self.stats.log_levels_counter = self.spider._log_counter.get_counts() + self.stats.end_time = anyio.current_time() + log.info(_dump(self.stats.to_dict())) + return self.stats + + @property + def items(self) -> list[dict[str, Any]]: + """Access scraped items.""" + return self._items diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py new file mode 100644 index 0000000..495c73f --- /dev/null +++ b/scrapling/spiders/request.py @@ -0,0 +1,59 @@ +from urllib.parse import urlparse + +from scrapling.engines.toolbelt.custom import Response +from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union + + +class Request: + def __init__( + self, + url: str, + sid: str = "", + callback: Callable[[Response], AsyncGenerator[Union[Dict[str, Any], "Request", None], None]] | None = None, + priority: int = 0, + dont_filter: bool = False, + meta: dict[str, Any] | None = None, + **kwargs: Any, + ) -> None: + self.url: str = url + self.sid: str = sid + self.callback = callback + self.priority: int = priority + self.dont_filter: bool = dont_filter + self.meta: dict[str, Any] = meta if meta else {} + self._session_kwargs = kwargs if kwargs else {} + + @property + def domain(self) -> str: + return urlparse(self.url).netloc + + @property + def _fp(self) -> str: + """Generate a unique fingerprint for deduplication.""" + # TODO: Improve fingerprint + return f"{self.sid}:{self.url}" + + def __repr__(self) -> str: + callback_name = getattr(self.callback, "__name__", None) or "None" + return f"" + + def __str__(self) -> str: + return self.url + + def __lt__(self, other: object) -> bool: + """Compare requests by priority""" + if not isinstance(other, Request): + return NotImplemented + return self.priority < other.priority + + def __gt__(self, other: object) -> bool: + """Compare requests by priority""" + if not isinstance(other, Request): + return NotImplemented + return self.priority > other.priority + + def __eq__(self, other: object) -> bool: + """Requests are equal if they have the same fingerprint.""" + if not isinstance(other, Request): + return NotImplemented + return self._fp == other._fp diff --git a/scrapling/spiders/result.py b/scrapling/spiders/result.py new file mode 100644 index 0000000..d36b0ad --- /dev/null +++ b/scrapling/spiders/result.py @@ -0,0 +1,82 @@ +from dataclasses import dataclass, field + +from scrapling.core._types import Any, Iterator, Dict, List, Tuple + + +@dataclass +class CrawlStats: + """Statistics for a crawl run.""" + + requests_count: int = 0 + concurrent_requests: int = 0 + concurrent_requests_per_domain: int = 0 + failed_requests_count: int = 0 + offsite_requests_count: int = 0 + response_bytes: int = 0 + items_scraped: int = 0 + start_time: float = 0.0 + end_time: float = 0.0 + download_delay: float = 0.0 + blocked_requests_count: int = 0 + custom_stats: Dict = field(default_factory=dict) + response_status_count: Dict = field(default_factory=dict) + domains_response_bytes: Dict = field(default_factory=dict) + sessions_requests_count: Dict = field(default_factory=dict) + proxies: List[str | Dict | Tuple] = field(default_factory=list) + log_levels_counter: Dict = field(default_factory=dict) + + @property + def elapsed_seconds(self) -> float: + return self.end_time - self.start_time + + @property + def requests_per_second(self) -> float: + if self.elapsed_seconds == 0: + return 0.0 + return self.requests_count / self.elapsed_seconds + + def increment_status(self, status: int) -> None: + self.response_status_count[f"status_{status}"] = self.response_status_count.get(f"status_{status}", 0) + 1 + + def increment_response_bytes(self, domain: str, count: int) -> None: + self.response_bytes += count + self.domains_response_bytes[domain] = self.domains_response_bytes.get(domain, 0) + count + + def increment_requests_count(self, sid: str) -> None: + self.requests_count += 1 + self.sessions_requests_count[sid] = self.sessions_requests_count.get(sid, 0) + 1 + + def to_dict(self) -> dict[str, Any]: + return { + "items_scraped": self.items_scraped, + "elapsed_seconds": round(self.elapsed_seconds, 2), + "download_delay": round(self.download_delay, 2), + "concurrent_requests": self.concurrent_requests, + "concurrent_requests_per_domain": self.concurrent_requests_per_domain, + "requests_count": self.requests_count, + "requests_per_second": round(self.requests_per_second, 2), + "sessions_requests_count": self.sessions_requests_count, + "failed_requests_count": self.failed_requests_count, + "offsite_requests_count": self.offsite_requests_count, + "blocked_requests_count": self.blocked_requests_count, + "response_status_count": self.response_status_count, + "response_bytes": self.response_bytes, + "domains_response_bytes": self.domains_response_bytes, + "proxies": self.proxies, + "custom_stats": self.custom_stats, + "log_count": self.log_levels_counter, + } + + +@dataclass +class CrawlResult: + """Complete result from a spider run.""" + + stats: CrawlStats + items: list[dict[str, Any]] + + def __len__(self) -> int: + return len(self.items) + + def __iter__(self) -> Iterator[dict[str, Any]]: + return iter(self.items) diff --git a/scrapling/spiders/scheduler.py b/scrapling/spiders/scheduler.py new file mode 100644 index 0000000..2890e50 --- /dev/null +++ b/scrapling/spiders/scheduler.py @@ -0,0 +1,45 @@ +import asyncio +from itertools import count + +from scrapling.core.utils import log +from scrapling.spiders.request import Request + + +class Scheduler: + """ + Priority queue with URL deduplication. (heapq) + + Higher priority requests are processed first. + Duplicate URLs are filtered unless dont_filter=True. + """ + + def __init__(self): + self._queue: asyncio.PriorityQueue[tuple[int, int, Request]] = asyncio.PriorityQueue() + self._seen: set[str] = set() + self._counter = count() + + async def enqueue(self, request: Request) -> bool: + """Add a request to the queue.""" + fingerprint = request._fp + + if not request.dont_filter and fingerprint in self._seen: + log.debug("Dropped duplicate request: %s", request) + return False + + self._seen.add(fingerprint) + + # Negative priority so higher priority = dequeued first + await self._queue.put((-request.priority, next(self._counter), request)) + return True + + async def dequeue(self) -> Request: + """Get the next request to process.""" + _, _, request = await self._queue.get() + return request + + def __len__(self) -> int: + return self._queue.qsize() + + @property + def is_empty(self) -> bool: + return self._queue.empty() diff --git a/scrapling/spiders/session.py b/scrapling/spiders/session.py new file mode 100644 index 0000000..452d12b --- /dev/null +++ b/scrapling/spiders/session.py @@ -0,0 +1,129 @@ +from scrapling.spiders.request import Request +from scrapling.engines.static import _ASyncSessionLogic +from scrapling.engines.toolbelt.convertor import Response +from scrapling.core._types import cast, SUPPORTED_HTTP_METHODS +from scrapling.fetchers import AsyncDynamicSession, AsyncStealthySession, FetcherSession + +Session = FetcherSession | AsyncDynamicSession | AsyncStealthySession + + +class SessionManager: + """Manages pre-configured session instances.""" + + def __init__(self): + self._sessions: dict[str, Session] = {} + self._default_session_id: str | None = None + self._started: bool = False + + def add(self, session_id: str, session: Session, *, default: bool = False) -> "SessionManager": + """Register a session instance. + + :param session_id: Name to reference this session in requests + :param session: Your pre-configured session instance + :param default: If True, this becomes the default session + """ + if session_id in self._sessions: + raise ValueError(f"Session '{session_id}' already registered") + + self._sessions[session_id] = session + + if default or self._default_session_id is None: + self._default_session_id = session_id + + return self + + def remove(self, session_id: str) -> None: + """Removes a session. + + :param session_id: ID of session to remove + """ + _ = self.pop(session_id) + + def pop(self, session_id: str) -> Session: + """Remove and returns a session. + + :param session_id: ID of session to remove + """ + if session_id not in self._sessions: + raise KeyError(f"Session '{session_id}' not found") + + session = self._sessions.pop(session_id) + + if session and self._default_session_id == session_id: + self._default_session_id = next(iter(self._sessions), None) + + return session + + @property + def default_session_id(self) -> str: + if self._default_session_id is None: + raise RuntimeError("No sessions registered") + return self._default_session_id + + @property + def session_ids(self) -> list[str]: + return list(self._sessions.keys()) + + def get(self, session_id: str) -> Session: + if session_id not in self._sessions: + available = ", ".join(self._sessions.keys()) + raise KeyError(f"Session '{session_id}' not found. Available: {available}") + return self._sessions[session_id] + + async def start(self) -> None: + """Start all sessions that aren't already alive.""" + if self._started: + return + + for session in self._sessions.values(): + if not session._is_alive: + await session.__aenter__() + + self._started = True + + async def close(self) -> None: + """Close all registered sessions.""" + for session in self._sessions.values(): + _ = await session.__aexit__(None, None, None) + + self._started = False + + async def fetch(self, request: Request) -> Response: + sid = request.sid if request.sid else self.default_session_id + session = self.get(sid) + + if session: + if isinstance(session, FetcherSession): + session = session._client + + if isinstance(session, _ASyncSessionLogic): + response = await session._make_request( + method=cast(SUPPORTED_HTTP_METHODS, request._session_kwargs.pop("method", "GET")), + url=request.url, + **request._session_kwargs, + ) + else: + # Sync session or other types - shouldn't happen in async context + raise TypeError(f"Session type {type(session)} not supported for async fetch") + else: + response = await session.fetch(url=request.url, **request._session_kwargs) + + response.request = request + response.meta = request.meta + return response + raise RuntimeError("No session found with the request session id") + + async def __aenter__(self) -> "SessionManager": + await self.start() + return self + + async def __aexit__(self, *exc) -> None: + await self.close() + + def __contains__(self, session_id: str) -> bool: + """Check if a session ID is registered.""" + return session_id in self._sessions + + def __len__(self) -> int: + """Number of registered sessions.""" + return len(self._sessions) diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py new file mode 100644 index 0000000..a111cd6 --- /dev/null +++ b/scrapling/spiders/spider.py @@ -0,0 +1,206 @@ +import logging +from pathlib import Path +from abc import ABC + +import anyio + +from scrapling.spiders.request import Request +from scrapling.spiders.result import CrawlResult +from scrapling.spiders.engine import CrawlerEngine +from scrapling.spiders.session import SessionManager +from scrapling.core.utils import set_logger, reset_logger +from scrapling.core._types import Set, Any, Dict, Optional, TYPE_CHECKING, AsyncGenerator + +BLOCKED_CODES = {401, 403, 407, 429, 444, 500, 502, 503, 504} +if TYPE_CHECKING: + from scrapling.engines.toolbelt.custom import Response + + +class LogCounterHandler(logging.Handler): + """A logging handler that counts log messages by level.""" + + def __init__(self): + super().__init__() + self.counts = { + logging.DEBUG: 0, + logging.INFO: 0, + logging.WARNING: 0, + logging.ERROR: 0, + logging.CRITICAL: 0, + } + + def emit(self, record: logging.LogRecord) -> None: + level = record.levelno + # Map to the closest standard level + if level >= logging.CRITICAL: + self.counts[logging.CRITICAL] += 1 + elif level >= logging.ERROR: + self.counts[logging.ERROR] += 1 + elif level >= logging.WARNING: + self.counts[logging.WARNING] += 1 + elif level >= logging.INFO: + self.counts[logging.INFO] += 1 + else: + self.counts[logging.DEBUG] += 1 + + def get_counts(self) -> Dict[str, int]: + """Return counts as a dictionary with string keys.""" + return { + "debug": self.counts[logging.DEBUG], + "info": self.counts[logging.INFO], + "warning": self.counts[logging.WARNING], + "error": self.counts[logging.ERROR], + "critical": self.counts[logging.CRITICAL], + } + + +class SessionConfigurationError(Exception): + """Raised when session configuration fails.""" + + pass + + +class Spider(ABC): + """An abstract base class for creating web spiders. + + Check the documentation website for more information. + """ + + name: Optional[str] = None + start_urls: list[str] = [] + allowed_domains: Set[str] = set() + + # Concurrency settings + concurrent_requests: int = 16 + concurrent_requests_per_domain: int = 0 + download_delay: float = 0.0 + + # Logging settings + logging_level: int = logging.DEBUG + log_file: Optional[str] = None + + def __init__(self): + if self.name is None: + raise ValueError(f"{self.__class__.__name__} must have a name.") + + self.logger = logging.getLogger(f"scrapling.spiders.{self.name}") + self.logger.setLevel(self.logging_level) + self.logger.handlers.clear() + self.logger.propagate = False # Don't propagate to parent 'scrapling' logger + + formatter = logging.Formatter( + fmt=f"[%(asctime)s]:({self.name}) %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S" + ) + + # Add a log counter handler to track log counts by level + self._log_counter = LogCounterHandler() + self.logger.addHandler(self._log_counter) + + console_handler = logging.StreamHandler() + console_handler.setFormatter(formatter) + self.logger.addHandler(console_handler) + + if self.log_file: + Path(self.log_file).parent.mkdir(parents=True, exist_ok=True) + file_handler = logging.FileHandler(self.log_file) + file_handler.setFormatter(formatter) + self.logger.addHandler(file_handler) + + self._session_manager = SessionManager() + try: + self.configure_sessions(self._session_manager) + except Exception as e: + raise SessionConfigurationError(f"Error in {self.__class__.__name__}.configure_sessions(): {e}") from e + + if len(self._session_manager) == 0: + raise SessionConfigurationError(f"{self.__class__.__name__}.configure_sessions() did not add any sessions") + + self.logger.info("Spider initialized") + + async def start_requests(self) -> AsyncGenerator[Request, None]: + """Generate initial requests to start the crawl. + + By default, this generates Request objects for each URL in `start_urls` + using the session manager's default session and `parse()` as callback. + + Override this method for more control over initial requests + (e.g., to add custom headers, use different callbacks, etc.) + """ + if not self.start_urls: + raise RuntimeError( + "Spider has no starting point, either set `start_urls` or override `start_requests` function." + ) + + for url in self.start_urls: + yield Request(url, sid=self._session_manager.default_session_id) + + async def parse(self, response: "Response") -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + """Default callback for processing responses""" + raise NotImplementedError(f"{self.__class__.__name__} must implement parse() method") + yield # Make this a generator + + async def on_start(self) -> None: + """Called before crawling starts. Override for setup logic.""" + self.logger.debug("Starting spider") + + async def on_close(self) -> None: + """Called after crawling finishes. Override for cleanup logic.""" + self.logger.debug("Spider closed") + + async def on_error(self, request: Request, error: Exception) -> None: + """ + Handle request errors for all spider requests. + + Override for custom error handling. + """ + self.logger.error(error, exc_info=error) + + @staticmethod + async def is_blocked(response: "Response") -> bool: + """Check if the response is blocked.""" + # TODO + if response.status in BLOCKED_CODES: + return True + return False + + def __repr__(self) -> str: + """String representation of the spider.""" + return f"<{self.__class__.__name__} '{self.name}'>" + + def configure_sessions(self, manager: SessionManager) -> None: + """Configure sessions for this spider. + + Override this method to add custom sessions. + The default implementation creates a FetcherSession session. + + The first session added becomes the default for `start_requests()` unless specified otherwise. + + :param manager: SessionManager to configure + """ + from scrapling.fetchers import FetcherSession + + manager.add("default", FetcherSession()) + + async def __run(self) -> CrawlResult: + token = set_logger(self.logger) + try: + engine = CrawlerEngine(self, session_manager=self._session_manager) + stats = await engine.crawl() + return CrawlResult(stats=stats, items=engine.items) + finally: + reset_logger(token) + # Close any file handlers to release file resources. + if self.log_file: + for handler in self.logger.handlers: + if isinstance(handler, logging.FileHandler): + handler.close() + + def start(self, backend_options: Dict[str, Any] | None = None) -> CrawlResult: + """Run the spider and return results. + + This is the main entry point for running a spider. + Handles async execution internally via anyio. + + :param backend_options: Asyncio backend options to be used with `anyio.run` + """ + return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) From 32f4f2adf425936936802ec1830bf5ccd34294c7 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 17:01:33 +0200 Subject: [PATCH 14/80] build: Add AnyIO to the dependencies --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index e16895c..2264425 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,6 +71,7 @@ fetchers = [ "patchright==1.56.0", "browserforge>=1.2.3", "msgspec>=0.20.0", + "anyio>=4.12.1" ] ai = [ "mcp>=1.24.0", From d5b9ed11b2821fb00960ed77c55e59678fe4526e Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 18:34:13 +0200 Subject: [PATCH 15/80] fix(browsers): Close pages that give error This was causing the browser and the whole code to stand still. --- scrapling/engines/_browsers/_controllers.py | 4 ++++ scrapling/engines/_browsers/_stealth.py | 4 ++++ scrapling/spiders/engine.py | 2 -- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index aef197a..3d39e9d 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -158,6 +158,8 @@ class DynamicSession(SyncSession, DynamicSessionMixin): except Exception as e: page_info.mark_error() + page_info.page.close() + self.page_pool.pages.remove(page_info) raise e @@ -298,4 +300,6 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): except Exception as e: # pragma: no cover page_info.mark_error() + await page_info.page.close() + self.page_pool.pages.remove(page_info) raise e diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 6883fdf..ade3ab9 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -250,6 +250,8 @@ class StealthySession(SyncSession, StealthySessionMixin): except Exception as e: page_info.mark_error() + page_info.page.close() + self.page_pool.pages.remove(page_info) raise e @@ -467,4 +469,6 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): except Exception as e: # pragma: no cover page_info.mark_error() + await page_info.page.close() + self.page_pool.pages.remove(page_info) raise e diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index e4210e9..dce7b08 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -1,5 +1,3 @@ -"""Crawler engine that orchestrates the crawling process.""" - import json import anyio From 0bfdab7158671a80428a6fb64f04be56247efb26 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 18:39:42 +0200 Subject: [PATCH 16/80] feat: spiders use uvloop/winloop when available --- scrapling/spiders/spider.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index a111cd6..fbaa5f4 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -203,4 +203,7 @@ class Spider(ABC): :param backend_options: Asyncio backend options to be used with `anyio.run` """ + backend_options = backend_options or {} + # By default use the faster uvloop/winloop event loop implementation, if available + backend_options.update({"use_uvloop": True}) return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) From 774364b6d35b39bb9ef7ba000c3e906f95902140 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 19:57:03 +0200 Subject: [PATCH 17/80] style(spiders): make the usage of uvloop optional --- scrapling/spiders/spider.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index fbaa5f4..5c51071 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -195,15 +195,16 @@ class Spider(ABC): if isinstance(handler, logging.FileHandler): handler.close() - def start(self, backend_options: Dict[str, Any] | None = None) -> CrawlResult: + def start(self, use_uvloop: bool = False, **backend_options: Any) -> CrawlResult: """Run the spider and return results. This is the main entry point for running a spider. Handles async execution internally via anyio. + :param use_uvloop: Whether to use the faster uvloop/winloop event loop implementation, if available. :param backend_options: Asyncio backend options to be used with `anyio.run` """ backend_options = backend_options or {} - # By default use the faster uvloop/winloop event loop implementation, if available - backend_options.update({"use_uvloop": True}) + if use_uvloop: + backend_options.update({"use_uvloop": True}) return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) From 736873a7c6c931b8c40e702cd733e806e149629c Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 21:56:57 +0200 Subject: [PATCH 18/80] feat(spiders): Add logic to detect blocked requests and retry them --- scrapling/spiders/engine.py | 17 ++++++++++++++++- scrapling/spiders/request.py | 15 +++++++++++++++ scrapling/spiders/spider.py | 11 +++++++---- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index dce7b08..83cafb3 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -75,7 +75,22 @@ class CrawlerEngine: await self.spider.on_error(request, e) return - # Process response through callback + if await self.spider.is_blocked(response): + self.stats.blocked_requests_count += 1 + if request._retry_count < self.spider.max_blocked_retries: + retry_request = request.copy() + retry_request._retry_count += 1 + retry_request.priority -= 1 # Don't retry immediately + retry_request.dont_filter = True + new_request = await self.spider.retry_blocked_request(retry_request) + await self.scheduler.enqueue(new_request) + log.debug( + f"Scheduled blocked request for retry ({retry_request._retry_count}/{self.spider.max_blocked_retries}): {request.url}" + ) + else: + log.warning(f"Max retries exceeded for blocked request: {request.url}") + return + callback = request.callback if request.callback else self.spider.parse try: async for result in callback(response): diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py index 495c73f..e6b25d0 100644 --- a/scrapling/spiders/request.py +++ b/scrapling/spiders/request.py @@ -13,6 +13,7 @@ class Request: priority: int = 0, dont_filter: bool = False, meta: dict[str, Any] | None = None, + _retry_count: int = 0, **kwargs: Any, ) -> None: self.url: str = url @@ -21,8 +22,22 @@ class Request: self.priority: int = priority self.dont_filter: bool = dont_filter self.meta: dict[str, Any] = meta if meta else {} + self._retry_count: int = _retry_count self._session_kwargs = kwargs if kwargs else {} + def copy(self) -> "Request": + """Create a copy of this request.""" + return Request( + url=self.url, + sid=self.sid, + callback=self.callback, + priority=self.priority, + dont_filter=self.dont_filter, + meta=self.meta.copy(), + _retry_count=self._retry_count, + **self._session_kwargs, + ) + @property def domain(self) -> str: return urlparse(self.url).netloc diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 5c51071..5333f50 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -74,6 +74,7 @@ class Spider(ABC): concurrent_requests: int = 16 concurrent_requests_per_domain: int = 0 download_delay: float = 0.0 + max_blocked_retries: int = 3 # Logging settings logging_level: int = logging.DEBUG @@ -155,14 +156,16 @@ class Spider(ABC): """ self.logger.error(error, exc_info=error) - @staticmethod - async def is_blocked(response: "Response") -> bool: - """Check if the response is blocked.""" - # TODO + async def is_blocked(self, response: "Response") -> bool: + """Check if the response is blocked. Users should override this for custom detection logic.""" if response.status in BLOCKED_CODES: return True return False + async def retry_blocked_request(self, request: Request) -> Request: + """Users should override this to prepare the blocked request before retrying, if needed.""" + return request + def __repr__(self) -> str: """String representation of the spider.""" return f"<{self.__class__.__name__} '{self.name}'>" From 5a11c2466b03694b3592fe8412002b43a1c791a4 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 22:54:17 +0200 Subject: [PATCH 19/80] fix: make `retry_blocked_request` take the response as well --- scrapling/spiders/engine.py | 2 +- scrapling/spiders/spider.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 83cafb3..26fce1e 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -82,7 +82,7 @@ class CrawlerEngine: retry_request._retry_count += 1 retry_request.priority -= 1 # Don't retry immediately retry_request.dont_filter = True - new_request = await self.spider.retry_blocked_request(retry_request) + new_request = await self.spider.retry_blocked_request(retry_request, response) await self.scheduler.enqueue(new_request) log.debug( f"Scheduled blocked request for retry ({retry_request._retry_count}/{self.spider.max_blocked_retries}): {request.url}" diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 5333f50..5f3268e 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -162,7 +162,7 @@ class Spider(ABC): return True return False - async def retry_blocked_request(self, request: Request) -> Request: + async def retry_blocked_request(self, request: Request, response: "Response") -> Request: """Users should override this to prepare the blocked request before retrying, if needed.""" return request From a17bb1d97607908a5bf8b4ab145968a02449c2c3 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 11 Jan 2026 23:40:26 +0200 Subject: [PATCH 20/80] feat(browsers): Add option to retry tabs that gives errors --- scrapling/engines/_browsers/_base.py | 8 + scrapling/engines/_browsers/_controllers.py | 168 +++++++++--------- scrapling/engines/_browsers/_stealth.py | 184 +++++++++++--------- scrapling/engines/_browsers/_types.py | 2 + scrapling/engines/_browsers/_validators.py | 3 + 5 files changed, 205 insertions(+), 160 deletions(-) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index cbbdc24..810c51c 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -310,6 +310,14 @@ class BaseSessionMixin: if config.additional_args: self._context_options.update(config.additional_args) + @staticmethod + def _is_retriable(error: Exception) -> bool: + """Check if an error is retriable (transient network/timeout issues).""" + if isinstance(error, TimeoutError): + return True + error_msg = str(error).lower() + return "net::" in error_msg or "failed to get response" in error_msg + class DynamicSessionMixin(BaseSessionMixin): def __validate__(self, **params): diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index 3d39e9d..bd5d455 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -1,3 +1,6 @@ +from time import sleep as time_sleep +from asyncio import sleep as asyncio_sleep + from playwright.sync_api import ( Locator, Playwright, @@ -115,52 +118,56 @@ class DynamicSession(SyncSession, DynamicSessionMixin): else None ) - page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + for attempt in range(self._config.retries): + page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) + final_response = [None] + handle_response = self._create_response_handler(page_info, final_response) - try: # pragma: no cover - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = page_info.page.goto(url, referer=referer) - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + try: # pragma: no cover + page_info.page.on("response", handle_response) + first_response = page_info.page.goto(url, referer=referer) + self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.page_action: - try: - _ = params.page_action(page_info.page) - except Exception as e: # pragma: no cover - log.error(f"Error executing page_action: {e}") + if params.page_action: + try: + _ = params.page_action(page_info.page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - if params.wait_selector: - try: - waiter: Locator = page_info.page.locator(params.wait_selector) - waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: # pragma: no cover - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + if params.wait_selector: + try: + waiter: Locator = page_info.page.locator(params.wait_selector) + waiter.first.wait_for(state=params.wait_selector_state) + self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - page_info.page.wait_for_timeout(params.wait) + page_info.page.wait_for_timeout(params.wait) - # Create response object - response = ResponseFactory.from_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + response = ResponseFactory.from_playwright_response( + page_info.page, first_response, final_response[0], params.selector_config + ) - # Close the page to free up resources - page_info.page.close() - self.page_pool.pages.remove(page_info) + page_info.page.close() + self.page_pool.pages.remove(page_info) + return response - return response + except Exception as e: + page_info.mark_error() + page_info.page.close() + self.page_pool.pages.remove(page_info) - except Exception as e: - page_info.mark_error() - page_info.page.close() - self.page_pool.pages.remove(page_info) - raise e + if attempt < self._config.retries - 1 and self._is_retriable(e): + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") + time_sleep(self._config.retry_delay) + else: + raise + + # For type checking purposes only + raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): @@ -252,54 +259,59 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): else None ) - page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + for attempt in range(self._config.retries): + page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) + final_response = [None] + handle_response = self._create_response_handler(page_info, final_response) - if TYPE_CHECKING: - from playwright.async_api import Page as async_Page + if TYPE_CHECKING: + from playwright.async_api import Page as async_Page - if not isinstance(page_info.page, async_Page): - raise TypeError + if not isinstance(page_info.page, async_Page): + raise TypeError - try: - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = await page_info.page.goto(url, referer=referer) - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + try: + page_info.page.on("response", handle_response) + first_response = await page_info.page.goto(url, referer=referer) + await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.page_action: - try: - _ = await params.page_action(page_info.page) - except Exception as e: - log.error(f"Error executing page_action: {e}") + if params.page_action: + try: + _ = await params.page_action(page_info.page) + except Exception as e: + log.error(f"Error executing page_action: {e}") - if params.wait_selector: - try: - waiter: AsyncLocator = page_info.page.locator(params.wait_selector) - await waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + if params.wait_selector: + try: + waiter: AsyncLocator = page_info.page.locator(params.wait_selector) + await waiter.first.wait_for(state=params.wait_selector_state) + await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + except Exception as e: + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - await page_info.page.wait_for_timeout(params.wait) + await page_info.page.wait_for_timeout(params.wait) - # Create response object - response = await ResponseFactory.from_async_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + response = await ResponseFactory.from_async_playwright_response( + page_info.page, first_response, final_response[0], params.selector_config + ) - # Close the page to free up resources - await page_info.page.close() - self.page_pool.pages.remove(page_info) - return response + await page_info.page.close() + self.page_pool.pages.remove(page_info) + return response - except Exception as e: # pragma: no cover - page_info.mark_error() - await page_info.page.close() - self.page_pool.pages.remove(page_info) - raise e + except Exception as e: # pragma: no cover + page_info.mark_error() + await page_info.page.close() + self.page_pool.pages.remove(page_info) + + if attempt < self._config.retries - 1 and self._is_retriable(e): + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") + await asyncio_sleep(self._config.retry_delay) + else: + raise + + # For type checking purposes only + raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index ade3ab9..27c4d79 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -1,5 +1,7 @@ from random import randint from re import compile as re_compile +from time import sleep as time_sleep +from asyncio import sleep as asyncio_sleep from playwright.sync_api import ( Locator, @@ -202,57 +204,66 @@ class StealthySession(SyncSession, StealthySessionMixin): else None ) - page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + for attempt in range(self._config.retries): + page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) + final_response = [None] + handle_response = self._create_response_handler(page_info, final_response) - try: # pragma: no cover - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = page_info.page.goto(url, referer=referer) - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") - - if params.solve_cloudflare: - self._cloudflare_solver(page_info.page) - # Make sure the page is fully loaded after the captcha + try: # pragma: no cover + # Navigate to URL and wait for a specified state + page_info.page.on("response", handle_response) + first_response = page_info.page.goto(url, referer=referer) self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - if params.page_action: - try: - _ = params.page_action(page_info.page) - except Exception as e: # pragma: no cover - log.error(f"Error executing page_action: {e}") + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.wait_selector: - try: - waiter: Locator = page_info.page.locator(params.wait_selector) - waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare + if params.solve_cloudflare: + self._cloudflare_solver(page_info.page) + # Make sure the page is fully loaded after the captcha self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: # pragma: no cover - log.error(f"Error waiting for selector {params.wait_selector}: {e}") - page_info.page.wait_for_timeout(params.wait) + if params.page_action: + try: + _ = params.page_action(page_info.page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - # Create response object - response = ResponseFactory.from_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + if params.wait_selector: + try: + waiter: Locator = page_info.page.locator(params.wait_selector) + waiter.first.wait_for(state=params.wait_selector_state) + # Wait again after waiting for the selector, helpful with protections like Cloudflare + self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - # Close the page to free up resources - page_info.page.close() - self.page_pool.pages.remove(page_info) + page_info.page.wait_for_timeout(params.wait) - return response + # Create response object + response = ResponseFactory.from_playwright_response( + page_info.page, first_response, final_response[0], params.selector_config + ) - except Exception as e: - page_info.mark_error() - page_info.page.close() - self.page_pool.pages.remove(page_info) - raise e + # Close the page to free up resources + page_info.page.close() + self.page_pool.pages.remove(page_info) + + return response + + except Exception as e: + page_info.mark_error() + page_info.page.close() + self.page_pool.pages.remove(page_info) + + if attempt < self._config.retries - 1 and self._is_retriable(e): + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") + time_sleep(self._config.retry_delay) + else: + raise + + # For type checking purposes only + raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover class AsyncStealthySession(AsyncSession, StealthySessionMixin): @@ -422,53 +433,62 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): else None ) - page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + for attempt in range(self._config.retries): + page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) + final_response = [None] + handle_response = self._create_response_handler(page_info, final_response) - try: - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = await page_info.page.goto(url, referer=referer) - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") - - if params.solve_cloudflare: - await self._cloudflare_solver(page_info.page) - # Make sure the page is fully loaded after the captcha + try: + # Navigate to URL and wait for a specified state + page_info.page.on("response", handle_response) + first_response = await page_info.page.goto(url, referer=referer) await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - if params.page_action: - try: - _ = await params.page_action(page_info.page) - except Exception as e: - log.error(f"Error executing page_action: {e}") + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.wait_selector: - try: - waiter: AsyncLocator = page_info.page.locator(params.wait_selector) - await waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare + if params.solve_cloudflare: + await self._cloudflare_solver(page_info.page) + # Make sure the page is fully loaded after the captcha await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: - log.error(f"Error waiting for selector {params.wait_selector}: {e}") - await page_info.page.wait_for_timeout(params.wait) + if params.page_action: + try: + _ = await params.page_action(page_info.page) + except Exception as e: + log.error(f"Error executing page_action: {e}") - # Create response object - response = await ResponseFactory.from_async_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + if params.wait_selector: + try: + waiter: AsyncLocator = page_info.page.locator(params.wait_selector) + await waiter.first.wait_for(state=params.wait_selector_state) + # Wait again after waiting for the selector, helpful with protections like Cloudflare + await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + except Exception as e: + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - # Close the page to free up resources - await page_info.page.close() - self.page_pool.pages.remove(page_info) - return response + await page_info.page.wait_for_timeout(params.wait) - except Exception as e: # pragma: no cover - page_info.mark_error() - await page_info.page.close() - self.page_pool.pages.remove(page_info) - raise e + # Create response object + response = await ResponseFactory.from_async_playwright_response( + page_info.page, first_response, final_response[0], params.selector_config + ) + + # Close the page to free up resources + await page_info.page.close() + self.page_pool.pages.remove(page_info) + return response + + except Exception as e: # pragma: no cover + page_info.mark_error() + await page_info.page.close() + self.page_pool.pages.remove(page_info) + + if attempt < self._config.retries - 1 and self._is_retriable(e): + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") + await asyncio_sleep(self._config.retry_delay) + else: + raise + + # For type checking purposes only + raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover diff --git a/scrapling/engines/_browsers/_types.py b/scrapling/engines/_browsers/_types.py index cb8d760..8391e9c 100644 --- a/scrapling/engines/_browsers/_types.py +++ b/scrapling/engines/_browsers/_types.py @@ -79,6 +79,8 @@ if TYPE_CHECKING: # pragma: no cover cdp_url: Optional[str] useragent: Optional[str] extra_flags: Optional[List[str]] + retries: int + retry_delay: int | float class PlaywrightFetchParams(TypedDict, total=False): load_dom: bool diff --git a/scrapling/engines/_browsers/_validators.py b/scrapling/engines/_browsers/_validators.py index 82270ef..0b08f2f 100644 --- a/scrapling/engines/_browsers/_validators.py +++ b/scrapling/engines/_browsers/_validators.py @@ -50,6 +50,7 @@ def _is_invalid_cdp_url(cdp_url: str) -> bool | str: # Type aliases for cleaner annotations PagesCount = Annotated[int, Meta(ge=1, le=50)] +RetriesCount = Annotated[int, Meta(ge=1, le=10)] Seconds = Annotated[int, float, Meta(ge=0)] @@ -80,6 +81,8 @@ class PlaywrightConfig(Struct, kw_only=True, frozen=False, weakref=True): cdp_url: Optional[str] = None useragent: Optional[str] = None extra_flags: Optional[List[str]] = None + retries: RetriesCount = 3 + retry_delay: Seconds = 1 def __post_init__(self): # pragma: no cover """Custom validation after msgspec validation""" From 72c3c2792a4cf35d991bdbe404ce3c6c20b5c1fb Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 01:21:05 +0200 Subject: [PATCH 21/80] feat(spiders): add simple export system for the results --- scrapling/spiders/engine.py | 6 +++--- scrapling/spiders/result.py | 40 +++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 26fce1e..8934474 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -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 diff --git a/scrapling/spiders/result.py b/scrapling/spiders/result.py index d36b0ad..fc10f1b 100644 --- a/scrapling/spiders/result.py +++ b/scrapling/spiders/result.py @@ -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) From f2c621696803c29b3f43a8fe18fe643ba38b7910 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 01:21:26 +0200 Subject: [PATCH 22/80] style: remove unwanted import from spiders main init file --- scrapling/spiders/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scrapling/spiders/__init__.py b/scrapling/spiders/__init__.py index ee3c00c..92eb2e9 100644 --- a/scrapling/spiders/__init__.py +++ b/scrapling/spiders/__init__.py @@ -1,18 +1,16 @@ -from .spider import Spider, SessionConfigurationError, LogCounterHandler from .request import Request -from .result import CrawlStats, CrawlResult +from .result import CrawlResult +from .scheduler import Scheduler from .engine import CrawlerEngine from .session import SessionManager -from .scheduler import Scheduler +from .spider import Spider, SessionConfigurationError from scrapling.engines.toolbelt.custom import Response __all__ = [ "Spider", "SessionConfigurationError", - "LogCounterHandler", "Request", "CrawlerEngine", - "CrawlStats", "CrawlResult", "SessionManager", "Scheduler", From 927cfd85ffe46aba45ec66cbf25e0c52d3949f8f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 02:09:50 +0200 Subject: [PATCH 23/80] feat(spiders): The option to start sessions lazily --- scrapling/spiders/session.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/scrapling/spiders/session.py b/scrapling/spiders/session.py index 452d12b..f5b5a49 100644 --- a/scrapling/spiders/session.py +++ b/scrapling/spiders/session.py @@ -1,7 +1,9 @@ +from asyncio import Lock + from scrapling.spiders.request import Request from scrapling.engines.static import _ASyncSessionLogic from scrapling.engines.toolbelt.convertor import Response -from scrapling.core._types import cast, SUPPORTED_HTTP_METHODS +from scrapling.core._types import Set, cast, SUPPORTED_HTTP_METHODS from scrapling.fetchers import AsyncDynamicSession, AsyncStealthySession, FetcherSession Session = FetcherSession | AsyncDynamicSession | AsyncStealthySession @@ -14,13 +16,16 @@ class SessionManager: self._sessions: dict[str, Session] = {} self._default_session_id: str | None = None self._started: bool = False + self._lazy_sessions: Set[str] = set() + self._lazy_lock = Lock() - def add(self, session_id: str, session: Session, *, default: bool = False) -> "SessionManager": + def add(self, session_id: str, session: Session, *, default: bool = False, lazy: bool = False) -> "SessionManager": """Register a session instance. :param session_id: Name to reference this session in requests :param session: Your pre-configured session instance :param default: If True, this becomes the default session + :param lazy: If True, the session will be started only when a request uses its ID. """ if session_id in self._sessions: raise ValueError(f"Session '{session_id}' already registered") @@ -30,6 +35,9 @@ class SessionManager: if default or self._default_session_id is None: self._default_session_id = session_id + if lazy: + self._lazy_sessions.add(session_id) + return self def remove(self, session_id: str) -> None: @@ -48,6 +56,8 @@ class SessionManager: raise KeyError(f"Session '{session_id}' not found") session = self._sessions.pop(session_id) + if session_id in self._lazy_sessions: + self._lazy_sessions.remove(session_id) if session and self._default_session_id == session_id: self._default_session_id = next(iter(self._sessions), None) @@ -75,8 +85,8 @@ class SessionManager: if self._started: return - for session in self._sessions.values(): - if not session._is_alive: + for sid, session in self._sessions.items(): + if sid not in self._lazy_sessions and not session._is_alive: await session.__aenter__() self._started = True @@ -93,6 +103,11 @@ class SessionManager: session = self.get(sid) if session: + if sid in self._lazy_sessions and not session._is_alive: + async with self._lazy_lock: + if not session._is_alive: + await session.__aenter__() + if isinstance(session, FetcherSession): session = session._client From e0f94cf7d026933b14ffabb5efc77a2ecff5f449 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 15:53:29 +0200 Subject: [PATCH 24/80] feat(spiders): Add a stream mode to collect items in realtime --- scrapling/spiders/engine.py | 29 +++++++++++++++++++++++++++-- scrapling/spiders/spider.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 8934474..bd50c41 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -1,14 +1,14 @@ import json import anyio -from anyio import create_task_group, CapacityLimiter +from anyio import create_task_group, CapacityLimiter, create_memory_object_stream, EndOfStream from scrapling.core.utils import log from scrapling.spiders.request import Request 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 +from scrapling.core._types import Dict, TYPE_CHECKING, Any, AsyncGenerator if TYPE_CHECKING: from scrapling.spiders.spider import Spider @@ -34,6 +34,7 @@ class CrawlerEngine: self._active_tasks: int = 0 self._running: bool = False self._items: ItemList = ItemList() + self._item_stream: Any = None def _is_domain_allowed(self, request: Request) -> bool: """Check if the request's domain is in allowed_domains.""" @@ -102,6 +103,8 @@ class CrawlerEngine: log.debug(f"Filtered offsite request to: {result.url}") elif isinstance(result, dict): await self._handle_item(result) + if self._item_stream: + await self._item_stream.send(result) log.debug(f"Scraped from {str(response)}\n{result}") except Exception as e: await self.spider.on_error(request, e) @@ -164,3 +167,25 @@ class CrawlerEngine: def items(self) -> ItemList: """Access scraped items.""" return self._items + + def __aiter__(self) -> AsyncGenerator[dict, None]: + return self._stream() + + async def _stream(self) -> AsyncGenerator[dict, None]: + """Async generator that runs crawl and yields items.""" + send, recv = create_memory_object_stream[dict](100) + self._item_stream = send + + async def run(): + try: + await self.crawl() + finally: + await send.aclose() + + async with create_task_group() as tg: + tg.start_soon(run) + try: + async for item in recv: + yield item + except EndOfStream: + pass diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 5f3268e..eb5987f 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -1,14 +1,14 @@ import logging -from pathlib import Path from abc import ABC +from pathlib import Path import anyio from scrapling.spiders.request import Request -from scrapling.spiders.result import CrawlResult from scrapling.spiders.engine import CrawlerEngine from scrapling.spiders.session import SessionManager from scrapling.core.utils import set_logger, reset_logger +from scrapling.spiders.result import CrawlResult, CrawlStats from scrapling.core._types import Set, Any, Dict, Optional, TYPE_CHECKING, AsyncGenerator BLOCKED_CODES = {401, 403, 407, 429, 444, 500, 502, 503, 504} @@ -108,6 +108,8 @@ class Spider(ABC): self.logger.addHandler(file_handler) self._session_manager = SessionManager() + self._stream_engine: CrawlerEngine | None = None + try: self.configure_sessions(self._session_manager) except Exception as e: @@ -211,3 +213,29 @@ class Spider(ABC): if use_uvloop: backend_options.update({"use_uvloop": True}) return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) + + async def stream(self) -> AsyncGenerator[Dict[str, Any], None]: + """Stream items as they're scraped. Ideal for long-running spiders or building applications on top of the spiders. + + Must be called from an async context. Yields items one by one as they are scraped. + Access `spider.stats` during iteration for real-time statistics. + """ + token = set_logger(self.logger) + try: + self._stream_engine = CrawlerEngine(self, self._session_manager) + async for item in self._stream_engine: + yield item + finally: + self._stream_engine = None + reset_logger(token) + if self.log_file: + for handler in self.logger.handlers: + if isinstance(handler, logging.FileHandler): + handler.close() + + @property + def stats(self) -> CrawlStats: + """Access current crawl stats (works during streaming).""" + if self._stream_engine: + return self._stream_engine.stats + raise RuntimeError("No active crawl. Use this property inside `async for item in spider.stream():`") From 3466bcab2c029abefecfc599f61e30351307b51d Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 15:58:33 +0200 Subject: [PATCH 25/80] feat: add hook to run after collecting an item --- scrapling/spiders/engine.py | 9 +++------ scrapling/spiders/spider.py | 4 ++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index bd50c41..2b12683 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -102,18 +102,15 @@ class CrawlerEngine: self.stats.offsite_requests_count += 1 log.debug(f"Filtered offsite request to: {result.url}") elif isinstance(result, dict): - await self._handle_item(result) + self.stats.items_scraped += 1 + self._items.append(result) if self._item_stream: await self._item_stream.send(result) + await self.spider.on_scraped_item(result) log.debug(f"Scraped from {str(response)}\n{result}") except Exception as e: await self.spider.on_error(request, e) - async def _handle_item(self, item: dict[str, Any]) -> None: - """Handle a scraped item. Override or extend for item pipelines.""" - self.stats.items_scraped += 1 - self._items.append(item) - async def _task_wrapper(self, request: Request) -> None: """Wrapper to track active task count.""" try: diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index eb5987f..bc7874c 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -158,6 +158,10 @@ class Spider(ABC): """ self.logger.error(error, exc_info=error) + async def on_scraped_item(self, item: dict[str, Any]) -> None: + """Handle a scraped item. Override or extend for item pipelines.""" + pass + async def is_blocked(self, response: "Response") -> bool: """Check if the response is blocked. Users should override this for custom detection logic.""" if response.status in BLOCKED_CODES: From 35d570120a814dbc4922a9d48af7bf967406a481 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 12 Jan 2026 17:11:52 +0200 Subject: [PATCH 26/80] feat(spiders): Add option to logging format and date format --- scrapling/spiders/spider.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index bc7874c..59ab61c 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -78,6 +78,8 @@ class Spider(ABC): # Logging settings logging_level: int = logging.DEBUG + logging_format: str = "[%(asctime)s]:({spider_name}) %(levelname)s: %(message)s" + logging_date_format: str = "%Y-%m-%d %H:%M:%S" log_file: Optional[str] = None def __init__(self): @@ -90,7 +92,7 @@ class Spider(ABC): self.logger.propagate = False # Don't propagate to parent 'scrapling' logger formatter = logging.Formatter( - fmt=f"[%(asctime)s]:({self.name}) %(levelname)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S" + fmt=self.logging_format.format(spider_name=self.name), datefmt=self.logging_date_format ) # Add a log counter handler to track log counts by level From dac854a1293092f86d371da2c6b44c6cdceda15a Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 13 Jan 2026 02:35:26 +0200 Subject: [PATCH 27/80] fix(parser): handle responses with empty body It makes root's value None --- scrapling/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrapling/parser.py b/scrapling/parser.py index f7da3a9..8e9704d 100644 --- a/scrapling/parser.py +++ b/scrapling/parser.py @@ -138,7 +138,7 @@ class Selector(SelectorsGeneration): default_doctype=True, strip_cdata=(not keep_cdata), ) - self._root = cast(HtmlElement, fromstring(body, parser=parser, base_url=url or None)) + self._root = cast(HtmlElement, fromstring(body or "", parser=parser, base_url=url or None)) self._raw_body = content else: From 41c7a7e7931ee147f354517f42f18b3f1a89215a Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 17 Jan 2026 19:57:04 +0200 Subject: [PATCH 28/80] fix(spiders engine): Improve logging --- scrapling/spiders/engine.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 2b12683..e869e7f 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -85,7 +85,7 @@ class CrawlerEngine: retry_request.dont_filter = True new_request = await self.spider.retry_blocked_request(retry_request, response) await self.scheduler.enqueue(new_request) - log.debug( + log.info( f"Scheduled blocked request for retry ({retry_request._retry_count}/{self.spider.max_blocked_retries}): {request.url}" ) else: @@ -108,6 +108,8 @@ class CrawlerEngine: await self._item_stream.send(result) await self.spider.on_scraped_item(result) log.debug(f"Scraped from {str(response)}\n{result}") + elif result is not None: + log.error(f"Spider must return Request, dict or None, got '{type(result)}' in {request}") except Exception as e: await self.spider.on_error(request, e) From afe6b2e97bbd920860fc28601f66111524535bc4 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 17 Jan 2026 20:52:49 +0200 Subject: [PATCH 29/80] feat(spiders): Change items hook to make it for processing items + add a stat for this --- scrapling/spiders/engine.py | 17 +++++++++++------ scrapling/spiders/result.py | 2 ++ scrapling/spiders/spider.py | 6 +++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index e869e7f..751d87b 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -102,12 +102,17 @@ class CrawlerEngine: self.stats.offsite_requests_count += 1 log.debug(f"Filtered offsite request to: {result.url}") elif isinstance(result, dict): - self.stats.items_scraped += 1 - self._items.append(result) - if self._item_stream: - await self._item_stream.send(result) - await self.spider.on_scraped_item(result) - log.debug(f"Scraped from {str(response)}\n{result}") + processed_result = await self.spider.on_scraped_item(result) + if processed_result: + self.stats.items_scraped += 1 + log.debug(f"Scraped from {str(response)}\n{processed_result}") + if self._item_stream: + await self._item_stream.send(processed_result) + else: + self._items.append(processed_result) + else: + self.stats.items_dropped += 1 + log.warning(f"Dropped from {str(response)}\n{processed_result}") elif result is not None: log.error(f"Spider must return Request, dict or None, got '{type(result)}' in {request}") except Exception as e: diff --git a/scrapling/spiders/result.py b/scrapling/spiders/result.py index fc10f1b..7e38a81 100644 --- a/scrapling/spiders/result.py +++ b/scrapling/spiders/result.py @@ -50,6 +50,7 @@ class CrawlStats: offsite_requests_count: int = 0 response_bytes: int = 0 items_scraped: int = 0 + items_dropped: int = 0 start_time: float = 0.0 end_time: float = 0.0 download_delay: float = 0.0 @@ -85,6 +86,7 @@ class CrawlStats: def to_dict(self) -> dict[str, Any]: return { "items_scraped": self.items_scraped, + "items_dropped": self.items_dropped, "elapsed_seconds": round(self.elapsed_seconds, 2), "download_delay": round(self.download_delay, 2), "concurrent_requests": self.concurrent_requests, diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 59ab61c..ac7174f 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -160,9 +160,9 @@ class Spider(ABC): """ self.logger.error(error, exc_info=error) - async def on_scraped_item(self, item: dict[str, Any]) -> None: - """Handle a scraped item. Override or extend for item pipelines.""" - pass + async def on_scraped_item(self, item: Dict[str, Any]) -> Dict[str, Any] | None: + """A hook to be overridden by users to do some processing on scraped items, return `None` to drop the item silently.""" + return item async def is_blocked(self, response: "Response") -> bool: """Check if the response is blocked. Users should override this for custom detection logic.""" From 02c9dffc77009379404c10fbd644c567edbb92bc Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 18 Jan 2026 00:01:04 +0200 Subject: [PATCH 30/80] style(spiders): make parse function abstract --- scrapling/spiders/spider.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index ac7174f..aedab1a 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -1,6 +1,6 @@ import logging -from abc import ABC from pathlib import Path +from abc import ABC, abstractmethod import anyio @@ -139,6 +139,7 @@ class Spider(ABC): for url in self.start_urls: yield Request(url, sid=self._session_manager.default_session_id) + @abstractmethod async def parse(self, response: "Response") -> AsyncGenerator[Dict[str, Any] | Request | None, None]: """Default callback for processing responses""" raise NotImplementedError(f"{self.__class__.__name__} must implement parse() method") From bf5aa021d4c83ab870e5007e26fcbd196c960181 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 18 Jan 2026 16:46:48 +0200 Subject: [PATCH 31/80] fix(browsers): solving an issues with leaving playwright loop open when cdp connection fails This has been causing issues with tests for a long time, and now finally found the reason. --- scrapling/engines/_browsers/_controllers.py | 63 ++++++++++-------- scrapling/engines/_browsers/_stealth.py | 71 ++++++++++++--------- 2 files changed, 76 insertions(+), 58 deletions(-) diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index bd5d455..a9dbe85 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -3,13 +3,11 @@ from asyncio import sleep as asyncio_sleep from playwright.sync_api import ( Locator, - Playwright, sync_playwright, ) from playwright.async_api import ( async_playwright, Locator as AsyncLocator, - Playwright as AsyncPlaywright, BrowserContext as AsyncBrowserContext, ) @@ -71,21 +69,27 @@ class DynamicSession(SyncSession, DynamicSessionMixin): def start(self): """Create a browser for this instance and context.""" if not self.playwright: - self.playwright: Playwright = sync_playwright().start() # pyright: ignore [reportAttributeAccessIssue] + self.playwright = sync_playwright().start() - if self._config.cdp_url: # pragma: no cover - browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context = browser.new_context(**self._context_options) - else: - self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) + try: + if self._config.cdp_url: # pragma: no cover + browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + self.context = browser.new_context(**self._context_options) + else: + self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) - if self._config.init_script: # pragma: no cover - self.context.add_init_script(path=self._config.init_script) + if self._config.init_script: # pragma: no cover + self.context.add_init_script(path=self._config.init_script) - if self._config.cookies: # pragma: no cover - self.context.add_cookies(self._config.cookies) + if self._config.cookies: # pragma: no cover + self.context.add_cookies(self._config.cookies) - self._is_alive = True + self._is_alive = True + except Exception: + # Clean up playwright if browser setup fails + self.playwright.stop() + self.playwright = None + raise else: raise RuntimeError("Session has been already started") @@ -209,23 +213,28 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): async def start(self): """Create a browser for this instance and context.""" if not self.playwright: - self.playwright: AsyncPlaywright = await async_playwright().start() # pyright: ignore [reportAttributeAccessIssue] + self.playwright = await async_playwright().start() + try: + if self._config.cdp_url: + browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) + else: + self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( + **self._launch_options + ) - if self._config.cdp_url: - browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) - else: - self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **self._launch_options - ) + if self._config.init_script: # pragma: no cover + await self.context.add_init_script(path=self._config.init_script) - if self._config.init_script: # pragma: no cover - await self.context.add_init_script(path=self._config.init_script) + if self._config.cookies: + await self.context.add_cookies(self._config.cookies) # pyright: ignore - if self._config.cookies: - await self.context.add_cookies(self._config.cookies) # pyright: ignore - - self._is_alive = True + self._is_alive = True + except Exception: + # Clean up playwright if browser setup fails + await self.playwright.stop() + self.playwright = None + raise else: raise RuntimeError("Session has been already started") diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 27c4d79..62c6455 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -6,12 +6,10 @@ from asyncio import sleep as asyncio_sleep from playwright.sync_api import ( Locator, Page, - Playwright, ) from playwright.async_api import ( Page as async_Page, Locator as AsyncLocator, - Playwright as AsyncPlaywright, BrowserContext as AsyncBrowserContext, ) from patchright.sync_api import sync_playwright @@ -82,24 +80,30 @@ class StealthySession(SyncSession, StealthySessionMixin): def start(self): """Create a browser for this instance and context.""" if not self.playwright: - self.playwright: Playwright = sync_playwright().start() # pyright: ignore [reportAttributeAccessIssue] + self.playwright = sync_playwright().start() - if self._config.cdp_url: # pragma: no cover - browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context = browser.new_context(**self._context_options) - else: - self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) + try: + if self._config.cdp_url: # pragma: no cover + browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + self.context = browser.new_context(**self._context_options) + else: + self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) - for script in _compiled_stealth_scripts(): - self.context.add_init_script(script=script) + for script in _compiled_stealth_scripts(): + self.context.add_init_script(script=script) - if self._config.init_script: # pragma: no cover - self.context.add_init_script(path=self._config.init_script) + if self._config.init_script: # pragma: no cover + self.context.add_init_script(path=self._config.init_script) - if self._config.cookies: # pragma: no cover - self.context.add_cookies(self._config.cookies) + if self._config.cookies: # pragma: no cover + self.context.add_cookies(self._config.cookies) - self._is_alive = True + self._is_alive = True + except Exception: + # Clean up playwright if browser setup fails + self.playwright.stop() + self.playwright = None + raise else: raise RuntimeError("Session has been already started") @@ -308,26 +312,31 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): async def start(self): """Create a browser for this instance and context.""" if not self.playwright: - self.playwright: AsyncPlaywright = await async_playwright().start() # pyright: ignore [reportAttributeAccessIssue] + self.playwright = await async_playwright().start() + try: + if self._config.cdp_url: + browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) + else: + self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( + **self._launch_options + ) - if self._config.cdp_url: - browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) - else: - self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **self._launch_options - ) + for script in _compiled_stealth_scripts(): + await self.context.add_init_script(script=script) - for script in _compiled_stealth_scripts(): - await self.context.add_init_script(script=script) + if self._config.init_script: # pragma: no cover + await self.context.add_init_script(path=self._config.init_script) - if self._config.init_script: # pragma: no cover - await self.context.add_init_script(path=self._config.init_script) + if self._config.cookies: + await self.context.add_cookies(self._config.cookies) # pyright: ignore - if self._config.cookies: - await self.context.add_cookies(self._config.cookies) # pyright: ignore - - self._is_alive = True + self._is_alive = True + except Exception: + # Clean up playwright if browser setup fails + await self.playwright.stop() + self.playwright = None + raise else: raise RuntimeError("Session has been already started") From acdb39988cf0b08cc1bbabed252eb8c05fce2185 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 03:40:57 +0200 Subject: [PATCH 32/80] ops: update bandit checklist --- .bandit.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.bandit.yml b/.bandit.yml index 5acd372..f74f22f 100644 --- a/.bandit.yml +++ b/.bandit.yml @@ -6,4 +6,5 @@ skips: - B404 # Using subprocess library - B602 # subprocess call with shell=True identified - B110 # Try, Except, Pass detected. -- B104 # Possible binding to all interfaces. \ No newline at end of file +- B104 # Possible binding to all interfaces. +- B301 # Pickle and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue. \ No newline at end of file From 1f0f86e3a2d79cce9352ff28e18a85be2cb625f5 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 03:43:10 +0200 Subject: [PATCH 33/80] feat(spiders): Add pause/resume system for crawls --- scrapling/spiders/checkpoint.py | 90 +++++++++++++++++++++++++++ scrapling/spiders/engine.py | 107 +++++++++++++++++++++++++++++--- scrapling/spiders/request.py | 28 ++++++++- scrapling/spiders/result.py | 6 ++ scrapling/spiders/scheduler.py | 36 ++++++++++- scrapling/spiders/spider.py | 97 ++++++++++++++++++++++++----- 6 files changed, 336 insertions(+), 28 deletions(-) create mode 100644 scrapling/spiders/checkpoint.py diff --git a/scrapling/spiders/checkpoint.py b/scrapling/spiders/checkpoint.py new file mode 100644 index 0000000..ae795dc --- /dev/null +++ b/scrapling/spiders/checkpoint.py @@ -0,0 +1,90 @@ +import pickle +from pathlib import Path +from dataclasses import dataclass, field + +import anyio +from anyio import Path as AsyncPath + +from scrapling.core.utils import log +from scrapling.core._types import Set, List, Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from scrapling.spiders.request import Request + + +@dataclass +class CheckpointData: + """Container for checkpoint state.""" + + requests: List["Request"] = field(default_factory=list) + seen: Set[str] = field(default_factory=set) + + +class CheckpointManager: + """Manages saving and loading checkpoint state to/from disk.""" + + CHECKPOINT_FILE = "checkpoint.pkl" + + def __init__(self, crawldir: str | Path | AsyncPath, interval: float = 300.0): + self.crawldir = AsyncPath(crawldir) + self._checkpoint_path = self.crawldir / self.CHECKPOINT_FILE + self.interval = interval + if not isinstance(interval, (int, float)): + raise TypeError("Checkpoints interval must be integer or float.") + else: + if interval < 0: + raise ValueError("Checkpoints interval must be greater than 0.") + + async def has_checkpoint(self) -> bool: + """Check if a checkpoint exists.""" + return await self._checkpoint_path.exists() + + async def save(self, data: CheckpointData) -> None: + """Save checkpoint data to disk atomically.""" + await self.crawldir.mkdir(parents=True, exist_ok=True) + + temp_path = self._checkpoint_path.with_suffix(".tmp") + + try: + serialized = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL) + async with await anyio.open_file(temp_path, "wb") as f: + await f.write(serialized) + + await temp_path.rename(self._checkpoint_path) + + log.info(f"Checkpoint saved: {len(data.requests)} requests, {len(data.seen)} seen URLs") + except Exception as e: + # Clean up temp file if it exists + if await temp_path.exists(): + await temp_path.unlink() + log.error(f"Failed to save checkpoint: {e}") + raise + + async def load(self) -> Optional[CheckpointData]: + """Load checkpoint data from disk. + + Returns None if no checkpoint exists or if loading fails. + """ + if not await self.has_checkpoint(): + return None + + try: + async with await anyio.open_file(self._checkpoint_path, "rb") as f: + content = await f.read() + data: CheckpointData = pickle.loads(content) + + log.info(f"Checkpoint loaded: {len(data.requests)} requests, {len(data.seen)} seen URLs") + return data + + except Exception as e: + log.error(f"Failed to load checkpoint (starting fresh): {e}") + return None + + async def cleanup(self) -> None: + """Delete checkpoint file after successful completion.""" + try: + if await self._checkpoint_path.exists(): + await self._checkpoint_path.unlink() + log.debug("Checkpoint file cleaned up") + except Exception as e: + log.warning(f"Failed to cleanup checkpoint file: {e}") diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 751d87b..9b226df 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -1,14 +1,18 @@ import json +import pprint +from pathlib import Path import anyio +from anyio import Path as AsyncPath from anyio import create_task_group, CapacityLimiter, create_memory_object_stream, EndOfStream from scrapling.core.utils import log from scrapling.spiders.request import Request -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, AsyncGenerator +from scrapling.spiders.result import CrawlStats, ItemList +from scrapling.spiders.checkpoint import CheckpointManager, CheckpointData +from scrapling.core._types import Dict, Union, Optional, TYPE_CHECKING, Any, AsyncGenerator if TYPE_CHECKING: from scrapling.spiders.spider import Spider @@ -21,10 +25,16 @@ def _dump(obj: Dict) -> str: class CrawlerEngine: """Orchestrates the crawling process.""" - def __init__(self, spider: "Spider", session_manager: SessionManager, scheduler: Scheduler | None = None): + def __init__( + self, + spider: "Spider", + session_manager: SessionManager, + crawldir: Optional[Union[str, Path, AsyncPath]] = None, + interval: float = 300.0, + ): self.spider = spider self.session_manager = session_manager - self.scheduler = scheduler or Scheduler() + self.scheduler = Scheduler() self.stats = CrawlStats() self._global_limiter = CapacityLimiter(spider.concurrent_requests) @@ -36,6 +46,12 @@ class CrawlerEngine: self._items: ItemList = ItemList() self._item_stream: Any = None + self._checkpoint_system_enabled = bool(crawldir) + self._checkpoint_manager = CheckpointManager(crawldir or "", interval) + self._last_checkpoint_time: float = 0.0 + self._pause_requested: bool = False + self.paused: bool = False + def _is_domain_allowed(self, request: Request) -> bool: """Check if the request's domain is in allowed_domains.""" if not self._allowed_domains: @@ -105,7 +121,7 @@ class CrawlerEngine: processed_result = await self.spider.on_scraped_item(result) if processed_result: self.stats.items_scraped += 1 - log.debug(f"Scraped from {str(response)}\n{processed_result}") + log.debug(f"Scraped from {str(response)}\n{pprint.pformat(processed_result)}") if self._item_stream: await self._item_stream.send(processed_result) else: @@ -116,6 +132,8 @@ class CrawlerEngine: elif result is not None: log.error(f"Spider must return Request, dict or None, got '{type(result)}' in {request}") except Exception as e: + msg = f"Spider error processing {request}:\n {e}" + log.error(msg, exc_info=e) await self.spider.on_error(request, e) async def _task_wrapper(self, request: Request) -> None: @@ -125,25 +143,95 @@ class CrawlerEngine: finally: self._active_tasks -= 1 + def request_pause(self) -> None: + """Request a graceful pause of the crawl.""" + if not self._pause_requested: + self._pause_requested = True + log.info("Pause requested, waiting for in-flight requests to complete...") + + async def _save_checkpoint(self) -> None: + """Save current state to checkpoint files.""" + requests, seen = self.scheduler.snapshot() + data = CheckpointData(requests=requests, seen=seen) + await self._checkpoint_manager.save(data) + self._last_checkpoint_time = anyio.current_time() + + def _is_checkpoint_time(self) -> bool: + """Check if it's time for the periodic checkpoint.""" + if not self._checkpoint_system_enabled: + return False + + if self._checkpoint_manager.interval == 0: + return False + + current_time = anyio.current_time() + return (current_time - self._last_checkpoint_time) >= self._checkpoint_manager.interval + + async def _restore_from_checkpoint(self) -> bool: + """Attempt to restore state from checkpoint. + + Returns True if successfully restored, False otherwise. + """ + if not self._checkpoint_system_enabled: + raise + + data = await self._checkpoint_manager.load() + if data is None: + return False + + self.scheduler.restore(data) + + # Restore callbacks from spider after scheduler restore + for request in data.requests: + request._restore_callback(self.spider) + + return True + async def crawl(self) -> CrawlStats: """Run the spider and return CrawlStats.""" self._running = True self._items.clear() + self.paused = False + self._pause_requested = False self.stats = CrawlStats(start_time=anyio.current_time()) + # Check for existing checkpoint + resuming = (await self._restore_from_checkpoint()) if self._checkpoint_system_enabled else False + self._last_checkpoint_time = anyio.current_time() + async with self.session_manager: self.stats.concurrent_requests = self.spider.concurrent_requests self.stats.concurrent_requests_per_domain = self.spider.concurrent_requests_per_domain self.stats.download_delay = self.spider.download_delay - await self.spider.on_start() + await self.spider.on_start(resuming=resuming) try: - async for request in self.spider.start_requests(): - await self.scheduler.enqueue(request) + if not resuming: + async for request in self.spider.start_requests(): + await self.scheduler.enqueue(request) + else: + log.info("Resuming from checkpoint, skipping start_requests()") # Process queue async with create_task_group() as tg: while self._running: + # Check for pause request + if self._checkpoint_system_enabled: + if self._pause_requested: + # Wait for active tasks to complete + if self._active_tasks == 0: + await self._save_checkpoint() + self.paused = True + self._running = False + log.info("Spider paused, checkpoint saved") + break + # Wait briefly and check again + await anyio.sleep(0.05) + continue + + if self._is_checkpoint_time(): + await self._save_checkpoint() + if self.scheduler.is_empty: # Empty queue + no active tasks = done if self._active_tasks == 0: @@ -161,6 +249,9 @@ class CrawlerEngine: finally: await self.spider.on_close() + # Clean up checkpoint files on successful completion (not paused) + if not self.paused and self._checkpoint_system_enabled: + await self._checkpoint_manager.cleanup() self.stats.log_levels_counter = self.spider._log_counter.get_counts() self.stats.end_time = anyio.current_time() diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py index e6b25d0..e2fb588 100644 --- a/scrapling/spiders/request.py +++ b/scrapling/spiders/request.py @@ -1,7 +1,10 @@ from urllib.parse import urlparse from scrapling.engines.toolbelt.custom import Response -from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union +from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union, TYPE_CHECKING + +if TYPE_CHECKING: + from scrapling.spiders.spider import Spider class Request: @@ -72,3 +75,26 @@ class Request: if not isinstance(other, Request): return NotImplemented return self._fp == other._fp + + def __getstate__(self) -> dict[str, Any]: + """Prepare state for pickling - store callback as name string for pickle compatibility.""" + state = self.__dict__.copy() + state["_callback_name"] = getattr(self.callback, "__name__", None) if self.callback is not None else None + state["callback"] = None # Don't pickle the actual callable + return state + + def __setstate__(self, state: dict[str, Any]) -> None: + """Restore state from pickle - callback restored later via _restore_callback().""" + self._callback_name: str | None = state.pop("_callback_name", None) + self.__dict__.update(state) + + def _restore_callback(self, spider: "Spider") -> None: + """Restore callback from spider after unpickling. + + :param spider: Spider instance to look up callback method on + """ + if hasattr(self, "_callback_name") and self._callback_name: + self.callback = getattr(spider, self._callback_name, None) or spider.parse + del self._callback_name + elif hasattr(self, "_callback_name"): + del self._callback_name diff --git a/scrapling/spiders/result.py b/scrapling/spiders/result.py index 7e38a81..eeb5522 100644 --- a/scrapling/spiders/result.py +++ b/scrapling/spiders/result.py @@ -112,6 +112,12 @@ class CrawlResult: stats: CrawlStats items: ItemList + paused: bool = False + + @property + def completed(self) -> bool: + """True if the crawl completed normally (not paused).""" + return not self.paused def __len__(self) -> int: return len(self.items) diff --git a/scrapling/spiders/scheduler.py b/scrapling/spiders/scheduler.py index 2890e50..e36472e 100644 --- a/scrapling/spiders/scheduler.py +++ b/scrapling/spiders/scheduler.py @@ -3,6 +3,10 @@ from itertools import count from scrapling.core.utils import log from scrapling.spiders.request import Request +from scrapling.core._types import List, Set, Tuple, TYPE_CHECKING + +if TYPE_CHECKING: + from scrapling.spiders.checkpoint import CheckpointData class Scheduler: @@ -17,6 +21,8 @@ class Scheduler: self._queue: asyncio.PriorityQueue[tuple[int, int, Request]] = asyncio.PriorityQueue() self._seen: set[str] = set() self._counter = count() + # Mirror dict for snapshot without draining queue + self._pending: dict[int, tuple[int, int, Request]] = {} async def enqueue(self, request: Request) -> bool: """Add a request to the queue.""" @@ -29,12 +35,16 @@ class Scheduler: self._seen.add(fingerprint) # Negative priority so higher priority = dequeued first - await self._queue.put((-request.priority, next(self._counter), request)) + counter = next(self._counter) + item = (-request.priority, counter, request) + self._pending[counter] = item + await self._queue.put(item) return True async def dequeue(self) -> Request: """Get the next request to process.""" - _, _, request = await self._queue.get() + _, counter, request = await self._queue.get() + self._pending.pop(counter, None) return request def __len__(self) -> int: @@ -43,3 +53,25 @@ class Scheduler: @property def is_empty(self) -> bool: return self._queue.empty() + + def snapshot(self) -> Tuple[List[Request], Set[str]]: + """Create a snapshot of the current state for checkpoints.""" + sorted_items = sorted(self._pending.values(), key=lambda x: (x[0], x[1])) # Maintain queue order + requests = [item[2] for item in sorted_items] + return requests, self._seen.copy() + + def restore(self, data: "CheckpointData") -> None: + """Restore scheduler state from checkpoint data. + + :param data: CheckpointData containing requests and seen set + """ + self._seen = data.seen.copy() + + # Restore pending requests in order (they're already sorted by priority) + for request in data.requests: + counter = next(self._counter) + item = (-request.priority, counter, request) + self._pending[counter] = item + self._queue.put_nowait(item) + + log.info(f"Scheduler restored: {len(data.requests)} requests, {len(data.seen)} seen") diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index aedab1a..bde8f78 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -1,15 +1,17 @@ +import signal import logging from pathlib import Path from abc import ABC, abstractmethod import anyio +from anyio import Path as AsyncPath from scrapling.spiders.request import Request from scrapling.spiders.engine import CrawlerEngine from scrapling.spiders.session import SessionManager from scrapling.core.utils import set_logger, reset_logger from scrapling.spiders.result import CrawlResult, CrawlStats -from scrapling.core._types import Set, Any, Dict, Optional, TYPE_CHECKING, AsyncGenerator +from scrapling.core._types import Set, Any, Dict, Optional, Union, TYPE_CHECKING, AsyncGenerator BLOCKED_CODES = {401, 403, 407, 429, 444, 500, 502, 503, 504} if TYPE_CHECKING: @@ -82,7 +84,12 @@ class Spider(ABC): logging_date_format: str = "%Y-%m-%d %H:%M:%S" log_file: Optional[str] = None - def __init__(self): + def __init__(self, crawldir: Optional[Union[str, Path, AsyncPath]] = None, interval: float = 300.0): + """Initialize the spider. + + :param crawldir: Directory for checkpoint files. If provided, enables pause/resume. + :param interval: Seconds between periodic checkpoint saves (default 5 minutes). + """ if self.name is None: raise ValueError(f"{self.__class__.__name__} must have a name.") @@ -109,8 +116,12 @@ class Spider(ABC): file_handler.setFormatter(formatter) self.logger.addHandler(file_handler) + self.crawldir: Optional[Path] = Path(crawldir) if crawldir else None + self._interval = interval + self._engine: Optional[CrawlerEngine] = None + self._original_sigint_handler: Any = None + self._session_manager = SessionManager() - self._stream_engine: CrawlerEngine | None = None try: self.configure_sessions(self._session_manager) @@ -143,11 +154,17 @@ class Spider(ABC): async def parse(self, response: "Response") -> AsyncGenerator[Dict[str, Any] | Request | None, None]: """Default callback for processing responses""" raise NotImplementedError(f"{self.__class__.__name__} must implement parse() method") - yield # Make this a generator + yield # Make this a generator for type checkers - async def on_start(self) -> None: - """Called before crawling starts. Override for setup logic.""" - self.logger.debug("Starting spider") + async def on_start(self, resuming: bool = False) -> None: + """Called before crawling starts. Override for setup logic. + + :param resuming: It's enabled if the spider is resuming from a checkpoint, left for the user to use. + """ + if resuming: + self.logger.debug("Resuming spider from checkpoint") + else: + self.logger.debug("Starting spider") async def on_close(self) -> None: """Called after crawling finishes. Override for cleanup logic.""" @@ -159,7 +176,7 @@ class Spider(ABC): Override for custom error handling. """ - self.logger.error(error, exc_info=error) + pass async def on_scraped_item(self, item: Dict[str, Any]) -> Dict[str, Any] | None: """A hook to be overridden by users to do some processing on scraped items, return `None` to drop the item silently.""" @@ -193,13 +210,45 @@ class Spider(ABC): manager.add("default", FetcherSession()) + def pause(self): + """Pause the crawling process if checkpoint system is enabled.""" + if self._engine: + self._engine.request_pause() + else: + raise RuntimeError("Spider doesn't have active crawl to pause, no crawl engine started!") + + def _setup_signal_handler(self) -> None: + """Set up SIGINT handler for graceful pause.""" + + def handler(_signum: int, _frame: Any) -> None: + if self._engine: + self._engine.request_pause() + else: + # No engine yet, just raise KeyboardInterrupt + raise KeyboardInterrupt + + try: + self._original_sigint_handler = signal.signal(signal.SIGINT, handler) + except ValueError: + self._original_sigint_handler = None + + def _restore_signal_handler(self) -> None: + """Restore original SIGINT handler.""" + if self._original_sigint_handler is not None: + try: + signal.signal(signal.SIGINT, self._original_sigint_handler) + except ValueError: + pass + async def __run(self) -> CrawlResult: token = set_logger(self.logger) try: - engine = CrawlerEngine(self, session_manager=self._session_manager) - stats = await engine.crawl() - return CrawlResult(stats=stats, items=engine.items) + self._engine = CrawlerEngine(self, self._session_manager, self.crawldir, self._interval) + stats = await self._engine.crawl() + paused = self._engine.paused + return CrawlResult(stats=stats, items=self._engine.items, paused=paused) finally: + self._engine = None reset_logger(token) # Close any file handlers to release file resources. if self.log_file: @@ -213,27 +262,41 @@ class Spider(ABC): This is the main entry point for running a spider. Handles async execution internally via anyio. + If crawldir is set, pressing Ctrl+C will pause the spider and save a checkpoint. + Running the spider again with the same crawldir will resume from the checkpoint. + :param use_uvloop: Whether to use the faster uvloop/winloop event loop implementation, if available. :param backend_options: Asyncio backend options to be used with `anyio.run` """ backend_options = backend_options or {} if use_uvloop: backend_options.update({"use_uvloop": True}) - return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) + + # Set up SIGINT handler for graceful pause (only if crawldir is set) + if self.crawldir: + self._setup_signal_handler() + + try: + return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) + finally: + if self.crawldir: + self._restore_signal_handler() async def stream(self) -> AsyncGenerator[Dict[str, Any], None]: """Stream items as they're scraped. Ideal for long-running spiders or building applications on top of the spiders. Must be called from an async context. Yields items one by one as they are scraped. Access `spider.stats` during iteration for real-time statistics. + + Note: SIGINT handling for pause/resume is not available in stream mode. """ token = set_logger(self.logger) try: - self._stream_engine = CrawlerEngine(self, self._session_manager) - async for item in self._stream_engine: + self._engine = CrawlerEngine(self, self._session_manager, self.crawldir, self._interval) + async for item in self._engine: yield item finally: - self._stream_engine = None + self._engine = None reset_logger(token) if self.log_file: for handler in self.logger.handlers: @@ -243,6 +306,6 @@ class Spider(ABC): @property def stats(self) -> CrawlStats: """Access current crawl stats (works during streaming).""" - if self._stream_engine: - return self._stream_engine.stats + if self._engine: + return self._engine.stats raise RuntimeError("No active crawl. Use this property inside `async for item in spider.stream():`") From 0d003f62e35118645cf4dd416cf8a50d23277c05 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 03:45:39 +0200 Subject: [PATCH 34/80] ops: update bandit checklist --- .bandit.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.bandit.yml b/.bandit.yml index f74f22f..bd06507 100644 --- a/.bandit.yml +++ b/.bandit.yml @@ -7,4 +7,5 @@ skips: - B602 # subprocess call with shell=True identified - B110 # Try, Except, Pass detected. - B104 # Possible binding to all interfaces. -- B301 # Pickle and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue. \ No newline at end of file +- B301 # Pickle and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue. +- B108 # Probable insecure usage of temp file/directory. \ No newline at end of file From d247b5b691d80b0a37176d61ee20ce7f862df344 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 03:46:00 +0200 Subject: [PATCH 35/80] test: add tests for the spiders system It's generated by Opus on Claude Code. It's very good as per my review and instructions, but I will have another look later. --- tests/spiders/__init__.py | 0 tests/spiders/test_checkpoint.py | 341 ++++++++++++++++++ tests/spiders/test_request.py | 363 +++++++++++++++++++ tests/spiders/test_result.py | 327 ++++++++++++++++++ tests/spiders/test_scheduler.py | 390 +++++++++++++++++++++ tests/spiders/test_session.py | 352 +++++++++++++++++++ tests/spiders/test_spider.py | 574 +++++++++++++++++++++++++++++++ 7 files changed, 2347 insertions(+) create mode 100644 tests/spiders/__init__.py create mode 100644 tests/spiders/test_checkpoint.py create mode 100644 tests/spiders/test_request.py create mode 100644 tests/spiders/test_result.py create mode 100644 tests/spiders/test_scheduler.py create mode 100644 tests/spiders/test_session.py create mode 100644 tests/spiders/test_spider.py diff --git a/tests/spiders/__init__.py b/tests/spiders/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/spiders/test_checkpoint.py b/tests/spiders/test_checkpoint.py new file mode 100644 index 0000000..fc35f43 --- /dev/null +++ b/tests/spiders/test_checkpoint.py @@ -0,0 +1,341 @@ +"""Tests for the CheckpointManager and CheckpointData classes.""" + +import pickle +import tempfile +from pathlib import Path + +import pytest +import anyio + +from scrapling.spiders.request import Request +from scrapling.spiders.checkpoint import CheckpointData, CheckpointManager + + +class TestCheckpointData: + """Test CheckpointData dataclass.""" + + def test_default_values(self): + """Test CheckpointData with default values.""" + data = CheckpointData() + + assert data.requests == [] + assert data.seen == set() + + def test_with_requests_and_seen(self): + """Test CheckpointData with requests and seen URLs.""" + requests = [ + Request("https://example.com/1", priority=10), + Request("https://example.com/2", priority=5), + ] + seen = {"url1", "url2", "url3"} + + data = CheckpointData(requests=requests, seen=seen) + + assert len(data.requests) == 2 + assert data.requests[0].url == "https://example.com/1" + assert data.seen == {"url1", "url2", "url3"} + + def test_pickle_roundtrip(self): + """Test that CheckpointData can be pickled and unpickled.""" + requests = [Request("https://example.com", priority=5)] + seen = {"fingerprint1", "fingerprint2"} + data = CheckpointData(requests=requests, seen=seen) + + pickled = pickle.dumps(data) + restored = pickle.loads(pickled) + + assert len(restored.requests) == 1 + assert restored.requests[0].url == "https://example.com" + assert restored.seen == {"fingerprint1", "fingerprint2"} + + +class TestCheckpointManagerInit: + """Test CheckpointManager initialization.""" + + def test_init_with_string_path(self): + """Test initialization with string path.""" + manager = CheckpointManager("/tmp/test_crawl") + + assert str(manager.crawldir) == "/tmp/test_crawl" + assert manager.interval == 300.0 + + def test_init_with_pathlib_path(self): + """Test initialization with pathlib.Path.""" + path = Path("/tmp/test_crawl") + manager = CheckpointManager(path) + + assert str(manager.crawldir) == "/tmp/test_crawl" + + def test_init_with_custom_interval(self): + """Test initialization with custom interval.""" + manager = CheckpointManager("/tmp/test", interval=60.0) + assert manager.interval == 60.0 + + def test_init_with_zero_interval(self): + """Test initialization with zero interval (disable periodic checkpoints).""" + manager = CheckpointManager("/tmp/test", interval=0) + assert manager.interval == 0 + + def test_init_with_negative_interval_raises(self): + """Test that negative interval raises ValueError.""" + with pytest.raises(ValueError, match="greater than 0"): + CheckpointManager("/tmp/test", interval=-1) + + def test_init_with_invalid_interval_type_raises(self): + """Test that invalid interval type raises TypeError.""" + with pytest.raises(TypeError, match="integer or float"): + CheckpointManager("/tmp/test", interval="invalid") # type: ignore + + def test_checkpoint_file_path(self): + """Test that checkpoint file path is correctly constructed.""" + manager = CheckpointManager("/tmp/test_crawl") + + expected_path = "/tmp/test_crawl/checkpoint.pkl" + assert str(manager._checkpoint_path) == expected_path + + +class TestCheckpointManagerOperations: + """Test CheckpointManager save/load/cleanup operations.""" + + @pytest.fixture + def temp_dir(self): + """Create a temporary directory for testing.""" + with tempfile.TemporaryDirectory() as tmpdir: + yield Path(tmpdir) + + @pytest.mark.asyncio + async def test_has_checkpoint_false_when_no_file(self, temp_dir: Path): + """Test has_checkpoint returns False when no checkpoint exists.""" + manager = CheckpointManager(temp_dir / "crawl") + + result = await manager.has_checkpoint() + + assert result is False + + @pytest.mark.asyncio + async def test_save_creates_checkpoint_file(self, temp_dir: Path): + """Test that save creates the checkpoint file.""" + crawl_dir = temp_dir / "crawl" + manager = CheckpointManager(crawl_dir) + + data = CheckpointData( + requests=[Request("https://example.com")], + seen={"fp1", "fp2"}, + ) + + await manager.save(data) + + checkpoint_path = crawl_dir / "checkpoint.pkl" + assert checkpoint_path.exists() + + @pytest.mark.asyncio + async def test_save_creates_directory_if_not_exists(self, temp_dir: Path): + """Test that save creates the directory if it doesn't exist.""" + crawl_dir = temp_dir / "nested" / "crawl" / "dir" + manager = CheckpointManager(crawl_dir) + + data = CheckpointData() + await manager.save(data) + + assert crawl_dir.exists() + + @pytest.mark.asyncio + async def test_has_checkpoint_true_after_save(self, temp_dir: Path): + """Test has_checkpoint returns True after saving.""" + manager = CheckpointManager(temp_dir / "crawl") + + data = CheckpointData() + await manager.save(data) + + result = await manager.has_checkpoint() + assert result is True + + @pytest.mark.asyncio + async def test_load_returns_none_when_no_checkpoint(self, temp_dir: Path): + """Test load returns None when no checkpoint exists.""" + manager = CheckpointManager(temp_dir / "crawl") + + result = await manager.load() + + assert result is None + + @pytest.mark.asyncio + async def test_save_and_load_roundtrip(self, temp_dir: Path): + """Test saving and loading checkpoint data.""" + manager = CheckpointManager(temp_dir / "crawl") + + original_data = CheckpointData( + requests=[ + Request("https://example.com/1", priority=10), + Request("https://example.com/2", priority=5), + ], + seen={"fp1", "fp2", "fp3"}, + ) + + await manager.save(original_data) + loaded_data = await manager.load() + + assert loaded_data is not None + assert len(loaded_data.requests) == 2 + assert loaded_data.requests[0].url == "https://example.com/1" + assert loaded_data.requests[0].priority == 10 + assert loaded_data.seen == {"fp1", "fp2", "fp3"} + + @pytest.mark.asyncio + async def test_save_is_atomic(self, temp_dir: Path): + """Test that save uses atomic write (temp file + rename).""" + crawl_dir = temp_dir / "crawl" + manager = CheckpointManager(crawl_dir) + + data = CheckpointData(requests=[Request("https://example.com")]) + await manager.save(data) + + # Temp file should not exist after successful save + temp_path = crawl_dir / "checkpoint.tmp" + assert not temp_path.exists() + + # Checkpoint file should exist + checkpoint_path = crawl_dir / "checkpoint.pkl" + assert checkpoint_path.exists() + + @pytest.mark.asyncio + async def test_cleanup_removes_checkpoint_file(self, temp_dir: Path): + """Test that cleanup removes the checkpoint file.""" + crawl_dir = temp_dir / "crawl" + manager = CheckpointManager(crawl_dir) + + # Save a checkpoint first + data = CheckpointData() + await manager.save(data) + + checkpoint_path = crawl_dir / "checkpoint.pkl" + assert checkpoint_path.exists() + + # Cleanup should remove it + await manager.cleanup() + + assert not checkpoint_path.exists() + + @pytest.mark.asyncio + async def test_cleanup_no_error_when_no_file(self, temp_dir: Path): + """Test that cleanup doesn't raise error when no file exists.""" + manager = CheckpointManager(temp_dir / "crawl") + + # Should not raise + await manager.cleanup() + + @pytest.mark.asyncio + async def test_load_returns_none_on_corrupt_file(self, temp_dir: Path): + """Test load returns None when checkpoint file is corrupt.""" + crawl_dir = temp_dir / "crawl" + crawl_dir.mkdir(parents=True) + + checkpoint_path = crawl_dir / "checkpoint.pkl" + checkpoint_path.write_bytes(b"not valid pickle data") + + manager = CheckpointManager(crawl_dir) + + result = await manager.load() + + assert result is None + + @pytest.mark.asyncio + async def test_multiple_saves_overwrite(self, temp_dir: Path): + """Test that multiple saves overwrite the checkpoint.""" + manager = CheckpointManager(temp_dir / "crawl") + + # First save + data1 = CheckpointData( + requests=[Request("https://example.com/1")], + seen={"fp1"}, + ) + await manager.save(data1) + + # Second save + data2 = CheckpointData( + requests=[Request("https://example.com/2"), Request("https://example.com/3")], + seen={"fp2", "fp3"}, + ) + await manager.save(data2) + + # Load should return the second save + loaded = await manager.load() + + assert loaded is not None + assert len(loaded.requests) == 2 + assert loaded.requests[0].url == "https://example.com/2" + assert loaded.seen == {"fp2", "fp3"} + + +class TestCheckpointManagerEdgeCases: + """Test edge cases for CheckpointManager.""" + + @pytest.fixture + def temp_dir(self): + """Create a temporary directory for testing.""" + with tempfile.TemporaryDirectory() as tmpdir: + yield Path(tmpdir) + + @pytest.mark.asyncio + async def test_save_empty_checkpoint(self, temp_dir: Path): + """Test saving empty checkpoint data.""" + manager = CheckpointManager(temp_dir / "crawl") + + data = CheckpointData(requests=[], seen=set()) + await manager.save(data) + + loaded = await manager.load() + + assert loaded is not None + assert loaded.requests == [] + assert loaded.seen == set() + + @pytest.mark.asyncio + async def test_save_large_checkpoint(self, temp_dir: Path): + """Test saving checkpoint with many requests.""" + manager = CheckpointManager(temp_dir / "crawl") + + # Create 1000 requests + requests = [ + Request(f"https://example.com/{i}", priority=i % 10) + for i in range(1000) + ] + seen = {f"fp_{i}" for i in range(2000)} + + data = CheckpointData(requests=requests, seen=seen) + await manager.save(data) + + loaded = await manager.load() + + assert loaded is not None + assert len(loaded.requests) == 1000 + assert len(loaded.seen) == 2000 + + @pytest.mark.asyncio + async def test_requests_preserve_metadata(self, temp_dir: Path): + """Test that request metadata is preserved through checkpoint.""" + manager = CheckpointManager(temp_dir / "crawl") + + original_request = Request( + url="https://example.com", + sid="my_session", + priority=42, + dont_filter=True, + meta={"item_id": 123, "page": 5}, + proxy="http://proxy:8080", + ) + + data = CheckpointData(requests=[original_request], seen=set()) + await manager.save(data) + + loaded = await manager.load() + + assert loaded is not None + restored = loaded.requests[0] + + assert restored.url == "https://example.com" + assert restored.sid == "my_session" + assert restored.priority == 42 + assert restored.dont_filter is True + assert restored.meta == {"item_id": 123, "page": 5} + assert restored._session_kwargs == {"proxy": "http://proxy:8080"} diff --git a/tests/spiders/test_request.py b/tests/spiders/test_request.py new file mode 100644 index 0000000..f6860cf --- /dev/null +++ b/tests/spiders/test_request.py @@ -0,0 +1,363 @@ +"""Tests for the Request class.""" + +import pickle + +import pytest + +from scrapling.spiders.request import Request +from scrapling.core._types import Any, Dict, AsyncGenerator + + +class TestRequestCreation: + """Test Request initialization and basic attributes.""" + + def test_basic_request_creation(self): + """Test creating a request with just a URL.""" + request = Request("https://example.com") + + assert request.url == "https://example.com" + assert request.sid == "" + assert request.callback is None + assert request.priority == 0 + assert request.dont_filter is False + assert request.meta == {} + assert request._retry_count == 0 + assert request._session_kwargs == {} + + def test_request_with_all_parameters(self): + """Test creating a request with all parameters.""" + + async def my_callback(response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield {"test": "data"} + + request = Request( + url="https://example.com/page", + sid="my_session", + callback=my_callback, + priority=10, + dont_filter=True, + meta={"key": "value"}, + _retry_count=2, + proxy="http://proxy:8080", + timeout=30, + ) + + assert request.url == "https://example.com/page" + assert request.sid == "my_session" + assert request.callback == my_callback + assert request.priority == 10 + assert request.dont_filter is True + assert request.meta == {"key": "value"} + assert request._retry_count == 2 + assert request._session_kwargs == {"proxy": "http://proxy:8080", "timeout": 30} + + def test_request_meta_default_is_empty_dict(self): + """Test that meta defaults to empty dict, not shared reference.""" + r1 = Request("https://example.com") + r2 = Request("https://example.com") + + r1.meta["key"] = "value" + + assert r1.meta == {"key": "value"} + assert r2.meta == {} + + +class TestRequestProperties: + """Test Request computed properties.""" + + def test_domain_extraction(self): + """Test domain property extracts netloc correctly.""" + request = Request("https://www.example.com/path/page.html?query=1") + assert request.domain == "www.example.com" + + def test_domain_with_port(self): + """Test domain extraction with port number.""" + request = Request("http://localhost:8080/api") + assert request.domain == "localhost:8080" + + def test_domain_with_subdomain(self): + """Test domain extraction with subdomains.""" + request = Request("https://api.v2.example.com/endpoint") + assert request.domain == "api.v2.example.com" + + def test_fingerprint_includes_session_and_url(self): + """Test fingerprint generation.""" + request = Request("https://example.com", sid="session1") + assert request._fp == "session1:https://example.com" + + def test_fingerprint_empty_session(self): + """Test fingerprint with empty session ID.""" + request = Request("https://example.com") + assert request._fp == ":https://example.com" + + +class TestRequestCopy: + """Test Request copy functionality.""" + + def test_copy_creates_independent_request(self): + """Test that copy creates a new independent request.""" + + async def callback(response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + original = Request( + url="https://example.com", + sid="session", + callback=callback, + priority=5, + dont_filter=True, + meta={"original": True}, + _retry_count=1, + proxy="http://proxy:8080", + ) + + copied = original.copy() + + # Check all values are copied + assert copied.url == original.url + assert copied.sid == original.sid + assert copied.callback == original.callback + assert copied.priority == original.priority + assert copied.dont_filter == original.dont_filter + assert copied.meta == original.meta + assert copied._retry_count == original._retry_count + assert copied._session_kwargs == original._session_kwargs + + # Check they are different objects + assert copied is not original + assert copied.meta is not original.meta # Meta should be a copy + + def test_copy_meta_is_independent(self): + """Test that modifying copied meta doesn't affect original.""" + original = Request("https://example.com", meta={"key": "original"}) + copied = original.copy() + + copied.meta["key"] = "modified" + copied.meta["new_key"] = "new_value" + + assert original.meta == {"key": "original"} + assert copied.meta == {"key": "modified", "new_key": "new_value"} + + +class TestRequestComparison: + """Test Request comparison operators.""" + + def test_priority_less_than(self): + """Test less than comparison by priority.""" + low_priority = Request("https://example.com/1", priority=1) + high_priority = Request("https://example.com/2", priority=10) + + assert low_priority < high_priority + assert not high_priority < low_priority + + def test_priority_greater_than(self): + """Test greater than comparison by priority.""" + low_priority = Request("https://example.com/1", priority=1) + high_priority = Request("https://example.com/2", priority=10) + + assert high_priority > low_priority + assert not low_priority > high_priority + + def test_equality_by_fingerprint(self): + """Test equality comparison by fingerprint.""" + r1 = Request("https://example.com", sid="session1") + r2 = Request("https://example.com", sid="session1") + r3 = Request("https://example.com", sid="session2") + + assert r1 == r2 + assert r1 != r3 + + def test_equality_different_priorities_same_fingerprint(self): + """Test requests with same fingerprint are equal despite different priorities.""" + r1 = Request("https://example.com", sid="s1", priority=1) + r2 = Request("https://example.com", sid="s1", priority=100) + + assert r1 == r2 # Same fingerprint means equal + + def test_comparison_with_non_request(self): + """Test comparison with non-Request types returns NotImplemented.""" + request = Request("https://example.com") + + assert request.__lt__("not a request") == NotImplemented + assert request.__gt__("not a request") == NotImplemented + assert request.__eq__("not a request") == NotImplemented + + +class TestRequestStringRepresentation: + """Test Request string representations.""" + + def test_str_returns_url(self): + """Test __str__ returns the URL.""" + request = Request("https://example.com/page") + assert str(request) == "https://example.com/page" + + def test_repr_without_callback(self): + """Test __repr__ without callback.""" + request = Request("https://example.com", priority=5) + repr_str = repr(request) + + assert "Request" in repr_str + assert "https://example.com" in repr_str + assert "priority=5" in repr_str + assert "callback=None" in repr_str + + def test_repr_with_callback(self): + """Test __repr__ with named callback.""" + + async def my_custom_callback(response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + request = Request("https://example.com", callback=my_custom_callback) + repr_str = repr(request) + + assert "callback=my_custom_callback" in repr_str + + +class TestRequestPickling: + """Test Request serialization for checkpointing.""" + + def test_pickle_without_callback(self): + """Test pickling request without callback.""" + original = Request( + url="https://example.com", + sid="session", + priority=5, + meta={"key": "value"}, + ) + + pickled = pickle.dumps(original) + restored = pickle.loads(pickled) + + assert restored.url == original.url + assert restored.sid == original.sid + assert restored.priority == original.priority + assert restored.meta == original.meta + assert restored.callback is None + + def test_pickle_with_callback_stores_name(self): + """Test that callback name is stored when pickling.""" + + async def parse_page(response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield {"data": "test"} + + original = Request("https://example.com", callback=parse_page) + + # Check getstate stores callback name + state = original.__getstate__() + assert state["_callback_name"] == "parse_page" + assert state["callback"] is None + + def test_pickle_with_none_callback(self): + """Test pickling with None callback.""" + original = Request("https://example.com", callback=None) + + state = original.__getstate__() + assert state["_callback_name"] is None + assert state["callback"] is None + + def test_setstate_stores_callback_name(self): + """Test that setstate correctly handles callback name.""" + request = Request("https://example.com") + state = { + "url": "https://example.com", + "sid": "", + "callback": None, + "priority": 0, + "dont_filter": False, + "meta": {}, + "_retry_count": 0, + "_session_kwargs": {}, + "_callback_name": "custom_parse", + } + + request.__setstate__(state) + + assert hasattr(request, "_callback_name") + assert request._callback_name == "custom_parse" + + def test_pickle_roundtrip_preserves_session_kwargs(self): + """Test that session kwargs are preserved through pickle.""" + original = Request( + "https://example.com", + proxy="http://proxy:8080", + timeout=30, + headers={"User-Agent": "test"}, + ) + + pickled = pickle.dumps(original) + restored = pickle.loads(pickled) + + assert restored._session_kwargs == { + "proxy": "http://proxy:8080", + "timeout": 30, + "headers": {"User-Agent": "test"}, + } + + +class TestRequestRestoreCallback: + """Test callback restoration from spider.""" + + def test_restore_callback_from_spider(self): + """Test restoring callback from spider instance.""" + + class MockSpider: + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + async def parse_detail(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield {"detail": True} + + spider = MockSpider() + request = Request("https://example.com") + request._callback_name = "parse_detail" + + request._restore_callback(spider) # type: ignore[arg-type] + + assert request.callback == spider.parse_detail + assert not hasattr(request, "_callback_name") + + def test_restore_callback_falls_back_to_parse(self): + """Test that missing callback falls back to spider.parse.""" + + class MockSpider: + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = MockSpider() + request = Request("https://example.com") + request._callback_name = "nonexistent_method" + + request._restore_callback(spider) # type: ignore[arg-type] + + assert request.callback == spider.parse + assert not hasattr(request, "_callback_name") + + def test_restore_callback_with_none_name(self): + """Test restore callback when _callback_name is None.""" + + class MockSpider: + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = MockSpider() + request = Request("https://example.com") + request._callback_name = None + + request._restore_callback(spider) # type: ignore[arg-type] + + # Should clean up _callback_name attribute + assert not hasattr(request, "_callback_name") + + def test_restore_callback_without_callback_name_attr(self): + """Test restore callback when _callback_name attribute doesn't exist.""" + + class MockSpider: + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = MockSpider() + request = Request("https://example.com") + # Don't set _callback_name + + # Should not raise an error + request._restore_callback(spider) # type: ignore[arg-type] diff --git a/tests/spiders/test_result.py b/tests/spiders/test_result.py new file mode 100644 index 0000000..f59f236 --- /dev/null +++ b/tests/spiders/test_result.py @@ -0,0 +1,327 @@ +"""Tests for the result module (ItemList, CrawlStats, CrawlResult).""" + +import json +import tempfile +from pathlib import Path + +import pytest + +from scrapling.spiders.result import ItemList, CrawlStats, CrawlResult + + +class TestItemList: + """Test ItemList functionality.""" + + def test_itemlist_is_list(self): + """Test that ItemList is a list subclass.""" + items = ItemList() + + assert isinstance(items, list) + + def test_itemlist_basic_operations(self): + """Test basic list operations work.""" + items = ItemList() + + items.append({"id": 1}) + items.append({"id": 2}) + + assert len(items) == 2 + assert items[0] == {"id": 1} + + def test_to_json_creates_file(self): + """Test to_json creates JSON file.""" + items = ItemList() + items.append({"name": "test", "value": 123}) + items.append({"name": "test2", "value": 456}) + + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "output.json" + items.to_json(path) + + assert path.exists() + + content = json.loads(path.read_text()) + assert len(content) == 2 + assert content[0]["name"] == "test" + + def test_to_json_creates_parent_directory(self): + """Test to_json creates parent directories.""" + items = ItemList() + items.append({"data": "test"}) + + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "nested" / "dirs" / "output.json" + items.to_json(path) + + assert path.exists() + + def test_to_json_with_indent(self): + """Test to_json with indentation.""" + items = ItemList() + items.append({"key": "value"}) + + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "output.json" + items.to_json(path, indent=True) + + content = path.read_text() + # Indented JSON should have newlines + assert "\n" in content + + def test_to_jsonl_creates_file(self): + """Test to_jsonl creates JSON Lines file.""" + items = ItemList() + items.append({"id": 1, "name": "first"}) + items.append({"id": 2, "name": "second"}) + items.append({"id": 3, "name": "third"}) + + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "output.jsonl" + items.to_jsonl(path) + + assert path.exists() + + lines = path.read_text().strip().split("\n") + assert len(lines) == 3 + + # Each line should be valid JSON + for line in lines: + parsed = json.loads(line) + assert "id" in parsed + assert "name" in parsed + + def test_to_jsonl_one_object_per_line(self): + """Test that JSONL has one JSON object per line.""" + items = ItemList() + items.append({"line": 1}) + items.append({"line": 2}) + + with tempfile.TemporaryDirectory() as tmpdir: + path = Path(tmpdir) / "output.jsonl" + items.to_jsonl(path) + + lines = path.read_text().strip().split("\n") + + assert json.loads(lines[0])["line"] == 1 + assert json.loads(lines[1])["line"] == 2 + + +class TestCrawlStats: + """Test CrawlStats dataclass.""" + + def test_default_values(self): + """Test CrawlStats default values.""" + stats = CrawlStats() + + assert stats.requests_count == 0 + assert stats.concurrent_requests == 0 + assert stats.failed_requests_count == 0 + assert stats.response_bytes == 0 + assert stats.items_scraped == 0 + assert stats.items_dropped == 0 + assert stats.start_time == 0.0 + assert stats.end_time == 0.0 + assert stats.custom_stats == {} + assert stats.response_status_count == {} + assert stats.proxies == [] + + def test_elapsed_seconds(self): + """Test elapsed_seconds property.""" + stats = CrawlStats(start_time=100.0, end_time=150.0) + + assert stats.elapsed_seconds == 50.0 + + def test_requests_per_second(self): + """Test requests_per_second calculation.""" + stats = CrawlStats( + requests_count=100, + start_time=0.0, + end_time=10.0, + ) + + assert stats.requests_per_second == 10.0 + + def test_requests_per_second_zero_elapsed(self): + """Test requests_per_second when elapsed is zero.""" + stats = CrawlStats( + requests_count=100, + start_time=0.0, + end_time=0.0, + ) + + assert stats.requests_per_second == 0.0 + + def test_increment_status(self): + """Test increment_status method.""" + stats = CrawlStats() + + stats.increment_status(200) + stats.increment_status(200) + stats.increment_status(404) + + assert stats.response_status_count == {"status_200": 2, "status_404": 1} + + def test_increment_response_bytes(self): + """Test increment_response_bytes method.""" + stats = CrawlStats() + + stats.increment_response_bytes("example.com", 1000) + stats.increment_response_bytes("example.com", 500) + stats.increment_response_bytes("other.com", 2000) + + assert stats.response_bytes == 3500 + assert stats.domains_response_bytes == { + "example.com": 1500, + "other.com": 2000, + } + + def test_increment_requests_count(self): + """Test increment_requests_count method.""" + stats = CrawlStats() + + stats.increment_requests_count("session1") + stats.increment_requests_count("session1") + stats.increment_requests_count("session2") + + assert stats.requests_count == 3 + assert stats.sessions_requests_count == {"session1": 2, "session2": 1} + + def test_to_dict(self): + """Test to_dict method returns all stats.""" + stats = CrawlStats( + items_scraped=10, + items_dropped=2, + requests_count=15, + start_time=0.0, + end_time=5.0, + ) + stats.increment_status(200) + + result = stats.to_dict() + + assert result["items_scraped"] == 10 + assert result["items_dropped"] == 2 + assert result["requests_count"] == 15 + assert result["elapsed_seconds"] == 5.0 + assert result["requests_per_second"] == 3.0 + assert result["response_status_count"] == {"status_200": 1} + + def test_custom_stats(self): + """Test custom_stats can be used.""" + stats = CrawlStats() + stats.custom_stats["my_metric"] = 42 + stats.custom_stats["another"] = "value" + + assert stats.custom_stats["my_metric"] == 42 + assert stats.to_dict()["custom_stats"]["my_metric"] == 42 + + +class TestCrawlResult: + """Test CrawlResult dataclass.""" + + def test_basic_creation(self): + """Test basic CrawlResult creation.""" + stats = CrawlStats(items_scraped=5) + items = ItemList() + items.extend([{"id": i} for i in range(5)]) + + result = CrawlResult(stats=stats, items=items) + + assert result.stats.items_scraped == 5 + assert len(result.items) == 5 + assert result.paused is False + + def test_completed_property_true_when_not_paused(self): + """Test completed is True when not paused.""" + result = CrawlResult( + stats=CrawlStats(), + items=ItemList(), + paused=False, + ) + + assert result.completed is True + + def test_completed_property_false_when_paused(self): + """Test completed is False when paused.""" + result = CrawlResult( + stats=CrawlStats(), + items=ItemList(), + paused=True, + ) + + assert result.completed is False + + def test_len_returns_item_count(self): + """Test len returns number of items.""" + items = ItemList() + items.extend([{"id": i} for i in range(10)]) + + result = CrawlResult(stats=CrawlStats(), items=items) + + assert len(result) == 10 + + def test_iter_yields_items(self): + """Test iteration yields items.""" + items = ItemList() + items.extend([{"id": 1}, {"id": 2}, {"id": 3}]) + + result = CrawlResult(stats=CrawlStats(), items=items) + + collected = list(result) + + assert collected == [{"id": 1}, {"id": 2}, {"id": 3}] + + def test_result_with_stats(self): + """Test CrawlResult with populated stats.""" + stats = CrawlStats( + requests_count=100, + items_scraped=50, + failed_requests_count=5, + start_time=0.0, + end_time=10.0, + ) + items = ItemList() + + result = CrawlResult(stats=stats, items=items) + + assert result.stats.requests_count == 100 + assert result.stats.items_scraped == 50 + assert result.stats.requests_per_second == 10.0 + + +class TestCrawlResultIntegration: + """Integration tests for result classes.""" + + def test_full_workflow(self): + """Test realistic workflow with all result classes.""" + # Simulate a crawl + stats = CrawlStats(start_time=1000.0) + + # Simulate requests + for _ in range(10): + stats.increment_requests_count("default") + stats.increment_status(200) + stats.increment_response_bytes("example.com", 5000) + + # Simulate some failures + stats.failed_requests_count = 2 + stats.blocked_requests_count = 1 + + # Collect items + items = ItemList() + for i in range(8): + items.append({"product_id": i, "name": f"Product {i}"}) + stats.items_scraped += 1 + + # Finish crawl + stats.end_time = 1005.0 + + # Create result + result = CrawlResult(stats=stats, items=items, paused=False) + + # Verify + assert result.completed is True + assert len(result) == 8 + assert result.stats.requests_count == 10 + assert result.stats.requests_per_second == 2.0 + assert result.stats.response_bytes == 50000 diff --git a/tests/spiders/test_scheduler.py b/tests/spiders/test_scheduler.py new file mode 100644 index 0000000..70b4ef5 --- /dev/null +++ b/tests/spiders/test_scheduler.py @@ -0,0 +1,390 @@ +"""Tests for the Scheduler class.""" + +import pytest + +from scrapling.spiders.request import Request +from scrapling.spiders.scheduler import Scheduler +from scrapling.spiders.checkpoint import CheckpointData + + +class TestSchedulerInit: + """Test Scheduler initialization.""" + + def test_scheduler_starts_empty(self): + """Test that scheduler starts with empty queue.""" + scheduler = Scheduler() + + assert len(scheduler) == 0 + assert scheduler.is_empty is True + + +class TestSchedulerEnqueue: + """Test Scheduler enqueue functionality.""" + + @pytest.mark.asyncio + async def test_enqueue_single_request(self): + """Test enqueueing a single request.""" + scheduler = Scheduler() + request = Request("https://example.com") + + result = await scheduler.enqueue(request) + + assert result is True + assert len(scheduler) == 1 + assert scheduler.is_empty is False + + @pytest.mark.asyncio + async def test_enqueue_multiple_requests(self): + """Test enqueueing multiple requests.""" + scheduler = Scheduler() + + for i in range(5): + request = Request(f"https://example.com/{i}") + await scheduler.enqueue(request) + + assert len(scheduler) == 5 + + @pytest.mark.asyncio + async def test_enqueue_duplicate_filtered(self): + """Test that duplicate requests are filtered by default.""" + scheduler = Scheduler() + + request1 = Request("https://example.com", sid="s1") + request2 = Request("https://example.com", sid="s1") # Same fingerprint + + result1 = await scheduler.enqueue(request1) + result2 = await scheduler.enqueue(request2) + + assert result1 is True + assert result2 is False # Duplicate filtered + assert len(scheduler) == 1 + + @pytest.mark.asyncio + async def test_enqueue_duplicate_allowed_with_dont_filter(self): + """Test that dont_filter allows duplicate requests.""" + scheduler = Scheduler() + + request1 = Request("https://example.com", sid="s1") + request2 = Request("https://example.com", sid="s1", dont_filter=True) + + result1 = await scheduler.enqueue(request1) + result2 = await scheduler.enqueue(request2) + + assert result1 is True + assert result2 is True + assert len(scheduler) == 2 + + @pytest.mark.asyncio + async def test_enqueue_different_sessions_not_duplicate(self): + """Test that same URL with different sessions are not duplicates.""" + scheduler = Scheduler() + + request1 = Request("https://example.com", sid="session1") + request2 = Request("https://example.com", sid="session2") + + result1 = await scheduler.enqueue(request1) + result2 = await scheduler.enqueue(request2) + + assert result1 is True + assert result2 is True + assert len(scheduler) == 2 + + +class TestSchedulerDequeue: + """Test Scheduler dequeue functionality.""" + + @pytest.mark.asyncio + async def test_dequeue_returns_request(self): + """Test that dequeue returns the enqueued request.""" + scheduler = Scheduler() + original = Request("https://example.com") + + await scheduler.enqueue(original) + dequeued = await scheduler.dequeue() + + assert dequeued.url == original.url + + @pytest.mark.asyncio + async def test_dequeue_respects_priority_order(self): + """Test that higher priority requests are dequeued first.""" + scheduler = Scheduler() + + low = Request("https://example.com/low", priority=1) + high = Request("https://example.com/high", priority=10) + medium = Request("https://example.com/medium", priority=5) + + await scheduler.enqueue(low) + await scheduler.enqueue(high) + await scheduler.enqueue(medium) + + # Should get high priority first + first = await scheduler.dequeue() + assert first.url == "https://example.com/high" + + second = await scheduler.dequeue() + assert second.url == "https://example.com/medium" + + third = await scheduler.dequeue() + assert third.url == "https://example.com/low" + + @pytest.mark.asyncio + async def test_dequeue_fifo_for_same_priority(self): + """Test FIFO ordering for requests with same priority.""" + scheduler = Scheduler() + + for i in range(3): + request = Request(f"https://example.com/{i}", priority=5) + await scheduler.enqueue(request) + + first = await scheduler.dequeue() + second = await scheduler.dequeue() + third = await scheduler.dequeue() + + # Should be in FIFO order since same priority + assert first.url == "https://example.com/0" + assert second.url == "https://example.com/1" + assert third.url == "https://example.com/2" + + @pytest.mark.asyncio + async def test_dequeue_updates_length(self): + """Test that dequeue decreases the queue length.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com/1")) + await scheduler.enqueue(Request("https://example.com/2")) + + assert len(scheduler) == 2 + + await scheduler.dequeue() + assert len(scheduler) == 1 + + await scheduler.dequeue() + assert len(scheduler) == 0 + assert scheduler.is_empty is True + + +class TestSchedulerSnapshot: + """Test Scheduler snapshot functionality for checkpointing.""" + + @pytest.mark.asyncio + async def test_snapshot_empty_scheduler(self): + """Test snapshot of empty scheduler.""" + scheduler = Scheduler() + + requests, seen = scheduler.snapshot() + + assert requests == [] + assert seen == set() + + @pytest.mark.asyncio + async def test_snapshot_captures_pending_requests(self): + """Test snapshot captures all pending requests.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com/1", priority=5)) + await scheduler.enqueue(Request("https://example.com/2", priority=10)) + await scheduler.enqueue(Request("https://example.com/3", priority=1)) + + requests, seen = scheduler.snapshot() + + assert len(requests) == 3 + # Should be sorted by priority (highest first due to negative priority in queue) + assert requests[0].url == "https://example.com/2" # priority 10 + assert requests[1].url == "https://example.com/1" # priority 5 + assert requests[2].url == "https://example.com/3" # priority 1 + + @pytest.mark.asyncio + async def test_snapshot_captures_seen_set(self): + """Test snapshot captures seen URLs.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com/1", sid="s1")) + await scheduler.enqueue(Request("https://example.com/2", sid="s1")) + + requests, seen = scheduler.snapshot() + + assert len(seen) == 2 + assert "s1:https://example.com/1" in seen + assert "s1:https://example.com/2" in seen + + @pytest.mark.asyncio + async def test_snapshot_returns_copies(self): + """Test that snapshot returns copies, not references.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com")) + + requests, seen = scheduler.snapshot() + + # Modifying snapshot shouldn't affect scheduler + requests.append(Request("https://modified.com")) + seen.add("new_fingerprint") + + original_requests, original_seen = scheduler.snapshot() + + assert len(original_requests) == 1 + assert "new_fingerprint" not in original_seen + + @pytest.mark.asyncio + async def test_snapshot_excludes_dequeued_requests(self): + """Test snapshot only includes pending requests.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com/1")) + await scheduler.enqueue(Request("https://example.com/2")) + await scheduler.enqueue(Request("https://example.com/3")) + + # Dequeue one + await scheduler.dequeue() + + requests, seen = scheduler.snapshot() + + # Snapshot should only have 2 pending requests + assert len(requests) == 2 + # But seen should still have all 3 (deduplication tracking) + assert len(seen) == 3 + + +class TestSchedulerRestore: + """Test Scheduler restore functionality from checkpoint.""" + + @pytest.mark.asyncio + async def test_restore_requests(self): + """Test restoring requests from checkpoint data.""" + scheduler = Scheduler() + + checkpoint_requests = [ + Request("https://example.com/1", priority=10), + Request("https://example.com/2", priority=5), + ] + checkpoint_seen = {"fp1", "fp2", "fp3"} + + data = CheckpointData(requests=checkpoint_requests, seen=checkpoint_seen) + + scheduler.restore(data) + + assert len(scheduler) == 2 + + @pytest.mark.asyncio + async def test_restore_seen_set(self): + """Test that restore sets up seen fingerprints.""" + scheduler = Scheduler() + + data = CheckpointData( + requests=[], + seen={"fp1", "fp2"}, + ) + + scheduler.restore(data) + + # Now try to enqueue a request with matching fingerprint + request = Request("https://example.com") + request.sid = "" # Empty sid + # Manually set fingerprint that matches seen + # Since fingerprint is sid:url, we need to create matching ones + + # Verify seen set was restored + _, seen = scheduler.snapshot() + assert seen == {"fp1", "fp2"} + + @pytest.mark.asyncio + async def test_restore_maintains_priority_order(self): + """Test that restored requests maintain priority order.""" + scheduler = Scheduler() + + # Requests should already be sorted by priority in checkpoint + checkpoint_requests = [ + Request("https://example.com/high", priority=10), + Request("https://example.com/low", priority=1), + ] + + data = CheckpointData(requests=checkpoint_requests, seen=set()) + scheduler.restore(data) + + # Dequeue should return high priority first + first = await scheduler.dequeue() + assert first.url == "https://example.com/high" + + second = await scheduler.dequeue() + assert second.url == "https://example.com/low" + + @pytest.mark.asyncio + async def test_restore_empty_checkpoint(self): + """Test restoring from empty checkpoint.""" + scheduler = Scheduler() + + data = CheckpointData(requests=[], seen=set()) + scheduler.restore(data) + + assert len(scheduler) == 0 + assert scheduler.is_empty is True + + +class TestSchedulerIntegration: + """Integration tests for Scheduler with checkpoint roundtrip.""" + + @pytest.mark.asyncio + async def test_snapshot_and_restore_roundtrip(self): + """Test that snapshot -> restore works correctly.""" + # Create and populate original scheduler + original = Scheduler() + + await original.enqueue(Request("https://example.com/1", sid="s1", priority=10)) + await original.enqueue(Request("https://example.com/2", sid="s1", priority=5)) + await original.enqueue(Request("https://example.com/3", sid="s2", priority=7)) + + # Snapshot + requests, seen = original.snapshot() + data = CheckpointData(requests=requests, seen=seen) + + # Restore to new scheduler + restored = Scheduler() + restored.restore(data) + + # Verify state matches + assert len(restored) == len(original) + + # Dequeue from both and compare + for _ in range(3): + orig_req = await original.dequeue() + rest_req = await restored.dequeue() + assert orig_req.url == rest_req.url + assert orig_req.priority == rest_req.priority + + @pytest.mark.asyncio + async def test_partial_processing_then_checkpoint(self): + """Test checkpointing after partial processing.""" + scheduler = Scheduler() + + # Enqueue 5 requests + for i in range(5): + await scheduler.enqueue(Request(f"https://example.com/{i}")) + + # Process 2 + await scheduler.dequeue() + await scheduler.dequeue() + + # Snapshot should show 3 pending, 5 seen + requests, seen = scheduler.snapshot() + + assert len(requests) == 3 + assert len(seen) == 5 + + @pytest.mark.asyncio + async def test_deduplication_after_restore(self): + """Test that deduplication works after restore.""" + scheduler = Scheduler() + + await scheduler.enqueue(Request("https://example.com", sid="s1")) + + requests, seen = scheduler.snapshot() + data = CheckpointData(requests=requests, seen=seen) + + # Restore to new scheduler + new_scheduler = Scheduler() + new_scheduler.restore(data) + + # Try to add duplicate - should be filtered + result = await new_scheduler.enqueue(Request("https://example.com", sid="s1")) + + assert result is False # Duplicate filtered based on restored seen set diff --git a/tests/spiders/test_session.py b/tests/spiders/test_session.py new file mode 100644 index 0000000..c1eed5d --- /dev/null +++ b/tests/spiders/test_session.py @@ -0,0 +1,352 @@ +"""Tests for the SessionManager class.""" + +from scrapling.core._types import Any +import pytest + +from scrapling.spiders.session import SessionManager + + +class MockSession: # type: ignore[type-arg] + """Mock session for testing without actual network calls.""" + + def __init__(self, name: str = "mock"): + self.name = name + self._is_alive = False + self._started = False + self._closed = False + + async def __aenter__(self): + self._is_alive = True + self._started = True + return self + + async def __aexit__(self, *args): + self._is_alive = False + self._closed = True + + async def fetch(self, url: str, **kwargs): + pass + + +class TestSessionManagerInit: + """Test SessionManager initialization.""" + + def test_manager_starts_empty(self): + """Test that manager starts with no sessions.""" + manager = SessionManager() + + assert len(manager) == 0 + + def test_manager_no_default_session_when_empty(self): + """Test that accessing default_session_id raises when empty.""" + manager = SessionManager() + + with pytest.raises(RuntimeError, match="No sessions registered"): + _ = manager.default_session_id + + +class TestSessionManagerAdd: + """Test SessionManager add functionality.""" + + def test_add_single_session(self): + """Test adding a single session.""" + manager = SessionManager() + session = MockSession() + + manager.add("test", session) + + assert len(manager) == 1 + assert "test" in manager + assert manager.session_ids == ["test"] + + def test_first_session_becomes_default(self): + """Test that first added session becomes default.""" + manager = SessionManager() + session = MockSession() + + manager.add("first", session) + + assert manager.default_session_id == "first" + + def test_add_multiple_sessions(self): + """Test adding multiple sessions.""" + manager = SessionManager() + + manager.add("session1", MockSession("s1")) + manager.add("session2", MockSession("s2")) + manager.add("session3", MockSession("s3")) + + assert len(manager) == 3 + assert "session1" in manager + assert "session2" in manager + assert "session3" in manager + + def test_explicit_default_session(self): + """Test setting explicit default session.""" + manager = SessionManager() + + manager.add("first", MockSession()) + manager.add("second", MockSession(), default=True) + + assert manager.default_session_id == "second" + + def test_add_duplicate_id_raises(self): + """Test that adding duplicate session ID raises.""" + manager = SessionManager() + manager.add("test", MockSession()) + + with pytest.raises(ValueError, match="already registered"): + manager.add("test", MockSession()) + + def test_add_returns_self_for_chaining(self): + """Test that add returns self for method chaining.""" + manager = SessionManager() + + result = manager.add("test", MockSession()) + + assert result is manager + + def test_method_chaining(self): + """Test fluent interface for adding sessions.""" + manager = SessionManager() + + manager.add("s1", MockSession()).add("s2", MockSession()).add("s3", MockSession()) + + assert len(manager) == 3 + + def test_add_lazy_session(self): + """Test adding lazy session.""" + manager = SessionManager() + + manager.add("lazy", MockSession(), lazy=True) + + assert "lazy" in manager + assert "lazy" in manager._lazy_sessions + + +class TestSessionManagerRemove: + """Test SessionManager remove/pop functionality.""" + + def test_remove_session(self): + """Test removing a session.""" + manager = SessionManager() + manager.add("test", MockSession()) + + manager.remove("test") + + assert "test" not in manager + assert len(manager) == 0 + + def test_remove_nonexistent_raises(self): + """Test removing nonexistent session raises.""" + manager = SessionManager() + + with pytest.raises(KeyError, match="not found"): + manager.remove("nonexistent") + + def test_pop_returns_session(self): + """Test pop returns the removed session.""" + manager = SessionManager() + session = MockSession("original") + manager.add("test", session) + + popped = manager.pop("test") + + assert popped is session + assert "test" not in manager + + def test_remove_default_updates_default(self): + """Test that removing default session updates default.""" + manager = SessionManager() + manager.add("first", MockSession()) + manager.add("second", MockSession()) + + assert manager.default_session_id == "first" + + manager.remove("first") + + assert manager.default_session_id == "second" + + def test_remove_lazy_session_cleans_up(self): + """Test that removing lazy session cleans up lazy set.""" + manager = SessionManager() + manager.add("lazy", MockSession(), lazy=True) + + manager.remove("lazy") + + assert "lazy" not in manager._lazy_sessions + + +class TestSessionManagerGet: + """Test SessionManager get functionality.""" + + def test_get_existing_session(self): + """Test getting an existing session.""" + manager = SessionManager() + session = MockSession("test") + manager.add("test", session) + + retrieved = manager.get("test") + + assert retrieved is session + + def test_get_nonexistent_raises_with_available(self): + """Test getting nonexistent session shows available sessions.""" + manager = SessionManager() + manager.add("session1", MockSession()) + manager.add("session2", MockSession()) + + with pytest.raises(KeyError, match="Available:"): + manager.get("nonexistent") + + +class TestSessionManagerContains: + """Test SessionManager contains functionality.""" + + def test_contains_existing(self): + """Test contains for existing session.""" + manager = SessionManager() + manager.add("test", MockSession()) + + assert "test" in manager + + def test_not_contains_missing(self): + """Test contains for missing session.""" + manager = SessionManager() + manager.add("test", MockSession()) + + assert "other" not in manager + + +class TestSessionManagerAsyncContext: + """Test SessionManager async context manager.""" + + @pytest.mark.asyncio + async def test_start_activates_sessions(self): + """Test that start activates non-lazy sessions.""" + manager = SessionManager() + session = MockSession() + manager.add("test", session) + + await manager.start() + + assert session._is_alive is True + assert manager._started is True + + @pytest.mark.asyncio + async def test_start_skips_lazy_sessions(self): + """Test that start skips lazy sessions.""" + manager = SessionManager() + eager_session = MockSession("eager") + lazy_session = MockSession("lazy") + + manager.add("eager", eager_session) + manager.add("lazy", lazy_session, lazy=True) + + await manager.start() + + assert eager_session._is_alive is True + assert lazy_session._is_alive is False + + @pytest.mark.asyncio + async def test_close_deactivates_sessions(self): + """Test that close deactivates all sessions.""" + manager = SessionManager() + session = MockSession() + manager.add("test", session) + + await manager.start() + assert session._is_alive is True + + await manager.close() + assert session._is_alive is False + assert manager._started is False + + @pytest.mark.asyncio + async def test_async_context_manager(self): + """Test using SessionManager as async context manager.""" + manager = SessionManager() + session = MockSession() + manager.add("test", session) + + async with manager: + assert session._is_alive is True + + assert session._is_alive is False + + @pytest.mark.asyncio + async def test_start_idempotent(self): + """Test that calling start multiple times is safe.""" + manager = SessionManager() + session = MockSession() + manager.add("test", session) + + await manager.start() + await manager.start() # Should not raise or double-start + + assert session._started is True + + +class TestSessionManagerProperties: + """Test SessionManager properties.""" + + def test_session_ids_returns_list(self): + """Test session_ids returns list of IDs.""" + manager = SessionManager() + manager.add("a", MockSession()) + manager.add("b", MockSession()) + manager.add("c", MockSession()) + + ids = manager.session_ids + + assert isinstance(ids, list) + assert set(ids) == {"a", "b", "c"} + + def test_len_returns_session_count(self): + """Test len returns number of sessions.""" + manager = SessionManager() + + assert len(manager) == 0 + + manager.add("s1", MockSession()) + assert len(manager) == 1 + + manager.add("s2", MockSession()) + assert len(manager) == 2 + + +class TestSessionManagerIntegration: + """Integration tests for SessionManager.""" + + def test_realistic_setup(self): + """Test realistic session manager setup.""" + manager = SessionManager() + + # Add different types of sessions + manager.add("default", MockSession("default")) + manager.add("backup", MockSession("backup")) + manager.add("lazy_special", MockSession("special"), lazy=True) + + assert len(manager) == 3 + assert manager.default_session_id == "default" + assert "lazy_special" in manager._lazy_sessions + + @pytest.mark.asyncio + async def test_lifecycle_management(self): + """Test complete lifecycle of session manager.""" + manager = SessionManager() + sessions = [MockSession(f"s{i}") for i in range(3)] + + for i, session in enumerate(sessions): + manager.add(f"session{i}", session) + + # Before start - no sessions active + assert all(not s._is_alive for s in sessions) + + # After start - all active + await manager.start() + assert all(s._is_alive for s in sessions) + + # After close - all inactive + await manager.close() + assert all(not s._is_alive for s in sessions) diff --git a/tests/spiders/test_spider.py b/tests/spiders/test_spider.py new file mode 100644 index 0000000..9cda3d7 --- /dev/null +++ b/tests/spiders/test_spider.py @@ -0,0 +1,574 @@ +"""Tests for the Spider class and related components.""" + +import logging +import tempfile +from pathlib import Path + +import pytest + +from scrapling.spiders.spider import Spider, SessionConfigurationError, LogCounterHandler, BLOCKED_CODES +from scrapling.spiders.request import Request +from scrapling.spiders.session import SessionManager +from scrapling.spiders.result import CrawlStats +from scrapling.core._types import Any, Dict, AsyncGenerator + + +class TestLogCounterHandler: + """Test LogCounterHandler for tracking log counts.""" + + def test_initial_counts_are_zero(self): + """Test that handler starts with zero counts.""" + handler = LogCounterHandler() + counts = handler.get_counts() + + assert counts["debug"] == 0 + assert counts["info"] == 0 + assert counts["warning"] == 0 + assert counts["error"] == 0 + assert counts["critical"] == 0 + + def test_counts_debug_messages(self): + """Test counting debug level messages.""" + handler = LogCounterHandler() + record = logging.LogRecord( + name="test", + level=logging.DEBUG, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + + handler.emit(record) + handler.emit(record) + + assert handler.get_counts()["debug"] == 2 + + def test_counts_info_messages(self): + """Test counting info level messages.""" + handler = LogCounterHandler() + record = logging.LogRecord( + name="test", + level=logging.INFO, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + + handler.emit(record) + + assert handler.get_counts()["info"] == 1 + + def test_counts_warning_messages(self): + """Test counting warning level messages.""" + handler = LogCounterHandler() + record = logging.LogRecord( + name="test", + level=logging.WARNING, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + + handler.emit(record) + + assert handler.get_counts()["warning"] == 1 + + def test_counts_error_messages(self): + """Test counting error level messages.""" + handler = LogCounterHandler() + record = logging.LogRecord( + name="test", + level=logging.ERROR, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + + handler.emit(record) + + assert handler.get_counts()["error"] == 1 + + def test_counts_critical_messages(self): + """Test counting critical level messages.""" + handler = LogCounterHandler() + record = logging.LogRecord( + name="test", + level=logging.CRITICAL, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + + handler.emit(record) + + assert handler.get_counts()["critical"] == 1 + + def test_counts_multiple_levels(self): + """Test counting messages at different levels.""" + handler = LogCounterHandler() + + levels = [ + logging.DEBUG, + logging.DEBUG, + logging.INFO, + logging.WARNING, + logging.ERROR, + logging.ERROR, + logging.ERROR, + logging.CRITICAL, + ] + + for level in levels: + record = logging.LogRecord( + name="test", + level=level, + pathname="", + lineno=0, + msg="test", + args=(), + exc_info=None, + ) + handler.emit(record) + + counts = handler.get_counts() + assert counts["debug"] == 2 + assert counts["info"] == 1 + assert counts["warning"] == 1 + assert counts["error"] == 3 + assert counts["critical"] == 1 + + +class TestBlockedCodes: + """Test BLOCKED_CODES constant.""" + + def test_blocked_codes_contains_expected_values(self): + """Test that BLOCKED_CODES contains expected HTTP status codes.""" + assert 401 in BLOCKED_CODES # Unauthorized + assert 403 in BLOCKED_CODES # Forbidden + assert 407 in BLOCKED_CODES # Proxy Authentication Required + assert 429 in BLOCKED_CODES # Too Many Requests + assert 444 in BLOCKED_CODES # Connection Closed Without Response (nginx) + assert 500 in BLOCKED_CODES # Internal Server Error + assert 502 in BLOCKED_CODES # Bad Gateway + assert 503 in BLOCKED_CODES # Service Unavailable + assert 504 in BLOCKED_CODES # Gateway Timeout + + def test_blocked_codes_does_not_contain_success(self): + """Test that success codes are not blocked.""" + assert 200 not in BLOCKED_CODES + assert 201 not in BLOCKED_CODES + assert 204 not in BLOCKED_CODES + assert 301 not in BLOCKED_CODES + assert 302 not in BLOCKED_CODES + + +class ConcreteSpider(Spider): + """Concrete spider implementation for testing.""" + + name = "test_spider" + start_urls = ["https://example.com"] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield {"url": str(response)} + + +class TestSpiderInit: + """Test Spider initialization.""" + + def test_spider_requires_name(self): + """Test that spider without name raises ValueError.""" + + class NoNameSpider(Spider): + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + with pytest.raises(ValueError, match="must have a name"): + NoNameSpider() + + def test_spider_initializes_logger(self): + """Test that spider creates a logger.""" + spider = ConcreteSpider() + + assert spider.logger is not None + assert spider.logger.name == "scrapling.spiders.test_spider" + + def test_spider_logger_has_log_counter(self): + """Test that spider logger has log counter handler.""" + spider = ConcreteSpider() + + assert spider._log_counter is not None + assert isinstance(spider._log_counter, LogCounterHandler) + + def test_spider_with_crawldir(self): + """Test spider initialization with crawldir.""" + with tempfile.TemporaryDirectory() as tmpdir: + spider = ConcreteSpider(crawldir=tmpdir) + + assert spider.crawldir == Path(tmpdir) + + def test_spider_without_crawldir(self): + """Test spider initialization without crawldir.""" + spider = ConcreteSpider() + + assert spider.crawldir is None + + def test_spider_custom_interval(self): + """Test spider with custom checkpoint interval.""" + spider = ConcreteSpider(interval=60.0) + + assert spider._interval == 60.0 + + def test_spider_default_interval(self): + """Test spider has default checkpoint interval.""" + spider = ConcreteSpider() + + assert spider._interval == 300.0 + + def test_spider_repr(self): + """Test spider string representation.""" + spider = ConcreteSpider() + + repr_str = repr(spider) + + assert "ConcreteSpider" in repr_str + assert "test_spider" in repr_str + + +class TestSpiderClassAttributes: + """Test Spider class attribute defaults.""" + + def test_default_concurrent_requests(self): + """Test default concurrent_requests is 16.""" + assert ConcreteSpider.concurrent_requests == 16 + + def test_default_concurrent_requests_per_domain(self): + """Test default concurrent_requests_per_domain is 0 (disabled).""" + assert ConcreteSpider.concurrent_requests_per_domain == 0 + + def test_default_download_delay(self): + """Test default download_delay is 0.""" + assert ConcreteSpider.download_delay == 0.0 + + def test_default_max_blocked_retries(self): + """Test default max_blocked_retries is 3.""" + assert ConcreteSpider.max_blocked_retries == 3 + + def test_default_logging_level(self): + """Test default logging level is DEBUG.""" + assert ConcreteSpider.logging_level == logging.DEBUG + + def test_default_allowed_domains_empty(self): + """Test default allowed_domains is empty set.""" + assert ConcreteSpider.allowed_domains == set() + + +class TestSpiderSessionConfiguration: + """Test Spider session configuration.""" + + def test_default_configure_sessions(self): + """Test that default configure_sessions adds a session.""" + spider = ConcreteSpider() + + assert len(spider._session_manager) > 0 + + def test_configure_sessions_error_raises_custom_exception(self): + """Test that errors in configure_sessions raise SessionConfigurationError.""" + + class BadSessionSpider(Spider): + name = "bad_spider" + + def configure_sessions(self, manager: SessionManager) -> None: + raise RuntimeError("Configuration failed!") + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + with pytest.raises(SessionConfigurationError, match="Configuration failed"): + BadSessionSpider() + + def test_configure_sessions_no_sessions_raises(self): + """Test that not adding any sessions raises SessionConfigurationError.""" + + class NoSessionSpider(Spider): + name = "no_session_spider" + + def configure_sessions(self, manager: SessionManager) -> None: + pass # Don't add any sessions + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + with pytest.raises(SessionConfigurationError, match="did not add any sessions"): + NoSessionSpider() + + +class TestSpiderStartRequests: + """Test Spider start_requests method.""" + + @pytest.mark.asyncio + async def test_start_requests_yields_from_start_urls(self): + """Test that start_requests yields requests for start_urls.""" + + class MultiUrlSpider(Spider): + name = "multi_url" + start_urls = [ + "https://example.com/1", + "https://example.com/2", + "https://example.com/3", + ] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = MultiUrlSpider() + requests = [r async for r in spider.start_requests()] + + assert len(requests) == 3 + assert requests[0].url == "https://example.com/1" + assert requests[1].url == "https://example.com/2" + assert requests[2].url == "https://example.com/3" + + @pytest.mark.asyncio + async def test_start_requests_no_urls_raises(self): + """Test that start_requests raises when no start_urls.""" + + class NoUrlSpider(Spider): + name = "no_url" + start_urls = [] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = NoUrlSpider() + + with pytest.raises(RuntimeError, match="no starting point"): + async for _ in spider.start_requests(): + pass + + @pytest.mark.asyncio + async def test_start_requests_uses_default_session(self): + """Test that start_requests uses default session ID.""" + spider = ConcreteSpider() + requests = [r async for r in spider.start_requests()] + + # Should use the default session from session manager + default_sid = spider._session_manager.default_session_id + assert requests[0].sid == default_sid + + +class TestSpiderHooks: + """Test Spider lifecycle hooks.""" + + @pytest.mark.asyncio + async def test_on_start_default(self): + """Test default on_start doesn't raise.""" + spider = ConcreteSpider() + + # Should not raise + await spider.on_start(resuming=False) + await spider.on_start(resuming=True) + + @pytest.mark.asyncio + async def test_on_close_default(self): + """Test default on_close doesn't raise.""" + spider = ConcreteSpider() + + # Should not raise + await spider.on_close() + + @pytest.mark.asyncio + async def test_on_error_default(self): + """Test default on_error logs the error.""" + spider = ConcreteSpider() + request = Request("https://example.com") + error = ValueError("test error") + + # Should not raise + await spider.on_error(request, error) + + @pytest.mark.asyncio + async def test_on_scraped_item_default_returns_item(self): + """Test default on_scraped_item returns the item unchanged.""" + spider = ConcreteSpider() + item = {"key": "value", "nested": {"a": 1}} + + result = await spider.on_scraped_item(item) + + assert result == item + + @pytest.mark.asyncio + async def test_is_blocked_default_checks_status_codes(self): + """Test default is_blocked checks blocked status codes.""" + + class MockResponse: + def __init__(self, status: int): + self.status = status + + spider = ConcreteSpider() + + # Test blocked codes + assert await spider.is_blocked(MockResponse(403)) is True + assert await spider.is_blocked(MockResponse(429)) is True + assert await spider.is_blocked(MockResponse(503)) is True + + # Test non-blocked codes + assert await spider.is_blocked(MockResponse(200)) is False + assert await spider.is_blocked(MockResponse(404)) is False + + @pytest.mark.asyncio + async def test_retry_blocked_request_default_returns_request(self): + """Test default retry_blocked_request returns the request unchanged.""" + + class MockResponse: + status = 429 + + spider = ConcreteSpider() + request = Request("https://example.com", priority=5) + + result = await spider.retry_blocked_request(request, MockResponse()) + + assert result is request + + +class TestSpiderPause: + """Test Spider pause functionality.""" + + def test_pause_without_engine_raises(self): + """Test that pause without active engine raises RuntimeError.""" + spider = ConcreteSpider() + + with pytest.raises(RuntimeError, match="no crawl engine started"): + spider.pause() + + +class TestSpiderStats: + """Test Spider stats property.""" + + def test_stats_without_engine_raises(self): + """Test that accessing stats without active crawl raises.""" + spider = ConcreteSpider() + + with pytest.raises(RuntimeError, match="No active crawl"): + _ = spider.stats + + +class TestSpiderCustomization: + """Test Spider customization patterns.""" + + def test_custom_concurrent_requests(self): + """Test spider with custom concurrent_requests.""" + + class CustomSpider(Spider): + name = "custom" + concurrent_requests = 32 + start_urls = ["https://example.com"] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = CustomSpider() + assert spider.concurrent_requests == 32 + + def test_custom_allowed_domains(self): + """Test spider with allowed_domains.""" + + class DomainSpider(Spider): + name = "domain_spider" + start_urls = ["https://example.com"] + allowed_domains = {"example.com", "api.example.com"} + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = DomainSpider() + assert "example.com" in spider.allowed_domains + assert "api.example.com" in spider.allowed_domains + + def test_custom_download_delay(self): + """Test spider with download delay.""" + + class SlowSpider(Spider): + name = "slow" + download_delay = 1.5 + start_urls = ["https://example.com"] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = SlowSpider() + assert spider.download_delay == 1.5 + + +class TestSpiderLogging: + """Test Spider logging configuration.""" + + def test_custom_logging_level(self): + """Test spider with custom logging level.""" + + class QuietSpider(Spider): + name = "quiet" + logging_level = logging.WARNING + start_urls = ["https://example.com"] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = QuietSpider() + assert spider.logger.level == logging.WARNING + + def test_log_file_creates_handler(self): + """Test spider with log file creates file handler.""" + with tempfile.TemporaryDirectory() as tmpdir: + log_path = Path(tmpdir) / "spider.log" + + class FileLogSpider(Spider): + name = "file_log" + log_file = str(log_path) + start_urls = ["https://example.com"] + + async def parse(self, response) -> AsyncGenerator[Dict[str, Any] | Request | None, None]: + yield None + + spider = FileLogSpider() + + # Should have a file handler + file_handlers = [ + h for h in spider.logger.handlers if isinstance(h, logging.FileHandler) + ] + assert len(file_handlers) == 1 + + # Clean up + for h in file_handlers: + h.close() + + def test_logger_does_not_propagate(self): + """Test that spider logger does not propagate to parent.""" + spider = ConcreteSpider() + + assert spider.logger.propagate is False + + +class TestSessionConfigurationError: + """Test SessionConfigurationError exception.""" + + def test_exception_message(self): + """Test that exception preserves message.""" + error = SessionConfigurationError("Custom error message") + + assert str(error) == "Custom error message" + + def test_exception_is_exception(self): + """Test that it's a proper exception.""" + error = SessionConfigurationError("test") + + assert isinstance(error, Exception) From 4ecf8a64d3b072f2fad6f84fd5ad36338e859354 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 15:04:40 +0200 Subject: [PATCH 36/80] fix(spiders): Fix for when the pausing system has large queue --- scrapling/spiders/engine.py | 39 +++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 9b226df..5819241 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -50,6 +50,7 @@ class CrawlerEngine: self._checkpoint_manager = CheckpointManager(crawldir or "", interval) self._last_checkpoint_time: float = 0.0 self._pause_requested: bool = False + self._force_stop: bool = False self.paused: bool = False def _is_domain_allowed(self, request: Request) -> bool: @@ -144,10 +145,23 @@ class CrawlerEngine: self._active_tasks -= 1 def request_pause(self) -> None: - """Request a graceful pause of the crawl.""" - if not self._pause_requested: + """Request a graceful pause of the crawl. + + First call: requests graceful pause (waits for active tasks). + Second call: forces immediate stop. + """ + if self._force_stop: + return # Already forcing stop + + if self._pause_requested: + # Second Ctrl+C - force stop + self._force_stop = True + log.warning("Force stop requested, cancelling immediately...") + else: self._pause_requested = True - log.info("Pause requested, waiting for in-flight requests to complete...") + log.info( + "Pause requested, waiting for in-flight requests to complete (press Ctrl+C again to force stop)..." + ) async def _save_checkpoint(self) -> None: """Save current state to checkpoint files.""" @@ -215,15 +229,22 @@ class CrawlerEngine: # Process queue async with create_task_group() as tg: while self._running: - # Check for pause request + # Check for pause/stop request if self._checkpoint_system_enabled: if self._pause_requested: # Wait for active tasks to complete - if self._active_tasks == 0: + if self._active_tasks == 0 or self._force_stop: + if self._force_stop: + log.warning(f"Force stopping with {self._active_tasks} active tasks") + await self._save_checkpoint() self.paused = True self._running = False - log.info("Spider paused, checkpoint saved") + + if not self._force_stop: + log.info("Spider paused, checkpoint saved") + else: + tg.cancel_scope.cancel() break # Wait briefly and check again await anyio.sleep(0.05) @@ -243,6 +264,12 @@ class CrawlerEngine: await anyio.sleep(0.05) continue + # Only spawn tasks up to concurrent_requests limit + # This prevents spawning thousands of waiting tasks + if self._active_tasks >= self.spider.concurrent_requests: + await anyio.sleep(0.01) + continue + request = await self.scheduler.dequeue() self._active_tasks += 1 tg.start_soon(self._task_wrapper, request) From fbc8be5bcc01ce960735b1b77c88e514c9cbcc0a Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 16:00:06 +0200 Subject: [PATCH 37/80] fix(spiders): fix a bug with session stats counter --- scrapling/spiders/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 5819241..1abeb76 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -84,7 +84,7 @@ class CrawlerEngine: self.stats.proxies.append(dict(request._session_kwargs["proxies"])) try: response = await self.session_manager.fetch(request) - self.stats.increment_requests_count(request.sid) + self.stats.increment_requests_count(request.sid or self.session_manager.default_session_id) self.stats.increment_response_bytes(request.domain, len(response.body)) self.stats.increment_status(response.status) From 25850db92c1963b66a0a24e0b9683711ca278749 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 16:13:03 +0200 Subject: [PATCH 38/80] fix(spiders): handle errors with manual pause during stream mode --- scrapling/spiders/engine.py | 1 + scrapling/spiders/spider.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 1abeb76..463a290 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -207,6 +207,7 @@ class CrawlerEngine: self._items.clear() self.paused = False self._pause_requested = False + self._force_stop = False self.stats = CrawlStats(start_time=anyio.current_time()) # Check for existing checkpoint diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index bde8f78..649f4d3 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -211,7 +211,9 @@ class Spider(ABC): manager.add("default", FetcherSession()) def pause(self): - """Pause the crawling process if checkpoint system is enabled.""" + """Pause the crawling process. Requires crawldir to be set for checkpoint system.""" + if not self.crawldir: + raise RuntimeError("Cannot pause without crawldir - checkpoint system not enabled") if self._engine: self._engine.request_pause() else: From 94bc759c6ad0a13e56455ead46ba7e8c9a9971d0 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 16:13:29 +0200 Subject: [PATCH 39/80] test: updates tests to include new logic --- tests/spiders/test_spider.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/spiders/test_spider.py b/tests/spiders/test_spider.py index 9cda3d7..c1edaed 100644 --- a/tests/spiders/test_spider.py +++ b/tests/spiders/test_spider.py @@ -443,13 +443,21 @@ class TestSpiderHooks: class TestSpiderPause: """Test Spider pause functionality.""" - def test_pause_without_engine_raises(self): - """Test that pause without active engine raises RuntimeError.""" + def test_pause_without_crawldir_raises(self): + """Test that pause without crawldir raises RuntimeError.""" spider = ConcreteSpider() - with pytest.raises(RuntimeError, match="no crawl engine started"): + with pytest.raises(RuntimeError, match="Cannot pause without crawldir"): spider.pause() + def test_pause_without_engine_raises(self): + """Test that pause without active engine raises RuntimeError.""" + with tempfile.TemporaryDirectory() as tmpdir: + spider = ConcreteSpider(crawldir=tmpdir) + + with pytest.raises(RuntimeError, match="no crawl engine started"): + spider.pause() + class TestSpiderStats: """Test Spider stats property.""" From 6947066761fbad8fdd8126c1c07ab11443c64155 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 16:40:02 +0200 Subject: [PATCH 40/80] feat(spiders): Make graceful shutdown always enabled --- scrapling/spiders/engine.py | 36 ++++++++++++++++++------------------ scrapling/spiders/spider.py | 22 ++++++++++------------ 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 463a290..2a812be 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -230,29 +230,29 @@ class CrawlerEngine: # Process queue async with create_task_group() as tg: while self._running: - # Check for pause/stop request - if self._checkpoint_system_enabled: - if self._pause_requested: - # Wait for active tasks to complete - if self._active_tasks == 0 or self._force_stop: - if self._force_stop: - log.warning(f"Force stopping with {self._active_tasks} active tasks") + if self._pause_requested: + if self._active_tasks == 0 or self._force_stop: + if self._force_stop: + log.warning(f"Force stopping with {self._active_tasks} active tasks") + tg.cancel_scope.cancel() + # Only save checkpoint if checkpoint system is enabled + if self._checkpoint_system_enabled: await self._save_checkpoint() self.paused = True - self._running = False + log.info("Spider paused, checkpoint saved") + else: + log.info("Spider stopped gracefully") - if not self._force_stop: - log.info("Spider paused, checkpoint saved") - else: - tg.cancel_scope.cancel() - break - # Wait briefly and check again - await anyio.sleep(0.05) - continue + self._running = False + break - if self._is_checkpoint_time(): - await self._save_checkpoint() + # Wait briefly and check again + await anyio.sleep(0.05) + continue + + if self._checkpoint_system_enabled and self._is_checkpoint_time(): + await self._save_checkpoint() if self.scheduler.is_empty: # Empty queue + no active tasks = done diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 649f4d3..465bd4f 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -211,13 +211,11 @@ class Spider(ABC): manager.add("default", FetcherSession()) def pause(self): - """Pause the crawling process. Requires crawldir to be set for checkpoint system.""" - if not self.crawldir: - raise RuntimeError("Cannot pause without crawldir - checkpoint system not enabled") + """Request graceful shutdown of the crawling process.""" if self._engine: self._engine.request_pause() else: - raise RuntimeError("Spider doesn't have active crawl to pause, no crawl engine started!") + raise RuntimeError("No active crawl to stop") def _setup_signal_handler(self) -> None: """Set up SIGINT handler for graceful pause.""" @@ -264,8 +262,11 @@ class Spider(ABC): This is the main entry point for running a spider. Handles async execution internally via anyio. - If crawldir is set, pressing Ctrl+C will pause the spider and save a checkpoint. - Running the spider again with the same crawldir will resume from the checkpoint. + Pressing Ctrl+C will initiate graceful shutdown (waits for active tasks to complete). + Pressing Ctrl+C a second time will force immediate stop. + + If crawldir is set, a checkpoint will also be saved on graceful shutdown, + allowing you to resume the crawl later by running the spider again. :param use_uvloop: Whether to use the faster uvloop/winloop event loop implementation, if available. :param backend_options: Asyncio backend options to be used with `anyio.run` @@ -274,15 +275,12 @@ class Spider(ABC): if use_uvloop: backend_options.update({"use_uvloop": True}) - # Set up SIGINT handler for graceful pause (only if crawldir is set) - if self.crawldir: - self._setup_signal_handler() - + # Set up SIGINT handler for graceful shutdown + self._setup_signal_handler() try: return anyio.run(self.__run, backend="asyncio", backend_options=backend_options) finally: - if self.crawldir: - self._restore_signal_handler() + self._restore_signal_handler() async def stream(self) -> AsyncGenerator[Dict[str, Any], None]: """Stream items as they're scraped. Ideal for long-running spiders or building applications on top of the spiders. From 0ec78e233578ab2a0caaec4ea6df9b624d51cc4f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 19 Jan 2026 16:40:18 +0200 Subject: [PATCH 41/80] test: update tests accordingly --- tests/spiders/test_spider.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/tests/spiders/test_spider.py b/tests/spiders/test_spider.py index c1edaed..b01ee47 100644 --- a/tests/spiders/test_spider.py +++ b/tests/spiders/test_spider.py @@ -443,20 +443,12 @@ class TestSpiderHooks: class TestSpiderPause: """Test Spider pause functionality.""" - def test_pause_without_crawldir_raises(self): - """Test that pause without crawldir raises RuntimeError.""" - spider = ConcreteSpider() - - with pytest.raises(RuntimeError, match="Cannot pause without crawldir"): - spider.pause() - def test_pause_without_engine_raises(self): """Test that pause without active engine raises RuntimeError.""" - with tempfile.TemporaryDirectory() as tmpdir: - spider = ConcreteSpider(crawldir=tmpdir) + spider = ConcreteSpider() - with pytest.raises(RuntimeError, match="no crawl engine started"): - spider.pause() + with pytest.raises(RuntimeError, match="No active crawl to stop"): + spider.pause() class TestSpiderStats: From 95955af3be725cfa8dbd54b461b3aa8e11e01d11 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 16:36:34 +0200 Subject: [PATCH 42/80] build: Add w3lib to deps --- pyproject.toml | 1 + scrapling/core/_html_utils.py | 342 --------------------------------- scrapling/core/custom_types.py | 2 +- 3 files changed, 2 insertions(+), 343 deletions(-) delete mode 100644 scrapling/core/_html_utils.py diff --git a/pyproject.toml b/pyproject.toml index 2264425..7a1b8b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ dependencies = [ "cssselect>=1.3.0", "orjson>=3.11.5", "tldextract>=5.3.1", + "w3lib>=2.3.0" ] [project.optional-dependencies] diff --git a/scrapling/core/_html_utils.py b/scrapling/core/_html_utils.py deleted file mode 100644 index 6b09830..0000000 --- a/scrapling/core/_html_utils.py +++ /dev/null @@ -1,342 +0,0 @@ -""" -This file is mostly copied from the submodule `w3lib.html` source code to stop downloading the whole library to use a small part of it. -So the goal of doing this is to minimize the memory footprint and keep the library size relatively smaller. -Repo source code: https://github.com/scrapy/w3lib/blob/master/w3lib/html.py -""" - -from re import compile as _re_compile, IGNORECASE - -from scrapling.core._types import Iterable, Optional, Match, StrOrBytes - -_ent_re = _re_compile( - r"&((?P[a-z\d]+)|#(?P\d+)|#x(?P[a-f\d]+))(?P;?)", - IGNORECASE, -) -# maps HTML4 entity name to the Unicode code point -name2codepoint = { - "AElig": 0x00C6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 - "Aacute": 0x00C1, # latin capital letter A with acute, U+00C1 ISOlat1 - "Acirc": 0x00C2, # latin capital letter A with circumflex, U+00C2 ISOlat1 - "Agrave": 0x00C0, # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 - "Alpha": 0x0391, # greek capital letter alpha, U+0391 - "Aring": 0x00C5, # latin capital letter A with the ring above = latin capital letter A ring, U+00C5 ISOlat1 - "Atilde": 0x00C3, # latin capital letter A with tilde, U+00C3 ISOlat1 - "Auml": 0x00C4, # latin capital letter A with diaeresis, U+00C4 ISOlat1 - "Beta": 0x0392, # greek capital letter beta, U+0392 - "Ccedil": 0x00C7, # latin capital letter C with cedilla, U+00C7 ISOlat1 - "Chi": 0x03A7, # greek capital letter chi, U+03A7 - "Dagger": 0x2021, # double dagger, U+2021 ISOpub - "Delta": 0x0394, # greek capital letter delta, U+0394 ISOgrk3 - "ETH": 0x00D0, # latin capital letter ETH, U+00D0 ISOlat1 - "Eacute": 0x00C9, # latin capital letter E with acute, U+00C9 ISOlat1 - "Ecirc": 0x00CA, # latin capital letter E with circumflex, U+00CA ISOlat1 - "Egrave": 0x00C8, # latin capital letter E with grave, U+00C8 ISOlat1 - "Epsilon": 0x0395, # greek capital letter epsilon, U+0395 - "Eta": 0x0397, # greek capital letter eta, U+0397 - "Euml": 0x00CB, # latin capital letter E with diaeresis, U+00CB ISOlat1 - "Gamma": 0x0393, # greek capital letter gamma, U+0393 ISOgrk3 - "Iacute": 0x00CD, # latin capital letter I with acute, U+00CD ISOlat1 - "Icirc": 0x00CE, # latin capital letter I with circumflex, U+00CE ISOlat1 - "Igrave": 0x00CC, # latin capital letter I with grave, U+00CC ISOlat1 - "Iota": 0x0399, # greek capital letter iota, U+0399 - "Iuml": 0x00CF, # latin capital letter I with diaeresis, U+00CF ISOlat1 - "Kappa": 0x039A, # greek capital letter kappa, U+039A - "Lambda": 0x039B, # greek capital letter lambda, U+039B ISOgrk3 - "Mu": 0x039C, # greek capital letter mu, U+039C - "Ntilde": 0x00D1, # latin capital letter N with tilde, U+00D1 ISOlat1 - "Nu": 0x039D, # greek capital letter nu, U+039D - "OElig": 0x0152, # latin capital ligature OE, U+0152 ISOlat2 - "Oacute": 0x00D3, # latin capital letter O with acute, U+00D3 ISOlat1 - "Ocirc": 0x00D4, # latin capital letter O with circumflex, U+00D4 ISOlat1 - "Ograve": 0x00D2, # latin capital letter O with grave, U+00D2 ISOlat1 - "Omega": 0x03A9, # greek capital letter omega, U+03A9 ISOgrk3 - "Omicron": 0x039F, # greek capital letter omicron, U+039F - "Oslash": 0x00D8, # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 - "Otilde": 0x00D5, # latin capital letter O with tilde, U+00D5 ISOlat1 - "Ouml": 0x00D6, # latin capital letter O with diaeresis, U+00D6 ISOlat1 - "Phi": 0x03A6, # greek capital letter phi, U+03A6 ISOgrk3 - "Pi": 0x03A0, # greek capital letter pi, U+03A0 ISOgrk3 - "Prime": 0x2033, # double prime = seconds = inches, U+2033 ISOtech - "Psi": 0x03A8, # greek capital letter psi, U+03A8 ISOgrk3 - "Rho": 0x03A1, # greek capital letter rho, U+03A1 - "Scaron": 0x0160, # latin capital letter S with caron, U+0160 ISOlat2 - "Sigma": 0x03A3, # greek capital letter sigma, U+03A3 ISOgrk3 - "THORN": 0x00DE, # latin capital letter THORN, U+00DE ISOlat1 - "Tau": 0x03A4, # greek capital letter tau, U+03A4 - "Theta": 0x0398, # greek capital letter theta, U+0398 ISOgrk3 - "Uacute": 0x00DA, # latin capital letter U with acute, U+00DA ISOlat1 - "Ucirc": 0x00DB, # latin capital letter U with circumflex, U+00DB ISOlat1 - "Ugrave": 0x00D9, # latin capital letter U with grave, U+00D9 ISOlat1 - "Upsilon": 0x03A5, # greek capital letter upsilon, U+03A5 ISOgrk3 - "Uuml": 0x00DC, # latin capital letter U with diaeresis, U+00DC ISOlat1 - "Xi": 0x039E, # greek capital letter xi, U+039E ISOgrk3 - "Yacute": 0x00DD, # latin capital letter Y with acute, U+00DD ISOlat1 - "Yuml": 0x0178, # latin capital letter Y with diaeresis, U+0178 ISOlat2 - "Zeta": 0x0396, # greek capital letter zeta, U+0396 - "aacute": 0x00E1, # latin small letter a with acute, U+00E1 ISOlat1 - "acirc": 0x00E2, # latin small letter a with circumflex, U+00E2 ISOlat1 - "acute": 0x00B4, # acute accent = spacing acute, U+00B4 ISOdia - "aelig": 0x00E6, # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 - "agrave": 0x00E0, # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 - "alefsym": 0x2135, # alef symbol = first transfinite cardinal, U+2135 NEW - "alpha": 0x03B1, # greek small letter alpha, U+03B1 ISOgrk3 - "amp": 0x0026, # ampersand, U+0026 ISOnum - "and": 0x2227, # logical and = wedge, U+2227 ISOtech - "ang": 0x2220, # angle, U+2220 ISOamso - "aring": 0x00E5, # latin small letter a with the ring above = latin small letter a ring, U+00E5 ISOlat1 - "asymp": 0x2248, # almost equal to = asymptotic to, U+2248 ISOamsr - "atilde": 0x00E3, # latin small letter a with tilde, U+00E3 ISOlat1 - "auml": 0x00E4, # latin small letter a with diaeresis, U+00E4 ISOlat1 - "bdquo": 0x201E, # double low-9 quotation mark, U+201E NEW - "beta": 0x03B2, # greek small letter beta, U+03B2 ISOgrk3 - "brvbar": 0x00A6, # broken bar = broken vertical bar, U+00A6 ISOnum - "bull": 0x2022, # bullet = black small circle, U+2022 ISOpub - "cap": 0x2229, # intersection = cap, U+2229 ISOtech - "ccedil": 0x00E7, # latin small letter c with cedilla, U+00E7 ISOlat1 - "cedil": 0x00B8, # cedilla = spacing cedilla, U+00B8 ISOdia - "cent": 0x00A2, # cent sign, U+00A2 ISOnum - "chi": 0x03C7, # greek small letter chi, U+03C7 ISOgrk3 - "circ": 0x02C6, # modifier letter circumflex accent, U+02C6 ISOpub - "clubs": 0x2663, # black club suit = shamrock, U+2663 ISOpub - "cong": 0x2245, # approximately equal to, U+2245 ISOtech - "copy": 0x00A9, # copyright sign, U+00A9 ISOnum - "crarr": 0x21B5, # downwards arrow with corner leftwards = carriage return, U+21B5 NEW - "cup": 0x222A, # union = cup, U+222A ISOtech - "curren": 0x00A4, # currency sign, U+00A4 ISOnum - "dArr": 0x21D3, # downwards double arrow, U+21D3 ISOamsa - "dagger": 0x2020, # dagger, U+2020 ISOpub - "darr": 0x2193, # downwards arrow, U+2193 ISOnum - "deg": 0x00B0, # degree sign, U+00B0 ISOnum - "delta": 0x03B4, # greek small letter delta, U+03B4 ISOgrk3 - "diams": 0x2666, # black diamond suit, U+2666 ISOpub - "divide": 0x00F7, # division sign, U+00F7 ISOnum - "eacute": 0x00E9, # latin small letter e with acute, U+00E9 ISOlat1 - "ecirc": 0x00EA, # latin small letter e with circumflex, U+00EA ISOlat1 - "egrave": 0x00E8, # latin small letter e with grave, U+00E8 ISOlat1 - "empty": 0x2205, # empty set = null set = diameter, U+2205 ISOamso - "emsp": 0x2003, # em space, U+2003 ISOpub - "ensp": 0x2002, # en space, U+2002 ISOpub - "epsilon": 0x03B5, # greek small letter epsilon, U+03B5 ISOgrk3 - "equiv": 0x2261, # identical to, U+2261 ISOtech - "eta": 0x03B7, # greek small letter eta, U+03B7 ISOgrk3 - "eth": 0x00F0, # latin small letter eth, U+00F0 ISOlat1 - "euml": 0x00EB, # latin small letter e with diaeresis, U+00EB ISOlat1 - "euro": 0x20AC, # euro sign, U+20AC NEW - "exist": 0x2203, # there exists, U+2203 ISOtech - "fnof": 0x0192, # latin small f with hook = function = florin, U+0192 ISOtech - "forall": 0x2200, # for all, U+2200 ISOtech - "frac12": 0x00BD, # vulgar fraction one half = fraction one half, U+00BD ISOnum - "frac14": 0x00BC, # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum - "frac34": 0x00BE, # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum - "frasl": 0x2044, # fraction slash, U+2044 NEW - "gamma": 0x03B3, # greek small letter gamma, U+03B3 ISOgrk3 - "ge": 0x2265, # greater-than or equal to, U+2265 ISOtech - "gt": 0x003E, # greater-than sign, U+003E ISOnum - "hArr": 0x21D4, # left right double arrow, U+21D4 ISOamsa - "harr": 0x2194, # left right arrow, U+2194 ISOamsa - "hearts": 0x2665, # black heart suit = valentine, U+2665 ISOpub - "hellip": 0x2026, # horizontal ellipsis = three dot leader, U+2026 ISOpub - "iacute": 0x00ED, # latin small letter i with acute, U+00ED ISOlat1 - "icirc": 0x00EE, # latin small letter i with circumflex, U+00EE ISOlat1 - "iexcl": 0x00A1, # inverted exclamation mark, U+00A1 ISOnum - "igrave": 0x00EC, # latin small letter i with grave, U+00EC ISOlat1 - "image": 0x2111, # blackletter capital I = imaginary part, U+2111 ISOamso - "infin": 0x221E, # infinity, U+221E ISOtech - "int": 0x222B, # integral, U+222B ISOtech - "iota": 0x03B9, # greek small letter iota, U+03B9 ISOgrk3 - "iquest": 0x00BF, # inverted question mark = turned question mark, U+00BF ISOnum - "isin": 0x2208, # element of, U+2208 ISOtech - "iuml": 0x00EF, # latin small letter i with diaeresis, U+00EF ISOlat1 - "kappa": 0x03BA, # greek small letter kappa, U+03BA ISOgrk3 - "lArr": 0x21D0, # leftwards double arrow, U+21D0 ISOtech - "lambda": 0x03BB, # greek small letter lambda, U+03BB ISOgrk3 - "lang": 0x2329, # left-pointing angle bracket = bra, U+2329 ISOtech - "laquo": 0x00AB, # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum - "larr": 0x2190, # leftwards arrow, U+2190 ISOnum - "lceil": 0x2308, # left ceiling = apl upstile, U+2308 ISOamsc - "ldquo": 0x201C, # left double quotation mark, U+201C ISOnum - "le": 0x2264, # less-than or equal to, U+2264 ISOtech - "lfloor": 0x230A, # left floor = apl downstile, U+230A ISOamsc - "lowast": 0x2217, # asterisk operator, U+2217 ISOtech - "loz": 0x25CA, # lozenge, U+25CA ISOpub - "lrm": 0x200E, # left-to-right mark, U+200E NEW RFC 2070 - "lsaquo": 0x2039, # single left-pointing angle quotation mark, U+2039 ISO proposed - "lsquo": 0x2018, # left single quotation mark, U+2018 ISOnum - "lt": 0x003C, # less-than sign, U+003C ISOnum - "macr": 0x00AF, # macron = spacing macron = overline = APL overbar, U+00AF ISOdia - "mdash": 0x2014, # em dash, U+2014 ISOpub - "micro": 0x00B5, # micro sign, U+00B5 ISOnum - "middot": 0x00B7, # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum - "minus": 0x2212, # minus sign, U+2212 ISOtech - "mu": 0x03BC, # greek small letter mu, U+03BC ISOgrk3 - "nabla": 0x2207, # nabla = backward difference, U+2207 ISOtech - "nbsp": 0x00A0, # no-break space = non-breaking space, U+00A0 ISOnum - "ndash": 0x2013, # en dash, U+2013 ISOpub - "ne": 0x2260, # not equal to, U+2260 ISOtech - "ni": 0x220B, # contains as member, U+220B ISOtech - "not": 0x00AC, # not sign, U+00AC ISOnum - "notin": 0x2209, # not an element of, U+2209 ISOtech - "nsub": 0x2284, # not a subset of, U+2284 ISOamsn - "ntilde": 0x00F1, # latin small letter n with tilde, U+00F1 ISOlat1 - "nu": 0x03BD, # greek small letter nu, U+03BD ISOgrk3 - "oacute": 0x00F3, # latin small letter o with acute, U+00F3 ISOlat1 - "ocirc": 0x00F4, # latin small letter o with circumflex, U+00F4 ISOlat1 - "oelig": 0x0153, # latin small ligature oe, U+0153 ISOlat2 - "ograve": 0x00F2, # latin small letter o with grave, U+00F2 ISOlat1 - "oline": 0x203E, # overline = spacing overscore, U+203E NEW - "omega": 0x03C9, # greek small letter omega, U+03C9 ISOgrk3 - "omicron": 0x03BF, # greek small letter omicron, U+03BF NEW - "oplus": 0x2295, # circled plus = direct sum, U+2295 ISOamsb - "or": 0x2228, # logical or = vee, U+2228 ISOtech - "ordf": 0x00AA, # feminine ordinal indicator, U+00AA ISOnum - "ordm": 0x00BA, # masculine ordinal indicator, U+00BA ISOnum - "oslash": 0x00F8, # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 - "otilde": 0x00F5, # latin small letter o with tilde, U+00F5 ISOlat1 - "otimes": 0x2297, # circled times = vector product, U+2297 ISOamsb - "ouml": 0x00F6, # latin small letter o with diaeresis, U+00F6 ISOlat1 - "para": 0x00B6, # pilcrow sign = paragraph sign, U+00B6 ISOnum - "part": 0x2202, # partial differential, U+2202 ISOtech - "permil": 0x2030, # per mille sign, U+2030 ISOtech - "perp": 0x22A5, # up tack = orthogonal to = perpendicular, U+22A5 ISOtech - "phi": 0x03C6, # greek small letter phi, U+03C6 ISOgrk3 - "pi": 0x03C0, # greek small letter pi, U+03C0 ISOgrk3 - "piv": 0x03D6, # greek pi symbol, U+03D6 ISOgrk3 - "plusmn": 0x00B1, # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum - "pound": 0x00A3, # pound sign, U+00A3 ISOnum - "prime": 0x2032, # prime = minutes = feet, U+2032 ISOtech - "prod": 0x220F, # n-ary product = product sign, U+220F ISOamsb - "prop": 0x221D, # proportional to, U+221D ISOtech - "psi": 0x03C8, # greek small letter psi, U+03C8 ISOgrk3 - "quot": 0x0022, # quotation mark = APL quote, U+0022 ISOnum - "rArr": 0x21D2, # rightwards double arrow, U+21D2 ISOtech - "radic": 0x221A, # square root = radical sign, U+221A ISOtech - "rang": 0x232A, # right-pointing angle bracket = ket, U+232A ISOtech - "raquo": 0x00BB, # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum - "rarr": 0x2192, # rightwards arrow, U+2192 ISOnum - "rceil": 0x2309, # right ceiling, U+2309 ISOamsc - "rdquo": 0x201D, # right double quotation mark, U+201D ISOnum - "real": 0x211C, # blackletter capital R = real part symbol, U+211C ISOamso - "reg": 0x00AE, # registered sign = registered trade mark sign, U+00AE ISOnum - "rfloor": 0x230B, # right floor, U+230B ISOamsc - "rho": 0x03C1, # greek small letter rho, U+03C1 ISOgrk3 - "rlm": 0x200F, # right-to-left mark, U+200F NEW RFC 2070 - "rsaquo": 0x203A, # single right-pointing angle quotation mark, U+203A ISO proposed - "rsquo": 0x2019, # right single quotation mark, U+2019 ISOnum - "sbquo": 0x201A, # single low-9 quotation mark, U+201A NEW - "scaron": 0x0161, # latin small letter s with caron, U+0161 ISOlat2 - "sdot": 0x22C5, # dot operator, U+22C5 ISOamsb - "sect": 0x00A7, # section sign, U+00A7 ISOnum - "shy": 0x00AD, # soft hyphen = discretionary hyphen, U+00AD ISOnum - "sigma": 0x03C3, # greek small letter sigma, U+03C3 ISOgrk3 - "sigmaf": 0x03C2, # greek small letter final sigma, U+03C2 ISOgrk3 - "sim": 0x223C, # tilde operator = varies with = similar to, U+223C ISOtech - "spades": 0x2660, # black spade suit, U+2660 ISOpub - "sub": 0x2282, # subset of, U+2282 ISOtech - "sube": 0x2286, # subset of or equal to, U+2286 ISOtech - "sum": 0x2211, # n-ary summation, U+2211 ISOamsb - "sup": 0x2283, # superset of, U+2283 ISOtech - "sup1": 0x00B9, # superscript one = superscript digit one, U+00B9 ISOnum - "sup2": 0x00B2, # superscript two = superscript digit two = squared, U+00B2 ISOnum - "sup3": 0x00B3, # superscript three = superscript digit three = cubed, U+00B3 ISOnum - "supe": 0x2287, # superset of or equal to, U+2287 ISOtech - "szlig": 0x00DF, # latin small letter sharp s = ess-zed, U+00DF ISOlat1 - "tau": 0x03C4, # greek small letter tau, U+03C4 ISOgrk3 - "there4": 0x2234, # therefore, U+2234 ISOtech - "theta": 0x03B8, # greek small letter theta, U+03B8 ISOgrk3 - "thetasym": 0x03D1, # greek small letter theta symbol, U+03D1 NEW - "thinsp": 0x2009, # thin space, U+2009 ISOpub - "thorn": 0x00FE, # latin small letter thorn with, U+00FE ISOlat1 - "tilde": 0x02DC, # small tilde, U+02DC ISOdia - "times": 0x00D7, # multiplication sign, U+00D7 ISOnum - "trade": 0x2122, # trade mark sign, U+2122 ISOnum - "uArr": 0x21D1, # upwards double arrow, U+21D1 ISOamsa - "uacute": 0x00FA, # latin small letter u with acute, U+00FA ISOlat1 - "uarr": 0x2191, # upwards arrow, U+2191 ISOnum - "ucirc": 0x00FB, # latin small letter u with circumflex, U+00FB ISOlat1 - "ugrave": 0x00F9, # latin small letter u with grave, U+00F9 ISOlat1 - "uml": 0x00A8, # diaeresis = spacing diaeresis, U+00A8 ISOdia - "upsih": 0x03D2, # greek upsilon with hook symbol, U+03D2 NEW - "upsilon": 0x03C5, # greek small letter upsilon, U+03C5 ISOgrk3 - "uuml": 0x00FC, # latin small letter u with diaeresis, U+00FC ISOlat1 - "weierp": 0x2118, # script capital P = power set = Weierstrass p, U+2118 ISOamso - "xi": 0x03BE, # greek small letter xi, U+03BE ISOgrk3 - "yacute": 0x00FD, # latin small letter y with acute, U+00FD ISOlat1 - "yen": 0x00A5, # yen sign = yuan sign, U+00A5 ISOnum - "yuml": 0x00FF, # latin small letter y with diaeresis, U+00FF ISOlat1 - "zeta": 0x03B6, # greek small letter zeta, U+03B6 ISOgrk3 - "zwj": 0x200D, # zero width joiner, U+200D NEW RFC 2070 - "zwnj": 0x200C, # zero width non-joiner, U+200C NEW RFC 2070 -} - - -def to_unicode(text: StrOrBytes, encoding: Optional[str] = None, errors: str = "strict") -> str: - """Return the Unicode representation of a bytes object `text`. If `text` - is already a Unicode object, return it as-is.""" - if isinstance(text, str): - return text - if not isinstance(text, (bytes, str)): - raise TypeError(f"to_unicode must receive bytes or str, got {type(text).__name__}") - if encoding is None: - encoding = "utf-8" - return text.decode(encoding, errors) - - -def _replace_entities( - text: StrOrBytes, - keep: Iterable[str] = (), - remove_illegal: bool = True, - encoding: str = "utf-8", -) -> str: - """Remove entities from the given `text` by converting them to their - corresponding Unicode character. - - `text` can be a Unicode string or a byte string encoded in the given - `encoding` (which defaults to 'utf-8'). - - If `keep` is passed (with a list of entity names), those entities will - be kept (they won't be removed). - - It supports both numeric entities (``&#nnnn;`` and ``&#hhhh;``) - and named entities (such as `` `` or ``>``). - - If `remove_illegal` is ``True``, entities that can't be converted are removed. - If `remove_illegal` is ``False``, entities that can't be converted are kept "as - is". For more information, see the tests. - - Always returns a Unicode string (with the entities removed). - - >>> _replace_entities(b'Price: £100') - 'Price: \\xa3100' - >>> print(_replace_entities(b'Price: £100')) - Price: £100 - >>> - - """ - - def convert_entity(m: Match[str]) -> str: - groups = m.groupdict() - number = None - if groups.get("dec"): - number = int(groups["dec"], 10) - elif groups.get("hex"): - number = int(groups["hex"], 16) - elif groups.get("named"): - entity_name = groups["named"] - if entity_name.lower() in keep: - return m.group(0) - number = name2codepoint.get(entity_name) or name2codepoint.get(entity_name.lower()) - if number is not None: - # Browsers typically - # interpret numeric character references in the 80-9F range as representing the characters mapped - # to bytes 80-9F in the Windows-1252 encoding. For more info - # see: http://en.wikipedia.org/wiki/Character_encodings_in_HTML - try: - if 0x80 <= number <= 0x9F: - return bytes((number,)).decode("cp1252") - return chr(number) - except (ValueError, OverflowError): # pragma: no cover - pass - - return "" if remove_illegal and groups.get("semicolon") else m.group(0) - - return _ent_re.sub(convert_entity, to_unicode(text, encoding)) diff --git a/scrapling/core/custom_types.py b/scrapling/core/custom_types.py index d437a23..45ab4d5 100644 --- a/scrapling/core/custom_types.py +++ b/scrapling/core/custom_types.py @@ -3,6 +3,7 @@ from types import MappingProxyType from re import compile as re_compile, UNICODE, IGNORECASE from orjson import dumps, loads +from w3lib.html import replace_entities as _replace_entities from scrapling.core._types import ( Any, @@ -19,7 +20,6 @@ from scrapling.core._types import ( SupportsIndex, ) from scrapling.core.utils import _is_iterable, flatten, __CONSECUTIVE_SPACES_REGEX__ -from scrapling.core._html_utils import _replace_entities # Define type variable for AttributeHandler value type _TextHandlerType = TypeVar("_TextHandlerType", bound="TextHandler") From d0f52c38555cb683d192b4045b452b5ea9a36573 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 16:37:17 +0200 Subject: [PATCH 43/80] test: remove the tests for the removed html_utils module --- tests/parser/test_html_utils.py | 194 -------------------------------- 1 file changed, 194 deletions(-) delete mode 100644 tests/parser/test_html_utils.py diff --git a/tests/parser/test_html_utils.py b/tests/parser/test_html_utils.py deleted file mode 100644 index 924ef95..0000000 --- a/tests/parser/test_html_utils.py +++ /dev/null @@ -1,194 +0,0 @@ -import pytest - -from scrapling.core._html_utils import to_unicode, _replace_entities, name2codepoint - - -class TestToUnicode: - def test_string_input(self): - """Test to_unicode with string input""" - text = "hello world" - assert to_unicode(text) == "hello world" - - def test_bytes_input_default_encoding(self): - """Test to_unicode with `bytes` input using default UTF-8""" - text = b"hello world" - assert to_unicode(text) == "hello world" - - def test_bytes_input_custom_encoding(self): - """Test to_unicode with custom encoding""" - text = "café".encode('latin-1') - assert to_unicode(text, encoding='latin-1') == "café" - - def test_bytes_input_with_errors(self): - """Test to_unicode with error handling""" - # Invalid UTF-8 bytes - text = b'\xff\xfe' - assert to_unicode(text, errors='ignore') == "" - assert to_unicode(text, errors='replace') == "��" - - def test_invalid_input_type(self): - """Test to_unicode with an invalid input type""" - with pytest.raises(TypeError, match="to_unicode must receive bytes or str"): - to_unicode(123) - - def test_none_encoding_defaults_to_utf8(self): - """Test that None encoding defaults to UTF-8""" - text = "café".encode('utf-8') - assert to_unicode(text, encoding=None) == "café" - - -class TestReplaceEntities: - def test_named_entities(self): - """Test replacement of named HTML entities""" - text = "& < > "  " - result = _replace_entities(text) - assert result == "& < > \" \xa0" - - def test_decimal_entities(self): - """Test replacement of decimal numeric entities""" - text = "& < >" - result = _replace_entities(text) - assert result == "& < >" - - def test_hexadecimal_entities(self): - """Test replacement of hexadecimal numeric entities""" - text = "& < >" - result = _replace_entities(text) - assert result == "& < >" - - def test_mixed_entities(self): - """Test replacement of mixed entity types""" - text = "Price: £100 €50 $25" - result = _replace_entities(text) - assert result == "Price: £100 €50 $25" - - def test_keep_entities(self): - """Test keeping specific entities""" - text = "& < >" - result = _replace_entities(text, keep=['amp', 'lt']) - assert result == "& < >" - - def test_windows_1252_range(self): - """Test handling of Windows-1252 range characters""" - text = "€ ‚ Ÿ" # Windows-1252 range - result = _replace_entities(text) - # These should be decoded using cp1252 - assert "€" in result # 128 -> Euro sign - - def test_remove_illegal_entities_true(self): - """Test removing illegal entities with remove_illegal=True""" - text = "&unknown; 󴈿" - result = _replace_entities(text, remove_illegal=True) - # The function may convert large numbers to Unicode characters or leave them as-is - assert "&unknown;" not in result # Unknown entities should be removed or converted - - def test_remove_illegal_entities_false(self): - """Test keeping illegal entities with remove_illegal=False""" - text = "&unknown; 󴈿" - result = _replace_entities(text, remove_illegal=False) - # Unknown entities should be preserved when remove_illegal=False - assert "&unknown;" in result - # Large numeric entities may be converted to Unicode characters - - def test_bytes_input(self): - """Test with bytes input""" - text = b"& < >" - result = _replace_entities(text) - assert result == "& < >" - - def test_custom_encoding(self): - """Test with custom encoding""" - text = "é".encode('latin-1') - result = _replace_entities(text, encoding='latin-1') - assert result == "é" - - def test_entities_without_semicolon(self): - """Test entities without semicolon""" - text = "& < >" - result = _replace_entities(text, remove_illegal=True) - # Should handle entities without a semicolon - assert len(result) <= len(text) - - def test_case_insensitive_named_entities(self): - """Test case-insensitive named-entity handling""" - text = "& ≪ >" - result = _replace_entities(text) - assert result == "& < >" - - def test_edge_cases(self): - """Test edge cases""" - # Empty string - assert _replace_entities("") == "" - - # No entities - assert _replace_entities("plain text") == "plain text" - - # Invalid numeric entity - text = "&#-1;" - result = _replace_entities(text, remove_illegal=True) - # Invalid entities may be left as-is or removed depending on implementation - assert len(result) >= 0 # Ensure no exception is raised - - -class TestName2Codepoint: - def test_common_entities_exist(self): - """Test that common HTML entities exist in mapping""" - common_entities = ['amp', 'lt', 'gt', 'quot', 'nbsp', 'copy', 'reg'] - for entity in common_entities: - assert entity in name2codepoint - - def test_greek_letters_exist(self): - """Test that Greek letter entities exist""" - greek_letters = ['alpha', 'beta', 'gamma', 'delta', 'epsilon'] - for letter in greek_letters: - assert letter in name2codepoint - - def test_mathematical_symbols_exist(self): - """Test that mathematical symbol entities exist""" - math_symbols = ['sum', 'prod', 'int', 'infin', 'plusmn'] - for symbol in math_symbols: - assert symbol in name2codepoint - - def test_currency_symbols_exist(self): - """Test that currency symbol entities exist""" - currencies = ['pound', 'yen', 'euro', 'cent'] - for currency in currencies: - assert currency in name2codepoint - - def test_codepoint_values(self): - """Test specific codepoint values""" - assert name2codepoint['amp'] == 0x0026 # & - assert name2codepoint['lt'] == 0x003C # < - assert name2codepoint['gt'] == 0x003E # > - assert name2codepoint['nbsp'] == 0x00A0 # non-breaking space - assert name2codepoint['copy'] == 0x00A9 # © - - -class TestIntegration: - def test_real_world_html(self): - """Test with real-world HTML content""" - html = """ - <div class="content"> - © 2024 Company & Associates - Price: £99.99 (€89.99) - Math: α + β = γ - </div> - """ - result = _replace_entities(html) - - assert '
' in result - assert '© 2024 Company & Associates' in result - assert 'Price: £99.99 (€89.99)' in result - assert 'Math: α + β = γ' in result - - def test_performance_with_large_text(self): - """Test performance with large text containing many entities""" - # Create large text with repeated entities - text = ("& < > " " * 1000) - result = _replace_entities(text) - - # Should complete without issues and have correct content - assert result.count("&") == 1000 - assert result.count("<") == 1000 - assert result.count(">") == 1000 - assert result.count('"') == 1000 From 5aa178a76ed113aedca3470739e162c3cdb2fe56 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 18:27:52 +0200 Subject: [PATCH 44/80] style: update post requests type hints to be more accurate --- scrapling/engines/_browsers/_types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scrapling/engines/_browsers/_types.py b/scrapling/engines/_browsers/_types.py index 8391e9c..47322da 100644 --- a/scrapling/engines/_browsers/_types.py +++ b/scrapling/engines/_browsers/_types.py @@ -1,3 +1,5 @@ +from io import BytesIO + from curl_cffi.requests import ( ProxySpec, CookieTypes, @@ -50,7 +52,7 @@ if TYPE_CHECKING: # pragma: no cover # Types for POST/PUT/DELETE request method parameters class DataRequestParams(GetRequestParams, total=False): - data: Optional[Dict | str] + data: Optional[Dict[str, str] | List[Tuple] | str | BytesIO | bytes] json: Optional[Dict | List] # Types for browser session From 122923c80e48b0074a9ab239bdff55e190f12134 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 20:21:42 +0200 Subject: [PATCH 45/80] feat(spiders/requests): Use a reliable method for fingerprint generation --- scrapling/spiders/checkpoint.py | 2 +- scrapling/spiders/engine.py | 18 +++++++- scrapling/spiders/request.py | 79 +++++++++++++++++++++++++++++---- scrapling/spiders/scheduler.py | 11 +++-- scrapling/spiders/spider.py | 5 +++ 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/scrapling/spiders/checkpoint.py b/scrapling/spiders/checkpoint.py index ae795dc..4c511ae 100644 --- a/scrapling/spiders/checkpoint.py +++ b/scrapling/spiders/checkpoint.py @@ -17,7 +17,7 @@ class CheckpointData: """Container for checkpoint state.""" requests: List["Request"] = field(default_factory=list) - seen: Set[str] = field(default_factory=set) + seen: Set[bytes] = field(default_factory=set) class CheckpointManager: diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index 2a812be..c57a4b4 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -34,7 +34,11 @@ class CrawlerEngine: ): self.spider = spider self.session_manager = session_manager - self.scheduler = Scheduler() + self.scheduler = Scheduler( + include_kwargs=spider.fp_include_kwargs, + include_headers=spider.fp_include_headers, + keep_fragments=spider.fp_keep_fragments, + ) self.stats = CrawlStats() self._global_limiter = CapacityLimiter(spider.concurrent_requests) @@ -72,6 +76,15 @@ class CrawlerEngine: return self._domain_limiters[domain] return self._global_limiter + def _normalize_request(self, request: Request) -> None: + """Normalize request fields before enqueueing. + + Resolves empty sid to the session manager's default session ID. + This ensures consistent fingerprinting for requests using the same session. + """ + if not request.sid: + request.sid = self.session_manager.default_session_id + async def _process_request(self, request: Request) -> None: """Download and process a single request.""" async with self._rate_limiter(request.domain): @@ -101,6 +114,7 @@ class CrawlerEngine: retry_request.priority -= 1 # Don't retry immediately retry_request.dont_filter = True new_request = await self.spider.retry_blocked_request(retry_request, response) + self._normalize_request(new_request) await self.scheduler.enqueue(new_request) log.info( f"Scheduled blocked request for retry ({retry_request._retry_count}/{self.spider.max_blocked_retries}): {request.url}" @@ -114,6 +128,7 @@ class CrawlerEngine: async for result in callback(response): if isinstance(result, Request): if self._is_domain_allowed(result): + self._normalize_request(result) await self.scheduler.enqueue(result) else: self.stats.offsite_requests_count += 1 @@ -223,6 +238,7 @@ class CrawlerEngine: try: if not resuming: async for request in self.spider.start_requests(): + self._normalize_request(request) await self.scheduler.enqueue(request) else: log.info("Resuming from checkpoint, skipping start_requests()") diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py index e2fb588..977e8e8 100644 --- a/scrapling/spiders/request.py +++ b/scrapling/spiders/request.py @@ -1,12 +1,27 @@ -from urllib.parse import urlparse +import hashlib +from io import BytesIO +from functools import cached_property +from urllib.parse import urlparse, urlencode + +import orjson +from w3lib.url import canonicalize_url from scrapling.engines.toolbelt.custom import Response -from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union, TYPE_CHECKING +from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union, Tuple, TYPE_CHECKING if TYPE_CHECKING: from scrapling.spiders.spider import Spider +def _convert_to_bytes(value: str | bytes) -> bytes: + if isinstance(value, bytes): + return value + if not isinstance(value, str): + raise TypeError(f"Can't convert {type(value).__name__} to bytes") + + return value.encode(encoding="utf-8", errors="ignore") + + class Request: def __init__( self, @@ -27,6 +42,7 @@ class Request: self.meta: dict[str, Any] = meta if meta else {} self._retry_count: int = _retry_count self._session_kwargs = kwargs if kwargs else {} + self._fp = None def copy(self) -> "Request": """Create a copy of this request.""" @@ -41,15 +57,60 @@ class Request: **self._session_kwargs, ) - @property + @cached_property def domain(self) -> str: return urlparse(self.url).netloc - @property - def _fp(self) -> str: - """Generate a unique fingerprint for deduplication.""" - # TODO: Improve fingerprint - return f"{self.sid}:{self.url}" + def update_fingerprint( + self, + include_kwargs: bool = False, + include_headers: bool = False, + keep_fragments: bool = False, + ) -> bytes: + """Generate a unique fingerprint for deduplication. + + Caches the result in self._fp after first computation. + """ + + post_data = self._session_kwargs.get("data", {}) + body = b"" + if post_data: + if isinstance(post_data, dict | list | tuple): + body = urlencode(post_data).encode() + elif isinstance(post_data, str): + body = post_data.encode() + elif isinstance(post_data, BytesIO): + body = post_data.getvalue() + elif isinstance(post_data, bytes): + body = post_data + elif post_data is None: + body = b"" + else: + post_data = self._session_kwargs.get("json", {}) + body: bytes = orjson.dumps(post_data) if post_data else b"" + + data: Dict[str, str | Tuple] = { + "sid": self.sid, + "body": body.hex(), + "method": self._session_kwargs.get("method", "GET"), + "url": canonicalize_url(self.url, keep_fragments=keep_fragments), + } + + if include_kwargs: + kwargs = (key.lower() for key in self._session_kwargs.keys() if key.lower() not in ("data", "json")) + data["kwargs"] = "".join(set(_convert_to_bytes(key).hex() for key in kwargs)) + + if include_headers: + headers = self._session_kwargs.get("headers") or self._session_kwargs.get("extra_headers") or {} + processed_headers = {} + # Some header normalization + for key, value in headers.items(): + processed_headers[_convert_to_bytes(key.lower()).hex()] = _convert_to_bytes(value.lower()).hex() + data["headers"] = tuple(processed_headers.items()) + + fp = hashlib.sha1(orjson.dumps(data, option=orjson.OPT_SORT_KEYS), usedforsecurity=False).digest() + self._fp = fp + return fp def __repr__(self) -> str: callback_name = getattr(self.callback, "__name__", None) or "None" @@ -74,6 +135,8 @@ class Request: """Requests are equal if they have the same fingerprint.""" if not isinstance(other, Request): return NotImplemented + if self._fp is None or other._fp is None: + raise RuntimeError("Cannot compare requests before generating their fingerprints!") return self._fp == other._fp def __getstate__(self) -> dict[str, Any]: diff --git a/scrapling/spiders/scheduler.py b/scrapling/spiders/scheduler.py index e36472e..aca3277 100644 --- a/scrapling/spiders/scheduler.py +++ b/scrapling/spiders/scheduler.py @@ -17,16 +17,19 @@ class Scheduler: Duplicate URLs are filtered unless dont_filter=True. """ - def __init__(self): + def __init__(self, include_kwargs: bool = False, include_headers: bool = False, keep_fragments: bool = False): self._queue: asyncio.PriorityQueue[tuple[int, int, Request]] = asyncio.PriorityQueue() - self._seen: set[str] = set() + self._seen: set[bytes] = set() self._counter = count() # Mirror dict for snapshot without draining queue self._pending: dict[int, tuple[int, int, Request]] = {} + self._include_kwargs = include_kwargs + self._include_headers = include_headers + self._keep_fragments = keep_fragments async def enqueue(self, request: Request) -> bool: """Add a request to the queue.""" - fingerprint = request._fp + fingerprint = request.update_fingerprint(self._include_kwargs, self._include_headers, self._keep_fragments) if not request.dont_filter and fingerprint in self._seen: log.debug("Dropped duplicate request: %s", request) @@ -54,7 +57,7 @@ class Scheduler: def is_empty(self) -> bool: return self._queue.empty() - def snapshot(self) -> Tuple[List[Request], Set[str]]: + def snapshot(self) -> Tuple[List[Request], Set[bytes]]: """Create a snapshot of the current state for checkpoints.""" sorted_items = sorted(self._pending.values(), key=lambda x: (x[0], x[1])) # Maintain queue order requests = [item[2] for item in sorted_items] diff --git a/scrapling/spiders/spider.py b/scrapling/spiders/spider.py index 465bd4f..f14174f 100644 --- a/scrapling/spiders/spider.py +++ b/scrapling/spiders/spider.py @@ -78,6 +78,11 @@ class Spider(ABC): download_delay: float = 0.0 max_blocked_retries: int = 3 + # Fingerprint adjustments + fp_include_kwargs = False + fp_keep_fragments = False + fp_include_headers = False + # Logging settings logging_level: int = logging.DEBUG logging_format: str = "[%(asctime)s]:({spider_name}) %(levelname)s: %(message)s" From d90189e6754bff7ee9249ed7b4a51f917dfa5f36 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 20:22:47 +0200 Subject: [PATCH 46/80] test: update tests accordingly --- tests/spiders/test_request.py | 44 +++++++++++++++++++++++---------- tests/spiders/test_scheduler.py | 36 ++++++++++++--------------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/tests/spiders/test_request.py b/tests/spiders/test_request.py index f6860cf..997a71b 100644 --- a/tests/spiders/test_request.py +++ b/tests/spiders/test_request.py @@ -80,15 +80,24 @@ class TestRequestProperties: request = Request("https://api.v2.example.com/endpoint") assert request.domain == "api.v2.example.com" - def test_fingerprint_includes_session_and_url(self): - """Test fingerprint generation.""" - request = Request("https://example.com", sid="session1") - assert request._fp == "session1:https://example.com" - - def test_fingerprint_empty_session(self): - """Test fingerprint with empty session ID.""" + def test_fingerprint_returns_bytes(self): + """Test fingerprint generation returns bytes.""" request = Request("https://example.com") - assert request._fp == ":https://example.com" + fp = request.update_fingerprint() + assert isinstance(fp, bytes) + assert len(fp) == 20 # SHA1 produces 20 bytes + + def test_fingerprint_is_deterministic(self): + """Test same request produces same fingerprint.""" + r1 = Request("https://example.com", data={"key": "value"}) + r2 = Request("https://example.com", data={"key": "value"}) + assert r1.update_fingerprint() == r2.update_fingerprint() + + def test_fingerprint_different_urls(self): + """Test different URLs produce different fingerprints.""" + r1 = Request("https://example.com/page1") + r2 = Request("https://example.com/page2") + assert r1.update_fingerprint() != r2.update_fingerprint() class TestRequestCopy: @@ -160,17 +169,26 @@ class TestRequestComparison: def test_equality_by_fingerprint(self): """Test equality comparison by fingerprint.""" - r1 = Request("https://example.com", sid="session1") - r2 = Request("https://example.com", sid="session1") - r3 = Request("https://example.com", sid="session2") + r1 = Request("https://example.com") + r2 = Request("https://example.com") + r3 = Request("https://example.com/other") + + # Generate fingerprints first (required for equality) + r1.update_fingerprint() + r2.update_fingerprint() + r3.update_fingerprint() assert r1 == r2 assert r1 != r3 def test_equality_different_priorities_same_fingerprint(self): """Test requests with same fingerprint are equal despite different priorities.""" - r1 = Request("https://example.com", sid="s1", priority=1) - r2 = Request("https://example.com", sid="s1", priority=100) + r1 = Request("https://example.com", priority=1) + r2 = Request("https://example.com", priority=100) + + # Generate fingerprints first + r1.update_fingerprint() + r2.update_fingerprint() assert r1 == r2 # Same fingerprint means equal diff --git a/tests/spiders/test_scheduler.py b/tests/spiders/test_scheduler.py index 70b4ef5..a7365aa 100644 --- a/tests/spiders/test_scheduler.py +++ b/tests/spiders/test_scheduler.py @@ -75,12 +75,12 @@ class TestSchedulerEnqueue: assert len(scheduler) == 2 @pytest.mark.asyncio - async def test_enqueue_different_sessions_not_duplicate(self): - """Test that same URL with different sessions are not duplicates.""" + async def test_enqueue_different_methods_not_duplicate(self): + """Test that same URL with different methods are not duplicates.""" scheduler = Scheduler() - request1 = Request("https://example.com", sid="session1") - request2 = Request("https://example.com", sid="session2") + request1 = Request("https://example.com", method="GET") + request2 = Request("https://example.com", method="POST") result1 = await scheduler.enqueue(request1) result2 = await scheduler.enqueue(request2) @@ -195,17 +195,19 @@ class TestSchedulerSnapshot: @pytest.mark.asyncio async def test_snapshot_captures_seen_set(self): - """Test snapshot captures seen URLs.""" + """Test snapshot captures seen fingerprints.""" scheduler = Scheduler() - await scheduler.enqueue(Request("https://example.com/1", sid="s1")) - await scheduler.enqueue(Request("https://example.com/2", sid="s1")) + await scheduler.enqueue(Request("https://example.com/1")) + await scheduler.enqueue(Request("https://example.com/2")) requests, seen = scheduler.snapshot() assert len(seen) == 2 - assert "s1:https://example.com/1" in seen - assert "s1:https://example.com/2" in seen + # Fingerprints are now bytes (SHA1 hashes) + for fp in seen: + assert isinstance(fp, bytes) + assert len(fp) == 20 # SHA1 produces 20 bytes @pytest.mark.asyncio async def test_snapshot_returns_copies(self): @@ -218,12 +220,12 @@ class TestSchedulerSnapshot: # Modifying snapshot shouldn't affect scheduler requests.append(Request("https://modified.com")) - seen.add("new_fingerprint") + seen.add(b"new_fingerprint_bytes") original_requests, original_seen = scheduler.snapshot() assert len(original_requests) == 1 - assert "new_fingerprint" not in original_seen + assert b"new_fingerprint_bytes" not in original_seen @pytest.mark.asyncio async def test_snapshot_excludes_dequeued_requests(self): @@ -257,7 +259,7 @@ class TestSchedulerRestore: Request("https://example.com/1", priority=10), Request("https://example.com/2", priority=5), ] - checkpoint_seen = {"fp1", "fp2", "fp3"} + checkpoint_seen = {b"fp1_bytes_padded!", b"fp2_bytes_padded!", b"fp3_bytes_padded!"} data = CheckpointData(requests=checkpoint_requests, seen=checkpoint_seen) @@ -272,20 +274,14 @@ class TestSchedulerRestore: data = CheckpointData( requests=[], - seen={"fp1", "fp2"}, + seen={b"fp1_bytes_here_pad", b"fp2_bytes_here_pad"}, # Bytes fingerprints ) scheduler.restore(data) - # Now try to enqueue a request with matching fingerprint - request = Request("https://example.com") - request.sid = "" # Empty sid - # Manually set fingerprint that matches seen - # Since fingerprint is sid:url, we need to create matching ones - # Verify seen set was restored _, seen = scheduler.snapshot() - assert seen == {"fp1", "fp2"} + assert seen == {b"fp1_bytes_here_pad", b"fp2_bytes_here_pad"} @pytest.mark.asyncio async def test_restore_maintains_priority_order(self): From 5dbbd84b3dc4c0fa0085c0818333221cab50cc3f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Tue, 20 Jan 2026 20:28:13 +0200 Subject: [PATCH 47/80] fix(requests): return the cached fingerprint on second call --- scrapling/spiders/request.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py index 977e8e8..3351100 100644 --- a/scrapling/spiders/request.py +++ b/scrapling/spiders/request.py @@ -71,6 +71,8 @@ class Request: Caches the result in self._fp after first computation. """ + if self._fp is not None: + return self._fp post_data = self._session_kwargs.get("data", {}) body = b"" From 90c52c45c753a24828941b9653bb72ff973b7d5b Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Fri, 23 Jan 2026 00:00:48 +0200 Subject: [PATCH 48/80] feat(parser): replacing `tldextract` with `tld` library This might break the adaptive data users have for websites BUT: 1. tld uses ~3.7x less memory during extraction operations (1.5 MB vs 5.7 MB). 2. tld uses ~56% less memory on import (5.2 MB vs 11.9 MB). 3. Zero dependencies (vs 3 for tldextract). In return, it's 30ms slower for extracting 5000 URLs, which is negligible. Also, the type hints aren't always accurate, but it's fine; I corrected them. --- pyproject.toml | 2 +- scrapling/cli.py | 3 +++ scrapling/core/storage.py | 18 ++++++++++++------ scrapling/engines/toolbelt/fingerprints.py | 12 ++++++++---- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7a1b8b8..4a6a7ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,7 @@ dependencies = [ "lxml>=6.0.2", "cssselect>=1.3.0", "orjson>=3.11.5", - "tldextract>=5.3.1", + "tld>=0.13.1", "w3lib>=2.3.0" ] diff --git a/scrapling/cli.py b/scrapling/cli.py index 68470a5..59f017e 100644 --- a/scrapling/cli.py +++ b/scrapling/cli.py @@ -128,6 +128,9 @@ def install(force): # pragma: no cover ], "Playwright dependencies", ) + from tld.utils import update_tld_names + + update_tld_names(fail_silently=True) # if no errors raised by the above commands, then we add the below file __PACKAGE_DIR__.joinpath(".scrapling_dependencies_installed").touch() else: diff --git a/scrapling/core/storage.py b/scrapling/core/storage.py index 50258c5..8e04599 100644 --- a/scrapling/core/storage.py +++ b/scrapling/core/storage.py @@ -8,7 +8,7 @@ from orjson import dumps, loads from lxml.html import HtmlElement from scrapling.core.utils import _StorageTools, log -from scrapling.core._types import Dict, Optional, Any +from scrapling.core._types import Dict, Optional, Any, cast class StorageSystemMixin(ABC): # pragma: no cover @@ -17,18 +17,24 @@ class StorageSystemMixin(ABC): # pragma: no cover """ :param url: URL of the website we are working on to separate it from other websites data """ - self.url = url + # Make the url in lowercase to handle this edge case until it's updated: https://github.com/barseghyanartur/tld/issues/124 + self.url = url.lower() if (url and isinstance(url, str)) else None @lru_cache(64, typed=True) def _get_base_url(self, default_value: str = "default") -> str: - if not self.url or not isinstance(self.url, str): + if not self.url: return default_value try: - from tldextract import extract as tld + from tld import get_tld, Result - extracted = tld(self.url) - return extracted.top_domain_under_public_suffix or extracted.domain or default_value + # Fixing the inaccurate return type hint in `get_tld` + extracted: Result | None = cast( + Result, get_tld(self.url, as_object=True, fail_silently=True, fix_protocol=True) + ) + if not extracted: + return default_value + return extracted.fld or extracted.domain or default_value except AttributeError: return default_value diff --git a/scrapling/engines/toolbelt/fingerprints.py b/scrapling/engines/toolbelt/fingerprints.py index 2ddbbe5..6774691 100644 --- a/scrapling/engines/toolbelt/fingerprints.py +++ b/scrapling/engines/toolbelt/fingerprints.py @@ -5,11 +5,11 @@ Functions related to generating headers and fingerprints generally from functools import lru_cache from platform import system as platform_system -from tldextract import extract +from tld import get_tld, Result from browserforge.headers import Browser, HeaderGenerator from browserforge.headers.generator import SUPPORTED_OPERATING_SYSTEMS -from scrapling.core._types import Dict, Literal, Tuple +from scrapling.core._types import Dict, Literal, Tuple, cast __OS_NAME__ = platform_system() OSName = Literal["linux", "macos", "windows"] @@ -28,11 +28,15 @@ def generate_convincing_referer(url: str) -> str | None: :param url: The URL you are about to fetch. :return: Google's search URL of the domain name, or None for localhost/IP addresses """ - extracted = extract(url) + # Fixing the inaccurate return type hint in `get_tld` + extracted: Result | None = cast(Result, get_tld(url, as_object=True, fail_silently=True)) + if not extracted: + return None + website_name = extracted.domain # Skip generating referer for localhost, IP addresses, or when there's no valid domain - if not website_name or not extracted.suffix or website_name in ("localhost", "127.0.0.1", "::1"): + if not website_name or not extracted.tld or website_name in ("localhost", "127.0.0.1", "::1"): return None # Check if it's an IP address (simple check for IPv4) From 0c3d359b46e57a312d7a62c08840117d49c5a914 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 29 Jan 2026 00:57:30 +0200 Subject: [PATCH 49/80] fix(browsers): disable autoplay for all browsers --- scrapling/engines/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrapling/engines/constants.py b/scrapling/engines/constants.py index 39e3907..231e0c0 100644 --- a/scrapling/engines/constants.py +++ b/scrapling/engines/constants.py @@ -90,7 +90,7 @@ DEFAULT_STEALTH_FLAGS = ( "--disable-client-side-phishing-detection", "--disable-backgrounding-occluded-windows", "--disable-layer-tree-host-memory-pressure", - "--autoplay-policy=no-user-gesture-required", + "--autoplay-policy=user-gesture-required", "--disable-offer-store-unmasked-wallet-cards", "--disable-blink-features=AutomationControlled", "--disable-component-extensions-with-background-pages", From 65f1a23358b5270922af88effdf2e0011f6a2767 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 29 Jan 2026 00:58:04 +0200 Subject: [PATCH 50/80] fix(browsers): Improve stealth and speed by adjusting flags --- scrapling/engines/constants.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scrapling/engines/constants.py b/scrapling/engines/constants.py index 231e0c0..9cd738e 100644 --- a/scrapling/engines/constants.py +++ b/scrapling/engines/constants.py @@ -30,6 +30,7 @@ DEFAULT_FLAGS = ( "--no-service-autorun", "--homepage=about:blank", "--password-store=basic", + "--disable-hang-monitor", "--no-default-browser-check", "--disable-session-crashed-bubble", "--disable-search-engine-choice-screen", @@ -96,5 +97,5 @@ DEFAULT_STEALTH_FLAGS = ( "--disable-component-extensions-with-background-pages", "--enable-features=NetworkService,NetworkServiceInProcess,TrustTokens,TrustTokensAlwaysAllowIssuance", "--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4", - "--disable-features=AudioServiceOutOfProcess,IsolateOrigins,site-per-process,TranslateUI,BlinkGenPropertyTrees", + "--disable-features=AudioServiceOutOfProcess,TranslateUI,BlinkGenPropertyTrees", ) From ef8c5bc7d6d85820b791cb099fc9bf71681d8187 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 2 Feb 2026 00:16:22 +0200 Subject: [PATCH 51/80] feat(spiders/fetchers): Adding proxy rotation logic and change retry logic - User passes a single proxy to the browser session, and it will keep using the same context. Pass a proxy manager that automatically refreshes the IP with each proxy, and you get speed but sacrifice some stealth. - User imports the proxy rotator class and passes proxies to it and a rotation strategy (Round robin by default). Then pass the instance to the session class, which will create a context and a tab for each proxy returned by the rotator. This way, you sacrifice speed a bit, but you get maximum stealth since each context is created with the proxy that will be used. - Normal requests use what you pass without issues, of course. - All errors are retried now, and proxies are rotated on retries automatically. --- scrapling/core/_types.py | 2 + scrapling/engines/_browsers/_base.py | 191 +++++++++++-- scrapling/engines/_browsers/_controllers.py | 235 ++++++++------- scrapling/engines/_browsers/_stealth.py | 283 ++++++++++--------- scrapling/engines/_browsers/_types.py | 3 + scrapling/engines/_browsers/_validators.py | 7 + scrapling/engines/constants.py | 2 - scrapling/engines/static.py | 75 ++++- scrapling/engines/toolbelt/__init__.py | 2 + scrapling/engines/toolbelt/proxy_rotation.py | 104 +++++++ 10 files changed, 623 insertions(+), 281 deletions(-) create mode 100644 scrapling/engines/toolbelt/proxy_rotation.py diff --git a/scrapling/core/_types.py b/scrapling/core/_types.py index 48a2eec..f19e706 100644 --- a/scrapling/core/_types.py +++ b/scrapling/core/_types.py @@ -33,6 +33,8 @@ from typing import ( SupportsIndex, ) +# Proxy can be a string URL or a dict (Playwright format: {"server": "...", "username": "...", "password": "..."}) +ProxyType = Union[str, Dict[str, str]] SUPPORTED_HTTP_METHODS = Literal["GET", "POST", "PUT", "DELETE"] SelectorWaitStates = Literal["attached", "detached", "hidden", "visible"] PageLoadStates = Literal["commit", "domcontentloaded", "load", "networkidle"] diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index 810c51c..5936652 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -1,9 +1,11 @@ from time import time from asyncio import sleep as asyncio_sleep, Lock +from contextlib import contextmanager, asynccontextmanager from playwright.sync_api._generated import Page from playwright.sync_api import ( Frame, + Browser, BrowserContext, Playwright, Response as SyncPlaywrightResponse, @@ -11,18 +13,31 @@ from playwright.sync_api import ( from playwright.async_api._generated import Page as AsyncPage from playwright.async_api import ( Frame as AsyncFrame, + Browser as AsyncBrowser, Playwright as AsyncPlaywright, Response as AsyncPlaywrightResponse, BrowserContext as AsyncBrowserContext, ) from playwright._impl._errors import Error as PlaywrightError -from ._page import PageInfo, PagePool from scrapling.parser import Selector -from ._validators import validate, PlaywrightConfig, StealthConfig -from ._config_tools import __default_chrome_useragent__, __default_useragent__ -from scrapling.engines.toolbelt.navigation import intercept_route, async_intercept_route -from scrapling.core._types import Any, cast, Dict, List, Optional, Callable, TYPE_CHECKING, overload, Tuple +from scrapling.engines._browsers._page import PageInfo, PagePool +from scrapling.engines._browsers._validators import validate, PlaywrightConfig, StealthConfig +from scrapling.engines._browsers._config_tools import __default_chrome_useragent__, __default_useragent__ +from scrapling.engines.toolbelt.navigation import construct_proxy_dict, intercept_route, async_intercept_route +from scrapling.core._types import ( + Any, + Dict, + List, + Optional, + Callable, + TYPE_CHECKING, + overload, + Tuple, + ProxyType, + Generator, + AsyncGenerator, +) from scrapling.engines.constants import ( DEFAULT_STEALTH_FLAGS, HARMFUL_DEFAULT_ARGS, @@ -31,12 +46,19 @@ from scrapling.engines.constants import ( class SyncSession: + _config: "PlaywrightConfig | StealthConfig" + _context_options: Dict[str, Any] + + def _build_context_with_proxy(self, proxy: Optional[ProxyType] = None) -> Dict[str, Any]: + raise NotImplementedError # pragma: no cover + def __init__(self, max_pages: int = 1): self.max_pages = max_pages self.page_pool = PagePool(max_pages) self._max_wait_for_page = 60 self.playwright: Playwright | Any = None self.context: BrowserContext | Any = None + self.browser: Optional[Browser] = None self._is_alive = False def start(self): @@ -51,6 +73,10 @@ class SyncSession: self.context.close() self.context = None + if self.browser: + self.browser.close() + self.browser = None + if self.playwright: self.playwright.stop() self.playwright = None # pyright: ignore @@ -64,17 +90,28 @@ class SyncSession: def __exit__(self, exc_type, exc_val, exc_tb): self.close() + def _initialize_context(self, config: PlaywrightConfig | StealthConfig, ctx: BrowserContext) -> BrowserContext: + """Initialize the browser context.""" + if config.init_script: + ctx.add_init_script(path=config.init_script) + + if config.cookies: # pragma: no cover + ctx.add_cookies(config.cookies) + + return ctx + def _get_page( self, timeout: int | float, extra_headers: Optional[Dict[str, str]], disable_resources: bool, + context: Optional[BrowserContext] = None, ) -> PageInfo[Page]: # pragma: no cover """Get a new page to use""" - # No need to check if a page is available or not in sync code because the code blocked before reaching here till the page closed, ofc. - assert self.context is not None, "Browser context not initialized" - page = self.context.new_page() + ctx = context if context is not None else self.context + assert ctx is not None, "Browser context not initialized" + page = ctx.new_page() page.set_default_navigation_timeout(timeout) page.set_default_timeout(timeout) if extra_headers: @@ -129,14 +166,52 @@ class SyncSession: return handle_response + @contextmanager + def _page_generator( + self, + timeout: int | float, + extra_headers: Optional[Dict[str, str]], + disable_resources: bool, + proxy: Optional[ProxyType] = None, + ) -> Generator["PageInfo[Page]", None, None]: + """Acquire a page - either from persistent context or fresh context with proxy.""" + if self._config.proxy_rotator: + # Rotation mode: create fresh context with the provided proxy + if not self.browser: # pragma: no cover + raise RuntimeError("Browser not initialized for proxy rotation mode") + context_options = self._build_context_with_proxy(proxy) + context: BrowserContext = self.browser.new_context(**context_options) + + try: + context = self._initialize_context(self._config, context) + page_info = self._get_page(timeout, extra_headers, disable_resources, context=context) + yield page_info + finally: + context.close() + else: + # Standard mode: use PagePool with persistent context + page_info = self._get_page(timeout, extra_headers, disable_resources) + try: + yield page_info + finally: + page_info.page.close() + self.page_pool.pages.remove(page_info) + class AsyncSession: + _config: "PlaywrightConfig | StealthConfig" + _context_options: Dict[str, Any] + + def _build_context_with_proxy(self, proxy: Optional[ProxyType] = None) -> Dict[str, Any]: + raise NotImplementedError # pragma: no cover + def __init__(self, max_pages: int = 1): self.max_pages = max_pages self.page_pool = PagePool(max_pages) self._max_wait_for_page = 60 self.playwright: AsyncPlaywright | Any = None self.context: AsyncBrowserContext | Any = None + self.browser: Optional[AsyncBrowser] = None self._is_alive = False self._lock = Lock() @@ -152,6 +227,10 @@ class AsyncSession: await self.context.close() self.context = None # pyright: ignore + if self.browser: + await self.browser.close() + self.browser = None + if self.playwright: await self.playwright.stop() self.playwright = None # pyright: ignore @@ -165,19 +244,34 @@ class AsyncSession: async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() + async def _initialize_context( + self, config: PlaywrightConfig | StealthConfig, ctx: AsyncBrowserContext + ) -> AsyncBrowserContext: + """Initialize the browser context.""" + if config.init_script: # pragma: no cover + await ctx.add_init_script(path=config.init_script) + + if config.cookies: # pragma: no cover + await ctx.add_cookies(config.cookies) + + return ctx + async def _get_page( self, timeout: int | float, extra_headers: Optional[Dict[str, str]], disable_resources: bool, + context: Optional[AsyncBrowserContext] = None, ) -> PageInfo[AsyncPage]: # pragma: no cover """Get a new page to use""" + ctx = context if context is not None else self.context if TYPE_CHECKING: - assert self.context is not None, "Browser context not initialized" + assert ctx is not None, "Browser context not initialized" async with self._lock: # If we're at max capacity after cleanup, wait for busy pages to finish - if self.page_pool.pages_count >= self.max_pages: + if context is None and self.page_pool.pages_count >= self.max_pages: + # Only applies when using persistent context start_time = time() while time() - start_time < self._max_wait_for_page: await asyncio_sleep(0.05) @@ -188,7 +282,7 @@ class AsyncSession: f"No pages finished to clear place in the pool within the {self._max_wait_for_page}s timeout period" ) - page = await self.context.new_page() + page = await ctx.new_page() page.set_default_navigation_timeout(timeout) page.set_default_timeout(timeout) if extra_headers: @@ -241,6 +335,37 @@ class AsyncSession: return handle_response + @asynccontextmanager + async def _page_generator( + self, + timeout: int | float, + extra_headers: Optional[Dict[str, str]], + disable_resources: bool, + proxy: Optional[ProxyType] = None, + ) -> AsyncGenerator["PageInfo[AsyncPage]", None]: + """Acquire a page - either from persistent context or fresh context with proxy.""" + if self._config.proxy_rotator: + # Rotation mode: create fresh context with the provided proxy + if not self.browser: # pragma: no cover + raise RuntimeError("Browser not initialized for proxy rotation mode") + context_options = self._build_context_with_proxy(proxy) + context: AsyncBrowserContext = await self.browser.new_context(**context_options) + + try: + context = await self._initialize_context(self._config, context) + page_info = await self._get_page(timeout, extra_headers, disable_resources, context=context) + yield page_info + finally: + await context.close() + else: + # Standard mode: use PagePool with persistent context + page_info = await self._get_page(timeout, extra_headers, disable_resources) + try: + yield page_info + finally: + await page_info.page.close() + self.page_pool.pages.remove(page_info) + class BaseSessionMixin: @overload @@ -254,7 +379,7 @@ class BaseSessionMixin: ) -> PlaywrightConfig | StealthConfig: # Dark color scheme bypasses the 'prefersLightColor' check in creepjs self._context_options: Dict[str, Any] = {"color_scheme": "dark", "device_scale_factor": 2} - self._launch_options: Dict[str, Any] = self._context_options | { + self._browser_options: Dict[str, Any] = { "args": DEFAULT_FLAGS, "ignore_default_args": HARMFUL_DEFAULT_ARGS, } @@ -269,7 +394,7 @@ class BaseSessionMixin: return config def __generate_options__(self, extra_flags: Tuple | None = None) -> None: - config = cast(PlaywrightConfig, getattr(self, "_config", None)) + config: PlaywrightConfig | StealthConfig = self._config # type: ignore[has-type] self._context_options.update( { "proxy": config.proxy, @@ -287,36 +412,40 @@ class BaseSessionMixin: ) if not config.cdp_url: - self._launch_options |= self._context_options - self._context_options = {} - flags = self._launch_options["args"] + flags = self._browser_options["args"] if config.extra_flags or extra_flags: flags = list(set(flags + (config.extra_flags or extra_flags))) - self._launch_options.update( + self._browser_options.update( { "args": flags, "headless": config.headless, - "user_data_dir": config.user_data_dir, "channel": "chrome" if config.real_chrome else "chromium", } ) - if config.additional_args: - self._launch_options.update(config.additional_args) + self._user_data_dir = config.user_data_dir else: - # while `context_options` is left to be used when cdp mode is enabled - self._launch_options = dict() - if config.additional_args: - self._context_options.update(config.additional_args) + self._browser_options = {} - @staticmethod - def _is_retriable(error: Exception) -> bool: - """Check if an error is retriable (transient network/timeout issues).""" - if isinstance(error, TimeoutError): - return True - error_msg = str(error).lower() - return "net::" in error_msg or "failed to get response" in error_msg + if config.additional_args: + self._context_options.update(config.additional_args) + + def _build_context_with_proxy(self, proxy: Optional[ProxyType] = None) -> Dict[str, Any]: + """ + Build context options with a specific proxy for rotation mode. + + :param proxy: Proxy URL string or Playwright-style proxy dict to use for this context. + :return: Dictionary of context options for browser.new_context(). + """ + + context_options = self._context_options.copy() + + # Override proxy if provided + if proxy: + context_options["proxy"] = construct_proxy_dict(proxy) + + return context_options class DynamicSessionMixin(BaseSessionMixin): diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index a9dbe85..34a0b25 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -12,12 +12,13 @@ from playwright.async_api import ( ) from scrapling.core.utils import log -from scrapling.core._types import Unpack, TYPE_CHECKING -from ._types import PlaywrightSession, PlaywrightFetchParams -from ._base import SyncSession, AsyncSession, DynamicSessionMixin -from ._validators import validate_fetch as _validate, PlaywrightConfig +from scrapling.core._types import Unpack +from scrapling.engines.toolbelt.proxy_rotation import is_proxy_error from scrapling.engines.toolbelt.convertor import Response, ResponseFactory from scrapling.engines.toolbelt.fingerprints import generate_convincing_referer +from scrapling.engines._browsers._types import PlaywrightSession, PlaywrightFetchParams +from scrapling.engines._browsers._base import SyncSession, AsyncSession, DynamicSessionMixin +from scrapling.engines._browsers._validators import validate_fetch as _validate, PlaywrightConfig class DynamicSession(SyncSession, DynamicSessionMixin): @@ -26,7 +27,9 @@ class DynamicSession(SyncSession, DynamicSessionMixin): __slots__ = ( "_config", "_context_options", - "_launch_options", + "_browser_options", + "_user_data_dir", + "_headers_keys", "max_pages", "page_pool", "_max_wait_for_page", @@ -73,16 +76,19 @@ class DynamicSession(SyncSession, DynamicSessionMixin): try: if self._config.cdp_url: # pragma: no cover - browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context = browser.new_context(**self._context_options) + self.browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + if not self._config.proxy_rotator and self.browser: + self.context = self.browser.new_context(**self._context_options) + elif self._config.proxy_rotator: + self.browser = self.playwright.chromium.launch(**self._browser_options) else: - self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) + persistent_options = ( + self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} + ) + self.context = self.playwright.chromium.launch_persistent_context(**persistent_options) - if self._config.init_script: # pragma: no cover - self.context.add_init_script(path=self._config.init_script) - - if self._config.cookies: # pragma: no cover - self.context.add_cookies(self._config.cookies) + if self.context: + self.context = self._initialize_context(self._config, self.context) self._is_alive = True except Exception: @@ -123,60 +129,73 @@ class DynamicSession(SyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): - page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None - try: # pragma: no cover - page_info.page.on("response", handle_response) - first_response = page_info.page.goto(url, referer=referer) - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + with self._page_generator( + params.timeout, params.extra_headers, params.disable_resources, proxy + ) as page_info: + final_response = [None] + page = page_info.page + page.on("response", self._create_response_handler(page_info, final_response)) - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + try: + first_response = page.goto(url, referer=referer) + self._wait_for_page_stability(page, params.load_dom, params.network_idle) - if params.page_action: - try: - _ = params.page_action(page_info.page) - except Exception as e: # pragma: no cover - log.error(f"Error executing page_action: {e}") + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.wait_selector: - try: - waiter: Locator = page_info.page.locator(params.wait_selector) - waiter.first.wait_for(state=params.wait_selector_state) - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: # pragma: no cover - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + if params.page_action: + try: + _ = params.page_action(page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - page_info.page.wait_for_timeout(params.wait) + if params.wait_selector: + try: + waiter: Locator = page.locator(params.wait_selector) + waiter.first.wait_for(state=params.wait_selector_state) + self._wait_for_page_stability(page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - response = ResponseFactory.from_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + page.wait_for_timeout(params.wait) - page_info.page.close() - self.page_pool.pages.remove(page_info) - return response + response = ResponseFactory.from_playwright_response( + page, first_response, final_response[0], params.selector_config + ) + return response - except Exception as e: - page_info.mark_error() - page_info.page.close() - self.page_pool.pages.remove(page_info) + except Exception as e: + page_info.mark_error() + if attempt < self._config.retries - 1: + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {self._config.retry_delay}s..." + ) + else: + log.warning( + f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s..." + ) + time_sleep(self._config.retry_delay) + else: + log.error(f"Failed after {self._config.retries} attempts: {e}") + raise - if attempt < self._config.retries - 1 and self._is_retriable(e): - log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") - time_sleep(self._config.retry_delay) - else: - raise - - # For type checking purposes only - raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover + raise RuntimeError("Request failed") # pragma: no cover class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): """An async Browser session manager with page pooling, it's using a persistent browser Context by default with a temporary user profile directory.""" + __slots__ = ( + "_config", + "_context_options", + "_browser_options", + "_user_data_dir", + "_headers_keys", + ) + def __init__(self, **kwargs: Unpack[PlaywrightSession]): """A Browser session manager with page pooling @@ -216,18 +235,21 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): self.playwright = await async_playwright().start() try: if self._config.cdp_url: - browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) + self.browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + if not self._config.proxy_rotator and self.browser: + self.context: AsyncBrowserContext = await self.browser.new_context(**self._context_options) + elif self._config.proxy_rotator: + self.browser = await self.playwright.chromium.launch(**self._browser_options) else: + persistent_options = ( + self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} + ) self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **self._launch_options + **persistent_options ) - if self._config.init_script: # pragma: no cover - await self.context.add_init_script(path=self._config.init_script) - - if self._config.cookies: - await self.context.add_cookies(self._config.cookies) # pyright: ignore + if self.context: + self.context = await self._initialize_context(self._config, self.context) self._is_alive = True except Exception: @@ -269,58 +291,57 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): - page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None - if TYPE_CHECKING: - from playwright.async_api import Page as async_Page + async with self._page_generator( + params.timeout, params.extra_headers, params.disable_resources, proxy + ) as page_info: + final_response = [None] + page = page_info.page + page.on("response", self._create_response_handler(page_info, final_response)) - if not isinstance(page_info.page, async_Page): - raise TypeError + try: + first_response = await page.goto(url, referer=referer) + await self._wait_for_page_stability(page, params.load_dom, params.network_idle) - try: - page_info.page.on("response", handle_response) - first_response = await page_info.page.goto(url, referer=referer) - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + if params.page_action: + try: + _ = await params.page_action(page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - if params.page_action: - try: - _ = await params.page_action(page_info.page) - except Exception as e: - log.error(f"Error executing page_action: {e}") + if params.wait_selector: + try: + waiter: AsyncLocator = page.locator(params.wait_selector) + await waiter.first.wait_for(state=params.wait_selector_state) + await self._wait_for_page_stability(page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - if params.wait_selector: - try: - waiter: AsyncLocator = page_info.page.locator(params.wait_selector) - await waiter.first.wait_for(state=params.wait_selector_state) - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + await page.wait_for_timeout(params.wait) - await page_info.page.wait_for_timeout(params.wait) + response = await ResponseFactory.from_async_playwright_response( + page, first_response, final_response[0], params.selector_config + ) + return response - response = await ResponseFactory.from_async_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + except Exception as e: + page_info.mark_error() + if attempt < self._config.retries - 1: + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {self._config.retry_delay}s..." + ) + else: + log.warning( + f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s..." + ) + await asyncio_sleep(self._config.retry_delay) + else: + log.error(f"Failed after {self._config.retries} attempts: {e}") + raise - await page_info.page.close() - self.page_pool.pages.remove(page_info) - return response - - except Exception as e: # pragma: no cover - page_info.mark_error() - await page_info.page.close() - self.page_pool.pages.remove(page_info) - - if attempt < self._config.retries - 1 and self._is_retriable(e): - log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") - await asyncio_sleep(self._config.retry_delay) - else: - raise - - # For type checking purposes only - raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover + raise RuntimeError("Request failed") # pragma: no cover diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 62c6455..fc76d26 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -3,10 +3,7 @@ from re import compile as re_compile from time import sleep as time_sleep from asyncio import sleep as asyncio_sleep -from playwright.sync_api import ( - Locator, - Page, -) +from playwright.sync_api import Locator, Page, BrowserContext from playwright.async_api import ( Page as async_Page, Locator as AsyncLocator, @@ -17,12 +14,13 @@ from patchright.async_api import async_playwright from scrapling.core.utils import log from scrapling.core._types import Any, Unpack -from ._config_tools import _compiled_stealth_scripts -from ._types import StealthSession, StealthFetchParams -from ._base import SyncSession, AsyncSession, StealthySessionMixin -from ._validators import validate_fetch as _validate, StealthConfig +from scrapling.engines.toolbelt.proxy_rotation import is_proxy_error from scrapling.engines.toolbelt.convertor import Response, ResponseFactory from scrapling.engines.toolbelt.fingerprints import generate_convincing_referer +from scrapling.engines._browsers._config_tools import _compiled_stealth_scripts +from scrapling.engines._browsers._types import StealthSession, StealthFetchParams +from scrapling.engines._browsers._base import SyncSession, AsyncSession, StealthySessionMixin +from scrapling.engines._browsers._validators import validate_fetch as _validate, StealthConfig __CF_PATTERN__ = re_compile("challenges.cloudflare.com/cdn-cgi/challenge-platform/.*") @@ -33,7 +31,9 @@ class StealthySession(SyncSession, StealthySessionMixin): __slots__ = ( "_config", "_context_options", - "_launch_options", + "_browser_options", + "_user_data_dir", + "_headers_keys", "max_pages", "page_pool", "_max_wait_for_page", @@ -84,19 +84,20 @@ class StealthySession(SyncSession, StealthySessionMixin): try: if self._config.cdp_url: # pragma: no cover - browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context = browser.new_context(**self._context_options) + self.browser = self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + if not self._config.proxy_rotator: + assert self.browser is not None + self.context = self.browser.new_context(**self._context_options) + elif self._config.proxy_rotator: + self.browser = self.playwright.chromium.launch(**self._browser_options) else: - self.context = self.playwright.chromium.launch_persistent_context(**self._launch_options) + persistent_options = ( + self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} + ) + self.context = self.playwright.chromium.launch_persistent_context(**persistent_options) - for script in _compiled_stealth_scripts(): - self.context.add_init_script(script=script) - - if self._config.init_script: # pragma: no cover - self.context.add_init_script(path=self._config.init_script) - - if self._config.cookies: # pragma: no cover - self.context.add_cookies(self._config.cookies) + if self.context: + self.context = self._initialize_context(self._config, self.context) self._is_alive = True except Exception: @@ -107,6 +108,14 @@ class StealthySession(SyncSession, StealthySessionMixin): else: raise RuntimeError("Session has been already started") + def _initialize_context(self, config, ctx: BrowserContext) -> BrowserContext: + """Initialize the browser context.""" + for script in _compiled_stealth_scripts(): + ctx.add_init_script(script=script) + + ctx = super()._initialize_context(config, ctx) + return ctx + def _cloudflare_solver(self, page: Page) -> None: # pragma: no cover """Solve the cloudflare challenge displayed on the playwright page passed @@ -209,70 +218,78 @@ class StealthySession(SyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): - page_info = self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None - try: # pragma: no cover - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = page_info.page.goto(url, referer=referer) - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + with self._page_generator( + params.timeout, params.extra_headers, params.disable_resources, proxy + ) as page_info: + final_response = [None] + page = page_info.page + page.on("response", self._create_response_handler(page_info, final_response)) - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + try: + first_response = page.goto(url, referer=referer) + self._wait_for_page_stability(page, params.load_dom, params.network_idle) - if params.solve_cloudflare: - self._cloudflare_solver(page_info.page) - # Make sure the page is fully loaded after the captcha - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.page_action: - try: - _ = params.page_action(page_info.page) - except Exception as e: # pragma: no cover - log.error(f"Error executing page_action: {e}") + if params.solve_cloudflare: + self._cloudflare_solver(page) + # Make sure the page is fully loaded after the captcha + self._wait_for_page_stability(page, params.load_dom, params.network_idle) - if params.wait_selector: - try: - waiter: Locator = page_info.page.locator(params.wait_selector) - waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare - self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: # pragma: no cover - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + if params.page_action: + try: + _ = params.page_action(page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - page_info.page.wait_for_timeout(params.wait) + if params.wait_selector: + try: + waiter: Locator = page.locator(params.wait_selector) + waiter.first.wait_for(state=params.wait_selector_state) + self._wait_for_page_stability(page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - # Create response object - response = ResponseFactory.from_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + page.wait_for_timeout(params.wait) - # Close the page to free up resources - page_info.page.close() - self.page_pool.pages.remove(page_info) + response = ResponseFactory.from_playwright_response( + page, first_response, final_response[0], params.selector_config + ) + return response - return response + except Exception as e: + page_info.mark_error() + if attempt < self._config.retries - 1: + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {self._config.retry_delay}s..." + ) + else: + log.warning( + f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s..." + ) + time_sleep(self._config.retry_delay) + else: + log.error(f"Failed after {self._config.retries} attempts: {e}") + raise - except Exception as e: - page_info.mark_error() - page_info.page.close() - self.page_pool.pages.remove(page_info) - - if attempt < self._config.retries - 1 and self._is_retriable(e): - log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") - time_sleep(self._config.retry_delay) - else: - raise - - # For type checking purposes only - raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover + raise RuntimeError("Request failed") # pragma: no cover class AsyncStealthySession(AsyncSession, StealthySessionMixin): """An async Stealthy Browser session manager with page pooling.""" + __slots__ = ( + "_config", + "_context_options", + "_browser_options", + "_user_data_dir", + "_headers_keys", + ) + def __init__(self, **kwargs: Unpack[StealthSession]): """A Browser session manager with page pooling, it's using a persistent browser Context by default with a temporary user profile directory. @@ -315,21 +332,22 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): self.playwright = await async_playwright().start() try: if self._config.cdp_url: - browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) - self.context: AsyncBrowserContext = await browser.new_context(**self._context_options) + self.browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) + if not self._config.proxy_rotator: + assert self.browser is not None + self.context: AsyncBrowserContext = await self.browser.new_context(**self._context_options) + elif self._config.proxy_rotator: + self.browser = await self.playwright.chromium.launch(**self._browser_options) else: + persistent_options = ( + self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} + ) self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **self._launch_options + **persistent_options ) - for script in _compiled_stealth_scripts(): - await self.context.add_init_script(script=script) - - if self._config.init_script: # pragma: no cover - await self.context.add_init_script(path=self._config.init_script) - - if self._config.cookies: - await self.context.add_cookies(self._config.cookies) # pyright: ignore + if self.context: + self.context = await self._initialize_context(self._config, self.context) self._is_alive = True except Exception: @@ -340,6 +358,14 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): else: raise RuntimeError("Session has been already started") + async def _initialize_context(self, config, ctx: AsyncBrowserContext) -> AsyncBrowserContext: + """Initialize the browser context.""" + for script in _compiled_stealth_scripts(): + await ctx.add_init_script(script=script) + + ctx = await super()._initialize_context(config, ctx) + return ctx + async def _cloudflare_solver(self, page: async_Page) -> None: # pragma: no cover """Solve the cloudflare challenge displayed on the playwright page passed @@ -443,61 +469,62 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): - page_info = await self._get_page(params.timeout, params.extra_headers, params.disable_resources) - final_response = [None] - handle_response = self._create_response_handler(page_info, final_response) + proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None - try: - # Navigate to URL and wait for a specified state - page_info.page.on("response", handle_response) - first_response = await page_info.page.goto(url, referer=referer) - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + async with self._page_generator( + params.timeout, params.extra_headers, params.disable_resources, proxy + ) as page_info: + final_response = [None] + page = page_info.page + page.on("response", self._create_response_handler(page_info, final_response)) - if not first_response: - raise RuntimeError(f"Failed to get response for {url}") + try: + first_response = await page.goto(url, referer=referer) + await self._wait_for_page_stability(page, params.load_dom, params.network_idle) - if params.solve_cloudflare: - await self._cloudflare_solver(page_info.page) - # Make sure the page is fully loaded after the captcha - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) + if not first_response: + raise RuntimeError(f"Failed to get response for {url}") - if params.page_action: - try: - _ = await params.page_action(page_info.page) - except Exception as e: - log.error(f"Error executing page_action: {e}") + if params.solve_cloudflare: + await self._cloudflare_solver(page) + # Make sure the page is fully loaded after the captcha + await self._wait_for_page_stability(page, params.load_dom, params.network_idle) - if params.wait_selector: - try: - waiter: AsyncLocator = page_info.page.locator(params.wait_selector) - await waiter.first.wait_for(state=params.wait_selector_state) - # Wait again after waiting for the selector, helpful with protections like Cloudflare - await self._wait_for_page_stability(page_info.page, params.load_dom, params.network_idle) - except Exception as e: - log.error(f"Error waiting for selector {params.wait_selector}: {e}") + if params.page_action: + try: + _ = await params.page_action(page) + except Exception as e: # pragma: no cover + log.error(f"Error executing page_action: {e}") - await page_info.page.wait_for_timeout(params.wait) + if params.wait_selector: + try: + waiter: AsyncLocator = page.locator(params.wait_selector) + await waiter.first.wait_for(state=params.wait_selector_state) + await self._wait_for_page_stability(page, params.load_dom, params.network_idle) + except Exception as e: # pragma: no cover + log.error(f"Error waiting for selector {params.wait_selector}: {e}") - # Create response object - response = await ResponseFactory.from_async_playwright_response( - page_info.page, first_response, final_response[0], params.selector_config - ) + await page.wait_for_timeout(params.wait) - # Close the page to free up resources - await page_info.page.close() - self.page_pool.pages.remove(page_info) - return response + response = await ResponseFactory.from_async_playwright_response( + page, first_response, final_response[0], params.selector_config + ) + return response - except Exception as e: # pragma: no cover - page_info.mark_error() - await page_info.page.close() - self.page_pool.pages.remove(page_info) + except Exception as e: + page_info.mark_error() + if attempt < self._config.retries - 1: + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {self._config.retry_delay}s..." + ) + else: + log.warning( + f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s..." + ) + await asyncio_sleep(self._config.retry_delay) + else: + log.error(f"Failed after {self._config.retries} attempts: {e}") + raise - if attempt < self._config.retries - 1 and self._is_retriable(e): - log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {self._config.retry_delay}s...") - await asyncio_sleep(self._config.retry_delay) - else: - raise - - # For type checking purposes only - raise AssertionError("Unreachable: retry loop must return or raise") # pragma: no cover + raise RuntimeError("Request failed") # pragma: no cover diff --git a/scrapling/engines/_browsers/_types.py b/scrapling/engines/_browsers/_types.py index 47322da..afce5d0 100644 --- a/scrapling/engines/_browsers/_types.py +++ b/scrapling/engines/_browsers/_types.py @@ -20,6 +20,7 @@ from scrapling.core._types import ( SelectorWaitStates, TYPE_CHECKING, ) +from scrapling.engines.toolbelt.proxy_rotation import ProxyRotator # Type alias for `impersonate` parameter - accepts a single browser or list of browsers ImpersonateType: TypeAlias = BrowserTypeLiteral | List[BrowserTypeLiteral] | None @@ -34,6 +35,7 @@ if TYPE_CHECKING: # pragma: no cover proxies: Optional[ProxySpec] proxy: Optional[str] proxy_auth: Optional[Tuple[str, str]] + proxy_rotator: Optional[ProxyRotator] timeout: Optional[int | float] headers: Optional[Mapping[str, Optional[str]]] retries: Optional[int] @@ -70,6 +72,7 @@ if TYPE_CHECKING: # pragma: no cover timezone_id: str | None page_action: Optional[Callable] proxy: Optional[str | Dict[str, str] | Tuple] + proxy_rotator: Optional[ProxyRotator] extra_headers: Optional[Dict[str, str]] timeout: int | float init_script: Optional[str] diff --git a/scrapling/engines/_browsers/_validators.py b/scrapling/engines/_browsers/_validators.py index 0b08f2f..2bda436 100644 --- a/scrapling/engines/_browsers/_validators.py +++ b/scrapling/engines/_browsers/_validators.py @@ -18,6 +18,7 @@ from scrapling.core._types import ( SetCookieParam, SelectorWaitStates, ) +from scrapling.engines.toolbelt.proxy_rotation import ProxyRotator from scrapling.engines.toolbelt.navigation import construct_proxy_dict from scrapling.engines._browsers._types import PlaywrightFetchParams, StealthFetchParams @@ -70,6 +71,7 @@ class PlaywrightConfig(Struct, kw_only=True, frozen=False, weakref=True): timezone_id: str | None = "" page_action: Optional[Callable] = None proxy: Optional[str | Dict[str, str] | Tuple] = None # The default value for proxy in Playwright's source is `None` + proxy_rotator: Optional[ProxyRotator] = None extra_headers: Optional[Dict[str, str]] = None timeout: Seconds = 30000 init_script: Optional[str] = None @@ -88,6 +90,11 @@ class PlaywrightConfig(Struct, kw_only=True, frozen=False, weakref=True): """Custom validation after msgspec validation""" if self.page_action and not callable(self.page_action): raise TypeError(f"page_action must be callable, got {type(self.page_action).__name__}") + if self.proxy and self.proxy_rotator: + raise ValueError( + "Cannot use 'proxy_rotator' together with 'proxy'. " + "Use either a static proxy or proxy rotation, not both." + ) if self.proxy: self.proxy = construct_proxy_dict(self.proxy) if self.cdp_url: diff --git a/scrapling/engines/constants.py b/scrapling/engines/constants.py index 9cd738e..f658416 100644 --- a/scrapling/engines/constants.py +++ b/scrapling/engines/constants.py @@ -57,7 +57,6 @@ DEFAULT_STEALTH_FLAGS = ( "--ignore-gpu-blocklist", "--enable-tcp-fast-open", "--enable-web-bluetooth", - "--disable-hang-monitor", "--disable-cloud-import", "--disable-print-preview", "--disable-dev-shm-usage", @@ -84,7 +83,6 @@ DEFAULT_STEALTH_FLAGS = ( "--prerender-from-omnibox=disabled", "--safebrowsing-disable-auto-update", "--disable-offer-upload-credit-cards", - "--disable-features=site-per-process", "--disable-background-timer-throttling", "--disable-new-content-rendering-timeout", "--run-all-compositor-stages-before-draw", diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index 46eab23..e8a41aa 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -22,9 +22,10 @@ from scrapling.core._types import ( SUPPORTED_HTTP_METHODS, ) -from ._browsers._types import RequestsSession, GetRequestParams, DataRequestParams, ImpersonateType from .toolbelt.custom import Response from .toolbelt.convertor import ResponseFactory +from .toolbelt.proxy_rotation import ProxyRotator, is_proxy_error +from ._browsers._types import RequestsSession, GetRequestParams, DataRequestParams, ImpersonateType from .toolbelt.fingerprints import generate_convincing_referer, generate_headers, __default_useragent__ _NO_SESSION: Any = object() @@ -63,6 +64,7 @@ class _ConfigurationLogic(ABC): "_default_http3", "selector_config", "_is_alive", + "_proxy_rotator", ) def __init__(self, **kwargs: Unpack[RequestsSession]): @@ -82,6 +84,13 @@ class _ConfigurationLogic(ABC): self._default_http3 = kwargs.get("http3", False) self.selector_config = kwargs.get("selector_config") or {} self._is_alive = False + self._proxy_rotator: Optional[ProxyRotator] = kwargs.get("proxy_rotator") + + if self._proxy_rotator and (self._default_proxy or self._default_proxies): + raise ValueError( + "Cannot use 'proxy_rotator' together with 'proxy' or 'proxies'. " + "Use either a static proxy or proxy rotation, not both." + ) @staticmethod def _get_param(kwargs: Dict, key: str, default: Any) -> Any: @@ -218,7 +227,7 @@ class _SyncSessionLogic(_ConfigurationLogic): selector_config = self._get_param(kwargs, "selector_config", self.selector_config) or self.selector_config max_retries = self._get_param(kwargs, "retries", self._default_retries) retry_delay = self._get_param(kwargs, "retry_delay", self._default_retry_delay) - request_args = self._merge_request_args(stealth=stealth, **kwargs) + static_proxy = kwargs.pop("proxy", None) session = self._curl_session one_off_request = False @@ -228,22 +237,38 @@ class _SyncSessionLogic(_ConfigurationLogic): session = CurlSession() one_off_request = True - if session: + if not session: + raise RuntimeError("No active session available.") # pragma: no cover + + try: for attempt in range(max_retries): + if self._proxy_rotator and static_proxy is None: + proxy = self._proxy_rotator.get_proxy() + else: + proxy = static_proxy + + request_args = self._merge_request_args(stealth=stealth, proxy=proxy, **kwargs) try: response = session.request(method, **request_args) result = ResponseFactory.from_http_request(response, selector_config) return result except CurlError as e: # pragma: no cover if attempt < max_retries - 1: - log.error(f"Attempt {attempt + 1} failed: {e}. Retrying in {retry_delay} seconds...") + # Now if the rotator is enabled, we will try again with the new proxy + # If it's not enabled, then we will try again with the same proxy + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {retry_delay} seconds..." + ) + else: + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {retry_delay} seconds...") time_sleep(retry_delay) else: log.error(f"Failed after {max_retries} attempts: {e}") raise # Raise the exception if all retries fail - finally: - if session and one_off_request: - session.close() + finally: + if session and one_off_request: + session.close() raise RuntimeError("No active session available.") # pragma: no cover @@ -415,7 +440,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): selector_config = self._get_param(kwargs, "selector_config", self.selector_config) or self.selector_config max_retries = self._get_param(kwargs, "retries", self._default_retries) retry_delay = self._get_param(kwargs, "retry_delay", self._default_retry_delay) - request_args = self._merge_request_args(stealth=stealth, **kwargs) + static_proxy = kwargs.pop("proxy", None) session = self._async_curl_session one_off_request = False @@ -427,22 +452,40 @@ class _ASyncSessionLogic(_ConfigurationLogic): session = AsyncCurlSession() one_off_request = True - if session: + if not session: + raise RuntimeError("No active session available.") # pragma: no cover + + try: + # Determine if we should use proxy rotation for attempt in range(max_retries): + if self._proxy_rotator and static_proxy is None: + proxy = self._proxy_rotator.get_proxy() + else: + proxy = static_proxy + + request_args = self._merge_request_args(stealth=stealth, proxy=proxy, **kwargs) try: response = await session.request(method, **request_args) result = ResponseFactory.from_http_request(response, selector_config) return result except CurlError as e: # pragma: no cover if attempt < max_retries - 1: - log.error(f"Attempt {attempt + 1} failed: {e}. Retrying in {retry_delay} seconds...") + # Now if the rotator is enabled, we will try again with the new proxy + # If it's not enabled, then we will try again with the same proxy + if is_proxy_error(e): + log.warning( + f"Proxy '{proxy}' failed (attempt {attempt + 1}) | Retrying in {retry_delay} seconds..." + ) + else: + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {retry_delay} seconds...") + await asyncio_sleep(retry_delay) else: log.error(f"Failed after {max_retries} attempts: {e}") raise # Raise the exception if all retries fail - finally: - if session and one_off_request: - await session.close() + finally: + if session and one_off_request: + await session.close() raise RuntimeError("No active session available.") # pragma: no cover @@ -604,6 +647,7 @@ class FetcherSession: "selector_config", "_client", "_is_alive", + "_proxy_rotator", ) def __init__( @@ -623,6 +667,7 @@ class FetcherSession: verify: bool = True, cert: Optional[str | Tuple[str, str]] = None, selector_config: Optional[Dict] = None, + proxy_rotator: Optional[ProxyRotator] = None, ): """ :param impersonate: Browser version to impersonate. Can be a single browser string or a list of browser strings for random selection. (Default: latest available Chrome version) @@ -641,6 +686,7 @@ class FetcherSession: :param verify: Whether to verify HTTPS certificates. Defaults to True. :param cert: Tuple of (cert, key) filenames for the client certificate. :param selector_config: Arguments passed when creating the final Selector class. + :param proxy_rotator: A ProxyRotator instance for automatic proxy rotation. """ self._default_impersonate: ImpersonateType = impersonate self._stealth = stealthy_headers @@ -659,6 +705,7 @@ class FetcherSession: self.selector_config = selector_config or {} self._is_alive = False self._client: _SyncSessionLogic | _ASyncSessionLogic | None = None + self._proxy_rotator = proxy_rotator def __enter__(self) -> _SyncSessionLogic: """Creates and returns a new synchronous Fetcher Session""" @@ -667,6 +714,7 @@ class FetcherSession: config = {k.replace("_default_", ""): getattr(self, k) for k in self.__slots__ if k.startswith("_default")} config["stealthy_headers"] = self._stealth config["selector_config"] = self.selector_config + config["proxy_rotator"] = self._proxy_rotator self._client = _SyncSessionLogic(**config) self._is_alive = True return self._client.__enter__() @@ -687,6 +735,7 @@ class FetcherSession: config = {k.replace("_default_", ""): getattr(self, k) for k in self.__slots__ if k.startswith("_default")} config["stealthy_headers"] = self._stealth config["selector_config"] = self.selector_config + config["proxy_rotator"] = self._proxy_rotator self._client = _ASyncSessionLogic(**config) self._is_alive = True return await self._client.__aenter__() diff --git a/scrapling/engines/toolbelt/__init__.py b/scrapling/engines/toolbelt/__init__.py index 8b13789..f3714c7 100644 --- a/scrapling/engines/toolbelt/__init__.py +++ b/scrapling/engines/toolbelt/__init__.py @@ -1 +1,3 @@ +from .proxy_rotation import ProxyRotator, is_proxy_error, round_robin +__all__ = ["ProxyRotator", "is_proxy_error", "round_robin"] diff --git a/scrapling/engines/toolbelt/proxy_rotation.py b/scrapling/engines/toolbelt/proxy_rotation.py new file mode 100644 index 0000000..82c270d --- /dev/null +++ b/scrapling/engines/toolbelt/proxy_rotation.py @@ -0,0 +1,104 @@ +from threading import Lock + +from scrapling.core._types import Callable, Dict, List, Tuple, ProxyType + + +RotationStrategy = Callable[[List[ProxyType], int], Tuple[ProxyType, int]] +_PROXY_ERROR_INDICATORS = { + "net::err_proxy", + "net::err_tunnel", + "connection refused", + "connection reset", + "connection timed out", + "failed to connect", + "could not resolve proxy", +} + + +def _get_proxy_key(proxy: ProxyType) -> str: + """Generate a unique key for a proxy (for dicts it's server plus username).""" + if isinstance(proxy, str): + return proxy + server = proxy.get("server", "") + username = proxy.get("username", "") + return f"{server}|{username}" + + +def is_proxy_error(error: Exception) -> bool: + """Check if an error is proxy-related. Works for both HTTP and browser errors.""" + error_msg = str(error).lower() + return any(indicator in error_msg for indicator in _PROXY_ERROR_INDICATORS) + + +def round_robin(proxies: List[ProxyType], current_index: int) -> Tuple[ProxyType, int]: + """Default round-robin rotation strategy.""" + idx = current_index % len(proxies) + return proxies[idx], (idx + 1) % len(proxies) + + +class ProxyRotator: + """ + A thread-safe proxy rotator with pluggable rotation strategies. + + Supports: + - Round-robin rotation (default) + - Custom rotation strategies via callable + - Both string URLs and Playwright-style dict proxies + """ + + __slots__ = ("_proxies", "_proxy_to_index", "_strategy", "_current_index", "_lock") + + def __init__( + self, + proxies: List[ProxyType], + strategy: RotationStrategy = round_robin, + ): + """ + Initialize the proxy rotator. + + :param proxies: List of proxy URLs or Playwright-style proxy dicts. + - String format: "http://proxy1:8080" or "http://user:pass@proxy:8080" + - Dict format: {"server": "http://proxy:8080", "username": "user", "password": "pass"} + :param strategy: Rotation strategy function. Takes (proxies, current_index) and returns (proxy, next_index). Defaults to round_robin. + """ + if not proxies: + raise ValueError("At least one proxy must be provided") + + if not callable(strategy): + raise TypeError(f"strategy must be callable, got {type(strategy).__name__}") + + self._strategy = strategy + self._lock = Lock() + + # Validate and store proxies + self._proxies: List[ProxyType] = [] + self._proxy_to_index: Dict[str, int] = {} # O(1) lookup by unique key (server + username) + for i, proxy in enumerate(proxies): + if isinstance(proxy, (str, dict)): + if isinstance(proxy, dict) and "server" not in proxy: + raise ValueError("Proxy dict must have a 'server' key") + + self._proxy_to_index[_get_proxy_key(proxy)] = i + self._proxies.append(proxy) + else: + raise TypeError(f"Invalid proxy type: {type(proxy)}. Expected str or dict.") + + self._current_index = 0 + + def get_proxy(self) -> ProxyType: + """Get the next proxy according to the rotation strategy.""" + with self._lock: + proxy, self._current_index = self._strategy(self._proxies, self._current_index) + return proxy + + @property + def proxies(self) -> List[ProxyType]: + """Get a copy of all configured proxies.""" + return list(self._proxies) + + def __len__(self) -> int: + """Return the total number of configured proxies.""" + return len(self._proxies) + + def __repr__(self) -> str: + return f"ProxyRotator(proxies={len(self._proxies)})" From 6e0277f23b991d84d684fe38ae849edc88007eb8 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 2 Feb 2026 00:16:40 +0200 Subject: [PATCH 52/80] test: add new tests for the proxy rotation logic --- tests/fetchers/test_proxy_rotation.py | 303 ++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 tests/fetchers/test_proxy_rotation.py diff --git a/tests/fetchers/test_proxy_rotation.py b/tests/fetchers/test_proxy_rotation.py new file mode 100644 index 0000000..d418c1a --- /dev/null +++ b/tests/fetchers/test_proxy_rotation.py @@ -0,0 +1,303 @@ +import pytest +import random +from threading import Thread +from concurrent.futures import ThreadPoolExecutor + +from scrapling.engines.toolbelt import ProxyRotator, is_proxy_error, round_robin + + +class TestRoundRobinStrategy: + """Test the default round_robin strategy function""" + + def test_round_robin_cycles_through_proxies(self): + """Test that round_robin returns proxies in order""" + proxies = ["http://p1:8080", "http://p2:8080", "http://p3:8080"] + + proxy, next_idx = round_robin(proxies, 0) + assert proxy == "http://p1:8080" + assert next_idx == 1 + + proxy, next_idx = round_robin(proxies, 1) + assert proxy == "http://p2:8080" + assert next_idx == 2 + + proxy, next_idx = round_robin(proxies, 2) + assert proxy == "http://p3:8080" + assert next_idx == 0 # Wraps around + + def test_round_robin_wraps_index(self): + """Test that round_robin handles index overflow""" + proxies = ["http://p1:8080", "http://p2:8080"] + + # Index larger than list length should wrap + proxy, next_idx = round_robin(proxies, 5) + assert proxy == "http://p2:8080" # 5 % 2 = 1 + assert next_idx == 0 + + +class TestProxyRotatorCreation: + """Test ProxyRotator initialization and validation""" + + def test_create_with_string_proxies(self): + """Test creating rotator with string proxy URLs""" + proxies = ["http://p1:8080", "http://p2:8080"] + rotator = ProxyRotator(proxies) + + assert len(rotator) == 2 + assert rotator.proxies == proxies + + def test_create_with_dict_proxies(self): + """Test creating rotator with dict proxies""" + proxies = [ + {"server": "http://p1:8080", "username": "user1", "password": "pass1"}, + {"server": "http://p2:8080"}, + ] + rotator = ProxyRotator(proxies) + + assert len(rotator) == 2 + assert rotator.proxies == proxies + + def test_create_with_mixed_proxies(self): + """Test creating rotator with mixed string and dict proxies""" + proxies = [ + "http://p1:8080", + {"server": "http://p2:8080", "username": "user"}, + ] + rotator = ProxyRotator(proxies) + + assert len(rotator) == 2 + + def test_empty_proxies_raises_error(self): + """Test that empty proxy list raises ValueError""" + with pytest.raises(ValueError, match="At least one proxy must be provided"): + ProxyRotator([]) + + def test_dict_without_server_raises_error(self): + """Test that dict proxy without 'server' key raises ValueError""" + with pytest.raises(ValueError, match="Proxy dict must have a 'server' key"): + ProxyRotator([{"username": "user", "password": "pass"}]) + + def test_invalid_proxy_type_raises_error(self): + """Test that invalid proxy type raises TypeError""" + with pytest.raises(TypeError, match="Invalid proxy type"): + ProxyRotator([123]) + + with pytest.raises(TypeError, match="Invalid proxy type"): + ProxyRotator([None]) + + def test_non_callable_strategy_raises_error(self): + """Test that non-callable strategy raises TypeError""" + with pytest.raises(TypeError, match="strategy must be callable"): + ProxyRotator(["http://p1:8080"], strategy="round_robin") + + with pytest.raises(TypeError, match="strategy must be callable"): + ProxyRotator(["http://p1:8080"], strategy=123) + + +class TestProxyRotatorRotation: + """Test ProxyRotator rotation behavior""" + + def test_get_proxy_round_robin(self): + """Test that get_proxy cycles through proxies in order""" + proxies = ["http://p1:8080", "http://p2:8080", "http://p3:8080"] + rotator = ProxyRotator(proxies) + + # First cycle + assert rotator.get_proxy() == "http://p1:8080" + assert rotator.get_proxy() == "http://p2:8080" + assert rotator.get_proxy() == "http://p3:8080" + + # Second cycle - wraps around + assert rotator.get_proxy() == "http://p1:8080" + assert rotator.get_proxy() == "http://p2:8080" + assert rotator.get_proxy() == "http://p3:8080" + + def test_get_proxy_single_proxy(self): + """Test rotation with single proxy always returns the same proxy""" + rotator = ProxyRotator(["http://only:8080"]) + + for _ in range(5): + assert rotator.get_proxy() == "http://only:8080" + + def test_get_proxy_with_dict_proxies(self): + """Test rotation with dict proxies""" + proxies = [ + {"server": "http://p1:8080"}, + {"server": "http://p2:8080"}, + ] + rotator = ProxyRotator(proxies) + + assert rotator.get_proxy() == {"server": "http://p1:8080"} + assert rotator.get_proxy() == {"server": "http://p2:8080"} + assert rotator.get_proxy() == {"server": "http://p1:8080"} + + +class TestCustomStrategies: + """Test ProxyRotator with custom rotation strategies""" + + def test_random_strategy(self): + """Test custom random selection strategy""" + def random_strategy(proxies, idx): + return random.choice(proxies), idx + + proxies = ["http://p1:8080", "http://p2:8080", "http://p3:8080"] + rotator = ProxyRotator(proxies, strategy=random_strategy) + + # Get multiple proxies - they should all be valid + results = [rotator.get_proxy() for _ in range(10)] + assert all(p in proxies for p in results) + + def test_sticky_strategy(self): + """Test custom sticky strategy that always returns first proxy""" + def sticky_strategy(proxies, idx): + return proxies[0], idx + + rotator = ProxyRotator( + ["http://p1:8080", "http://p2:8080"], + strategy=sticky_strategy + ) + + for _ in range(5): + assert rotator.get_proxy() == "http://p1:8080" + + def test_weighted_strategy(self): + """Test custom weighted strategy""" + call_count = {"count": 0} + + def alternating_strategy(proxies, idx): + # Returns first proxy twice, then second proxy once + call_count["count"] += 1 + if call_count["count"] % 3 == 0: + return proxies[1], idx + return proxies[0], idx + + rotator = ProxyRotator( + ["http://primary:8080", "http://backup:8080"], + strategy=alternating_strategy + ) + + assert rotator.get_proxy() == "http://primary:8080" + assert rotator.get_proxy() == "http://primary:8080" + assert rotator.get_proxy() == "http://backup:8080" + + def test_lambda_strategy(self): + """Test using lambda as strategy""" + rotator = ProxyRotator( + ["http://p1:8080", "http://p2:8080"], + strategy=lambda proxies, idx: (proxies[-1], idx) # Always last + ) + + assert rotator.get_proxy() == "http://p2:8080" + assert rotator.get_proxy() == "http://p2:8080" + + +class TestProxyRotatorProperties: + """Test ProxyRotator properties and methods""" + + def test_proxies_property_returns_copy(self): + """Test that proxies property returns a copy, not the original list""" + original = ["http://p1:8080", "http://p2:8080"] + rotator = ProxyRotator(original) + + proxies_copy = rotator.proxies + proxies_copy.append("http://p3:8080") + + # Original should be unchanged + assert len(rotator) == 2 + assert len(rotator.proxies) == 2 + + def test_len_returns_proxy_count(self): + """Test __len__ returns correct count""" + assert len(ProxyRotator(["http://p1:8080"])) == 1 + assert len(ProxyRotator(["http://p1:8080", "http://p2:8080"])) == 2 + assert len(ProxyRotator(["a", "b", "c", "d", "e"])) == 5 + + def test_repr(self): + """Test __repr__ format""" + rotator = ProxyRotator(["http://p1:8080", "http://p2:8080", "http://p3:8080"]) + assert repr(rotator) == "ProxyRotator(proxies=3)" + + +class TestProxyRotatorThreadSafety: + """Test ProxyRotator thread safety""" + + def test_concurrent_get_proxy(self): + """Test that concurrent get_proxy calls don't cause errors""" + proxies = [f"http://p{i}:8080" for i in range(10)] + rotator = ProxyRotator(proxies) + results = [] + + def get_proxies(n): + for _ in range(n): + results.append(rotator.get_proxy()) + + threads = [Thread(target=get_proxies, args=(100,)) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + + # All results should be valid proxies + assert len(results) == 1000 + assert all(p in proxies for p in results) + + def test_thread_pool_concurrent_access(self): + """Test concurrent access using ThreadPoolExecutor""" + proxies = ["http://p1:8080", "http://p2:8080", "http://p3:8080"] + rotator = ProxyRotator(proxies) + + with ThreadPoolExecutor(max_workers=5) as executor: + futures = [executor.submit(rotator.get_proxy) for _ in range(100)] + results = [f.result() for f in futures] + + assert len(results) == 100 + assert all(p in proxies for p in results) + + +class TestIsProxyError: + """Test is_proxy_error utility function""" + + @pytest.mark.parametrize("error_msg", [ + "net::err_proxy_connection_failed", + "NET::ERR_PROXY_AUTH_FAILED", + "net::err_tunnel_connection_failed", + "Connection refused by proxy", + "Connection reset by peer", + "Connection timed out while connecting to proxy", + "Failed to connect to proxy server", + "Could not resolve proxy host", + ]) + def test_proxy_errors_detected(self, error_msg): + """Test that proxy-related errors are detected""" + assert is_proxy_error(Exception(error_msg)) is True + + @pytest.mark.parametrize("error_msg", [ + "Page not found", + "404 Not Found", + "Internal server error", + "DNS resolution failed", + "SSL certificate error", + "Timeout waiting for response", + "Invalid JSON response", + ]) + def test_non_proxy_errors_not_detected(self, error_msg): + """Test that non-proxy errors are not detected as proxy errors""" + assert is_proxy_error(Exception(error_msg)) is False + + def test_case_insensitive_detection(self): + """Test that error detection is case-insensitive""" + assert is_proxy_error(Exception("NET::ERR_PROXY")) is True + assert is_proxy_error(Exception("Net::Err_Proxy")) is True + assert is_proxy_error(Exception("CONNECTION REFUSED")) is True + + def test_empty_error_message(self): + """Test handling of empty error message""" + assert is_proxy_error(Exception("")) is False + + def test_custom_exception_types(self): + """Test with custom exception types""" + class CustomError(Exception): + pass + + assert is_proxy_error(CustomError("net::err_proxy_failed")) is True + assert is_proxy_error(CustomError("normal error")) is False From f88502718fe06675c4b353db2a0d6f33fb2a8464 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 2 Feb 2026 14:26:52 +0200 Subject: [PATCH 53/80] feat(proxy control): Force a proxy at request level at any given point And merge request's meta with response's meta --- scrapling/engines/_browsers/_base.py | 4 ++-- scrapling/engines/_browsers/_controllers.py | 20 ++++++++++++++++---- scrapling/engines/_browsers/_stealth.py | 20 ++++++++++++++++---- scrapling/engines/_browsers/_types.py | 1 + scrapling/engines/static.py | 4 ++-- scrapling/engines/toolbelt/convertor.py | 8 +++++++- scrapling/engines/toolbelt/custom.py | 6 +++++- scrapling/spiders/engine.py | 3 +++ scrapling/spiders/session.py | 3 ++- 9 files changed, 54 insertions(+), 15 deletions(-) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index 5936652..01bced5 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -175,7 +175,7 @@ class SyncSession: proxy: Optional[ProxyType] = None, ) -> Generator["PageInfo[Page]", None, None]: """Acquire a page - either from persistent context or fresh context with proxy.""" - if self._config.proxy_rotator: + if proxy: # Rotation mode: create fresh context with the provided proxy if not self.browser: # pragma: no cover raise RuntimeError("Browser not initialized for proxy rotation mode") @@ -344,7 +344,7 @@ class AsyncSession: proxy: Optional[ProxyType] = None, ) -> AsyncGenerator["PageInfo[AsyncPage]", None]: """Acquire a page - either from persistent context or fresh context with proxy.""" - if self._config.proxy_rotator: + if proxy: # Rotation mode: create fresh context with the provided proxy if not self.browser: # pragma: no cover raise RuntimeError("Browser not initialized for proxy rotation mode") diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index 34a0b25..b43807c 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -115,8 +115,11 @@ class DynamicSession(SyncSession, DynamicSessionMixin): :param network_idle: Wait for the page until there are no network connections for at least 500 ms. :param load_dom: Enabled by default, wait for all JavaScript on page(s) to fully load and execute. :param selector_config: The arguments that will be passed in the end while creating the final Selector's class. + :param proxy: Static proxy to override rotator and session proxy. A new browser context will be created and used with it. :return: A `Response` object. """ + static_proxy = kwargs.pop("proxy", None) + params = _validate(kwargs, self, PlaywrightConfig) if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") @@ -129,7 +132,10 @@ class DynamicSession(SyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): - proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None + if self._config.proxy_rotator and static_proxy is None: + proxy = self._config.proxy_rotator.get_proxy() + else: + proxy = static_proxy with self._page_generator( params.timeout, params.extra_headers, params.disable_resources, proxy @@ -162,7 +168,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): page.wait_for_timeout(params.wait) response = ResponseFactory.from_playwright_response( - page, first_response, final_response[0], params.selector_config + page, first_response, final_response[0], params.selector_config, meta={"proxy": proxy} ) return response @@ -276,8 +282,11 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): :param network_idle: Wait for the page until there are no network connections for at least 500 ms. :param load_dom: Enabled by default, wait for all JavaScript on page(s) to fully load and execute. :param selector_config: The arguments that will be passed in the end while creating the final Selector's class. + :param proxy: Static proxy to override rotator and session proxy. A new browser context will be created and used with it. :return: A `Response` object. """ + static_proxy = kwargs.pop("proxy", None) + params = _validate(kwargs, self, PlaywrightConfig) if not self._is_alive: # pragma: no cover @@ -291,7 +300,10 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): - proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None + if self._config.proxy_rotator and static_proxy is None: + proxy = self._config.proxy_rotator.get_proxy() + else: + proxy = static_proxy async with self._page_generator( params.timeout, params.extra_headers, params.disable_resources, proxy @@ -324,7 +336,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): await page.wait_for_timeout(params.wait) response = await ResponseFactory.from_async_playwright_response( - page, first_response, final_response[0], params.selector_config + page, first_response, final_response[0], params.selector_config, meta={"proxy": proxy} ) return response diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index fc76d26..5564376 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -204,8 +204,11 @@ class StealthySession(SyncSession, StealthySessionMixin): :param load_dom: Enabled by default, wait for all JavaScript on page(s) to fully load and execute. :param solve_cloudflare: Solves all types of the Cloudflare's Turnstile/Interstitial challenges before returning the response to you. :param selector_config: The arguments that will be passed in the end while creating the final Selector's class. + :param proxy: Static proxy to override rotator and session proxy. A new browser context will be created and used with it. :return: A `Response` object. """ + static_proxy = kwargs.pop("proxy", None) + params = _validate(kwargs, self, StealthConfig) if not self._is_alive: # pragma: no cover raise RuntimeError("Context manager has been closed") @@ -218,7 +221,10 @@ class StealthySession(SyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): - proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None + if self._config.proxy_rotator and static_proxy is None: + proxy = self._config.proxy_rotator.get_proxy() + else: + proxy = static_proxy with self._page_generator( params.timeout, params.extra_headers, params.disable_resources, proxy @@ -256,7 +262,7 @@ class StealthySession(SyncSession, StealthySessionMixin): page.wait_for_timeout(params.wait) response = ResponseFactory.from_playwright_response( - page, first_response, final_response[0], params.selector_config + page, first_response, final_response[0], params.selector_config, meta={"proxy": proxy} ) return response @@ -454,8 +460,11 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): :param load_dom: Enabled by default, wait for all JavaScript on page(s) to fully load and execute. :param solve_cloudflare: Solves all types of the Cloudflare's Turnstile/Interstitial challenges before returning the response to you. :param selector_config: The arguments that will be passed in the end while creating the final Selector's class. + :param proxy: Static proxy to override rotator and session proxy. A new browser context will be created and used with it. :return: A `Response` object. """ + static_proxy = kwargs.pop("proxy", None) + params = _validate(kwargs, self, StealthConfig) if not self._is_alive: # pragma: no cover @@ -469,7 +478,10 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): - proxy = self._config.proxy_rotator.get_proxy() if self._config.proxy_rotator else None + if self._config.proxy_rotator and static_proxy is None: + proxy = self._config.proxy_rotator.get_proxy() + else: + proxy = static_proxy async with self._page_generator( params.timeout, params.extra_headers, params.disable_resources, proxy @@ -507,7 +519,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): await page.wait_for_timeout(params.wait) response = await ResponseFactory.from_async_playwright_response( - page, first_response, final_response[0], params.selector_config + page, first_response, final_response[0], params.selector_config, meta={"proxy": proxy} ) return response diff --git a/scrapling/engines/_browsers/_types.py b/scrapling/engines/_browsers/_types.py index afce5d0..d298248 100644 --- a/scrapling/engines/_browsers/_types.py +++ b/scrapling/engines/_browsers/_types.py @@ -99,6 +99,7 @@ if TYPE_CHECKING: # pragma: no cover selector_config: Optional[Dict] extra_headers: Optional[Dict[str, str]] wait_selector_state: SelectorWaitStates + proxy: Optional[str | Dict[str, str]] class StealthSession(PlaywrightSession, total=False): allow_webgl: bool diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index e8a41aa..884fe0c 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -250,7 +250,7 @@ class _SyncSessionLogic(_ConfigurationLogic): request_args = self._merge_request_args(stealth=stealth, proxy=proxy, **kwargs) try: response = session.request(method, **request_args) - result = ResponseFactory.from_http_request(response, selector_config) + result = ResponseFactory.from_http_request(response, selector_config, meta={"proxy": proxy}) return result except CurlError as e: # pragma: no cover if attempt < max_retries - 1: @@ -466,7 +466,7 @@ class _ASyncSessionLogic(_ConfigurationLogic): request_args = self._merge_request_args(stealth=stealth, proxy=proxy, **kwargs) try: response = await session.request(method, **request_args) - result = ResponseFactory.from_http_request(response, selector_config) + result = ResponseFactory.from_http_request(response, selector_config, meta={"proxy": proxy}) return result except CurlError as e: # pragma: no cover if attempt < max_retries - 1: diff --git a/scrapling/engines/toolbelt/convertor.py b/scrapling/engines/toolbelt/convertor.py index ef28acf..9dff73d 100644 --- a/scrapling/engines/toolbelt/convertor.py +++ b/scrapling/engines/toolbelt/convertor.py @@ -85,6 +85,7 @@ class ResponseFactory: first_response: SyncResponse, final_response: Optional[SyncResponse], parser_arguments: Dict, + meta: Optional[Dict] = None, ) -> Response: """ Transforms a Playwright response into an internal `Response` object, encapsulating @@ -134,6 +135,7 @@ class ResponseFactory: "headers": first_response.all_headers(), "request_headers": first_response.request.all_headers(), "history": history, + "meta": meta, **parser_arguments, } ) @@ -220,6 +222,7 @@ class ResponseFactory: first_response: AsyncResponse, final_response: Optional[AsyncResponse], parser_arguments: Dict, + meta: Optional[Dict] = None, ) -> Response: """ Transforms a Playwright response into an internal `Response` object, encapsulating @@ -269,16 +272,18 @@ class ResponseFactory: "headers": await first_response.all_headers(), "request_headers": await first_response.request.all_headers(), "history": history, + "meta": meta, **parser_arguments, } ) @staticmethod - def from_http_request(response: CurlResponse, parser_arguments: Dict) -> Response: + def from_http_request(response: CurlResponse, parser_arguments: Dict, meta: Optional[Dict] = None) -> Response: """Takes `curl_cffi` response and generates `Response` object from it. :param response: `curl_cffi` response object :param parser_arguments: Additional arguments to be passed to the `Response` object constructor. + :param meta: Optional metadata dictionary to attach to the Response. :return: A `Response` object that is the same as `Selector` object except it has these added attributes: `status`, `reason`, `cookies`, `headers`, and `request_headers` """ return Response( @@ -293,6 +298,7 @@ class ResponseFactory: "request_headers": dict(response.request.headers) if response.request else {}, "method": response.request.method if response.request else "GET", "history": response.history, # https://github.com/lexiforest/curl_cffi/issues/82 + "meta": meta, **parser_arguments, } ) diff --git a/scrapling/engines/toolbelt/custom.py b/scrapling/engines/toolbelt/custom.py index f5b8f62..29b9e17 100644 --- a/scrapling/engines/toolbelt/custom.py +++ b/scrapling/engines/toolbelt/custom.py @@ -39,6 +39,7 @@ class Response(Selector): encoding: str = "utf-8", method: str = "GET", history: List | None = None, + meta: Dict[str, Any] | None = None, **selector_config: Any, ): adaptive_domain: str = cast(str, selector_config.pop("adaptive_domain", "")) @@ -57,7 +58,10 @@ class Response(Selector): # For easier debugging while working from a Python shell log.info(f"Fetched ({status}) <{method} {url}> (referer: {request_headers.get('referer')})") - self.meta: Dict[str, Any] = {} + if meta and not isinstance(meta, dict): + raise TypeError(f"Response meta should be dictionary but got {type(meta).__name__} instead!") + + self.meta: Dict[str, Any] = meta or {} self.request: Optional["Request"] = None # Will be set by crawler def follow( diff --git a/scrapling/spiders/engine.py b/scrapling/spiders/engine.py index c57a4b4..416911d 100644 --- a/scrapling/spiders/engine.py +++ b/scrapling/spiders/engine.py @@ -113,6 +113,9 @@ class CrawlerEngine: retry_request._retry_count += 1 retry_request.priority -= 1 # Don't retry immediately retry_request.dont_filter = True + retry_request._session_kwargs.pop("proxy", None) + retry_request._session_kwargs.pop("proxies", None) + new_request = await self.spider.retry_blocked_request(retry_request, response) self._normalize_request(new_request) await self.scheduler.enqueue(new_request) diff --git a/scrapling/spiders/session.py b/scrapling/spiders/session.py index f5b5a49..8f5e7af 100644 --- a/scrapling/spiders/session.py +++ b/scrapling/spiders/session.py @@ -124,7 +124,8 @@ class SessionManager: response = await session.fetch(url=request.url, **request._session_kwargs) response.request = request - response.meta = request.meta + # Merge request meta into response meta (response meta takes priority) + response.meta = {**request.meta, **response.meta} return response raise RuntimeError("No session found with the request session id") From 151e4e7a7c1def5600fccd54289bc30389486816 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Thu, 5 Feb 2026 02:39:51 +0200 Subject: [PATCH 54/80] docs: adding new sponsor --- docs/README.md | 1 + docs/README_AR.md | 1 + docs/README_CN.md | 1 + docs/README_DE.md | 1 + docs/README_ES.md | 1 + docs/README_JP.md | 1 + docs/README_RU.md | 1 + docs/index.md | 1 + images/HyperSolutions.png | Bin 0 -> 26495 bytes 9 files changed, 8 insertions(+) create mode 100644 images/HyperSolutions.png diff --git a/docs/README.md b/docs/README.md index 8f34915..d411099 100644 --- a/docs/README.md +++ b/docs/README.md @@ -77,6 +77,7 @@ Built for the modern Web, Scrapling features **its own rapid parsing engine** an + diff --git a/docs/README_AR.md b/docs/README_AR.md index f37cca9..8a21afb 100644 --- a/docs/README_AR.md +++ b/docs/README_AR.md @@ -74,6 +74,7 @@ Scrapling ليست مجرد مكتبة أخرى لاستخراج بيانات ا + diff --git a/docs/README_CN.md b/docs/README_CN.md index fd2a854..ac83218 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -74,6 +74,7 @@ Scrapling不仅仅是另一个网页抓取库。它是第一个**自适应**抓 + diff --git a/docs/README_DE.md b/docs/README_DE.md index 9b9dd6c..3013d51 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -74,6 +74,7 @@ Für das moderne Web entwickelt, bietet Scrapling **seine eigene schnelle Parsin + diff --git a/docs/README_ES.md b/docs/README_ES.md index 7d7b7f2..a913608 100644 --- a/docs/README_ES.md +++ b/docs/README_ES.md @@ -74,6 +74,7 @@ Construido para la Web moderna, Scrapling presenta **su propio motor de análisi + diff --git a/docs/README_JP.md b/docs/README_JP.md index 4cb9077..1427607 100644 --- a/docs/README_JP.md +++ b/docs/README_JP.md @@ -74,6 +74,7 @@ Scraplingは単なるウェブスクレイピングライブラリではあり + diff --git a/docs/README_RU.md b/docs/README_RU.md index f0699c1..fed6f26 100644 --- a/docs/README_RU.md +++ b/docs/README_RU.md @@ -74,6 +74,7 @@ Scrapling - это не просто очередная библиотека д + diff --git a/docs/index.md b/docs/index.md index ab798e4..e61b458 100644 --- a/docs/index.md +++ b/docs/index.md @@ -43,6 +43,7 @@ Built for the modern Web, Scrapling features **its own rapid parsing engine** an +
diff --git a/images/HyperSolutions.png b/images/HyperSolutions.png new file mode 100644 index 0000000000000000000000000000000000000000..f16f5def2b7d91fbf349af50417b5600899b9702 GIT binary patch literal 26495 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 Date: Thu, 5 Feb 2026 02:44:12 +0200 Subject: [PATCH 55/80] docs: make translation urls absolute For PyPI, Docker, and other external websites featuring this --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index d411099..b4d1950 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -Automated translations: [العربيه](README_AR.md) | [Español](README_ES.md) | [Deutsch](README_DE.md) | [简体中文](README_CN.md) | [日本語](README_JP.md) | [Русский](README_RU.md) +Automated translations: [العربيه](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_AR.md) | [Español](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_ES.md) | [Deutsch](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_DE.md) | [简体中文](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_CN.md) | [日本語](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_JP.md) | [Русский](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_RU.md)

From aa7a95fb70acea193c5987006a7c92b959208d45 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Fri, 6 Feb 2026 02:43:51 +0200 Subject: [PATCH 56/80] feat(parser)!: Make all selection return selector objects by default - The strings/Texthandlers are only returned by `get`/`getall`/`extract`/`extract_first`. This makes the type checking/autocompletion experience consistent. - Removed `css_first` and `xpath_first` since it doesn't make sense to leave them now. - Made the type hints more accurate in multiple places. --- scrapling/core/mixins.py | 3 + scrapling/core/shell.py | 2 +- scrapling/parser.py | 231 +++++++++++++++++++-------------------- 3 files changed, 116 insertions(+), 120 deletions(-) diff --git a/scrapling/core/mixins.py b/scrapling/core/mixins.py index 3a96bda..0b66c07 100644 --- a/scrapling/core/mixins.py +++ b/scrapling/core/mixins.py @@ -15,6 +15,9 @@ class SelectorsGeneration: """Generate a selector for the current element. :return: A string of the generated selector. """ + if self._is_text_node(self._root): + return "" + selectorPath = [] target = self css = selection.lower() == "css" diff --git a/scrapling/core/shell.py b/scrapling/core/shell.py index 0499e81..3a1511e 100644 --- a/scrapling/core/shell.py +++ b/scrapling/core/shell.py @@ -583,7 +583,7 @@ class Convertor: raise ValueError(f"Unknown extraction type: {extraction_type}") else: if main_content_only: - page = cast(Selector, page.css_first("body")) or page + page = cast(Selector, page.css("body").first) or page pages = [page] if not css_selector else cast(Selectors, page.css(css_selector)) for page in pages: diff --git a/scrapling/parser.py b/scrapling/parser.py index 8e9704d..0edaf94 100644 --- a/scrapling/parser.py +++ b/scrapling/parser.py @@ -142,8 +142,21 @@ class Selector(SelectorsGeneration): self._raw_body = content else: + if self._is_text_node(root): + # Text node (from ::text, /text(), ::attr(), /@attr, etc.) + self._root = root + self._raw_body = "" + self.__adaptive_enabled = False + self.__keep_comments = keep_comments + self.__keep_cdata = keep_cdata + self.__huge_tree_enabled = huge_tree + self.encoding = encoding + self.url = url + self.__attributes = None + self.__tag = None + return # All HTML types inherit from HtmlMixin so this to check for all at once - if not issubclass(type(root), HtmlMixin): + elif not issubclass(type(root), HtmlMixin): raise TypeError( f"Root have to be a valid element of `html` module types to work, not of type {type(root)}" ) @@ -202,9 +215,13 @@ class Selector(SelectorsGeneration): return self._cached_response_data def __getitem__(self, key: str) -> TextHandler: + if self._is_text_node(self._root): + raise TypeError("Text nodes do not have attributes") return self.attrib[key] def __contains__(self, key: str) -> bool: + if self._is_text_node(self._root): + return False return key in self.attrib # Node functionalities, I wanted to move to a separate Mixin class, but it had a slight impact on performance @@ -220,8 +237,8 @@ class Selector(SelectorsGeneration): # Faster than checking `element.is_attribute or element.is_text or element.is_tail` return issubclass(type(element), _ElementUnicodeResult) - def __element_convertor(self, element: HtmlElement) -> "Selector": - """Used internally to convert a single HtmlElement to Selector directly without checks""" + def __element_convertor(self, element: HtmlElement | _ElementUnicodeResult) -> "Selector": + """Used internally to convert a single HtmlElement or text node to Selector directly without checks""" db_instance = self._storage if (hasattr(self, "_storage") and self._storage) else None return Selector( root=element, @@ -235,21 +252,14 @@ class Selector(SelectorsGeneration): **self.__response_data, ) - def __elements_convertor(self, elements: List[HtmlElement]) -> "Selectors": + def __elements_convertor(self, elements: List[HtmlElement | _ElementUnicodeResult]) -> "Selectors": return Selectors(map(self.__element_convertor, elements)) - def __handle_elements( - self, result: List[HtmlElement | _ElementUnicodeResult] - ) -> Union["Selectors", "TextHandlers"]: - """Used internally in all functions to convert results to type (Selectors|TextHandlers) in bulk when possible""" + def __handle_elements(self, result: List[HtmlElement | _ElementUnicodeResult]) -> "Selectors": + """Used internally in all functions to convert results to Selectors in bulk""" if not result: return Selectors() - # From within the code, this method will always get a list of the same type, - # so we will continue without checks for a slight performance boost - if self._is_text_node(result[0]): - return TextHandlers(map(TextHandler, result)) - return self.__elements_convertor(result) def __getstate__(self) -> Any: @@ -264,6 +274,8 @@ class Selector(SelectorsGeneration): @property def tag(self) -> str: """Get the tag name of the element""" + if self._is_text_node(self._root): + return "#text" if not self.__tag: self.__tag = self._root.tag return self.__tag @@ -271,6 +283,8 @@ class Selector(SelectorsGeneration): @property def text(self) -> TextHandler: """Get text content of the element""" + if self._is_text_node(self._root): + return TextHandler(str(self._root)) if self.__text is None: # If you want to escape lxml default behavior and remove comments like this `CONDITION: Excellent` # before extracting text, then keep `keep_comments` set to False while initializing the first class @@ -296,6 +310,9 @@ class Selector(SelectorsGeneration): :return: A TextHandler """ + if self._is_text_node(self._root): + return TextHandler(str(self._root)) + ignored_elements = set() if ignore_tags: for element in self._root.iter(*ignore_tags): @@ -320,6 +337,8 @@ class Selector(SelectorsGeneration): @property def attrib(self) -> AttributesHandler: """Get attributes of the element""" + if self._is_text_node(self._root): + return AttributesHandler({}) if not self.__attributes: self.__attributes = AttributesHandler(self._root.attrib) return self.__attributes @@ -327,6 +346,8 @@ class Selector(SelectorsGeneration): @property def html_content(self) -> TextHandler: """Return the inner HTML code of the element""" + if self._is_text_node(self._root): + return TextHandler(str(self._root)) content = tostring(self._root, encoding=self.encoding, method="html", with_tail=False) if isinstance(content, bytes): content = content.strip().decode(self.encoding) @@ -335,10 +356,14 @@ class Selector(SelectorsGeneration): @property def body(self) -> str | bytes: """Return the raw body of the current `Selector` without any processing. Useful for binary and non-HTML requests.""" + if self._is_text_node(self._root): + return "" return self._raw_body def prettify(self) -> TextHandler: """Return a prettified version of the element's inner html-code""" + if self._is_text_node(self._root): + return TextHandler(str(self._root)) content = tostring( self._root, encoding=self.encoding, @@ -355,6 +380,8 @@ class Selector(SelectorsGeneration): :param class_name: The class name to check for :return: True if element has class with that name otherwise False """ + if self._is_text_node(self._root): + return False return class_name in self._root.classes @property @@ -366,12 +393,16 @@ class Selector(SelectorsGeneration): @property def below_elements(self) -> "Selectors": """Return all elements under the current element in the DOM tree""" + if self._is_text_node(self._root): + return Selectors() below = _find_all_elements(self._root) return self.__elements_convertor(below) if below is not None else Selectors() @property def children(self) -> "Selectors": """Return the children elements of the current element or empty list otherwise""" + if self._is_text_node(self._root): + return Selectors() return Selectors( self.__element_convertor(child) for child in self._root.iterchildren() @@ -387,6 +418,8 @@ class Selector(SelectorsGeneration): def iterancestors(self) -> Generator["Selector", None, None]: """Return a generator that loops over all ancestors of the element, starting with the element's parent.""" + if self._is_text_node(self._root): + return for ancestor in self._root.iterancestors(): yield self.__element_convertor(ancestor) @@ -409,6 +442,8 @@ class Selector(SelectorsGeneration): @property def next(self) -> Optional["Selector"]: """Returns the next element of the current element in the children of the parent or ``None`` otherwise.""" + if self._is_text_node(self._root): + return None next_element = self._root.getnext() while next_element is not None and isinstance(next_element, html_forbidden): # Ignore HTML comments and unwanted types @@ -419,6 +454,8 @@ class Selector(SelectorsGeneration): @property def previous(self) -> Optional["Selector"]: """Returns the previous element of the current element in the children of the parent or ``None`` otherwise.""" + if self._is_text_node(self._root): + return None prev_element = self._root.getprevious() while prev_element is not None and isinstance(prev_element, html_forbidden): # Ignore HTML comments and unwanted types @@ -426,26 +463,40 @@ class Selector(SelectorsGeneration): return self.__element_convertor(prev_element) if prev_element is not None else None - # For easy copy-paste from Scrapy/parsel code when needed :) - def get(self, default=None): # pyright: ignore - return self + def get(self) -> TextHandler: + """ + Serialize this element to a string. + For text nodes, returns the text value. For HTML elements, returns the outer HTML. + """ + if self._is_text_node(self._root): + return TextHandler(str(self._root)) + return self.html_content - def get_all(self): - return self + def getall(self) -> TextHandlers: + """Return a single-element list containing this element's serialized string.""" + return TextHandlers([self.get()]) - extract = get_all + extract = getall extract_first = get def __str__(self) -> str: + if self._is_text_node(self._root): + return str(self._root) return self.html_content def __repr__(self) -> str: length_limit = 40 - data = "<" + + if self._is_text_node(self._root): + text = str(self._root) + if len(text) > length_limit: + text = text[:length_limit].strip() + "..." + return f"" + content = clean_spaces(self.html_content) if len(content) > length_limit: content = content[:length_limit].strip() + "..." - data += f"data='{content}'" + data = f" Union["Selector", "TextHandler", None]: - """Search the current tree with CSS3 selectors and return the first result if possible, otherwise return `None` - - **Important: - It's recommended to use the identifier argument if you plan to use a different selector later - and want to relocate the same element(s)** - - :param selector: The CSS3 selector to be used. - :param adaptive: Enabled will make the function try to relocate the element if it was 'saved' before - :param identifier: A string that will be used to save/retrieve element's data in adaptive, - otherwise the selector will be used. - :param auto_save: Automatically save new elements for `adaptive` later - :param percentage: The minimum percentage to accept while `adaptive` is working and not going lower than that. - Be aware that the percentage calculation depends solely on the page structure, so don't play with this - number unless you must know what you are doing! - """ - for element in self.css( - selector, - identifier, - adaptive, - auto_save, - percentage, - _scrapling_first_match=True, - ): - return element - return None - - def xpath_first( - self, - selector: str, - identifier: str = "", - adaptive: bool = False, - auto_save: bool = False, - percentage: int = 0, - **kwargs: Any, - ) -> Union["Selector", "TextHandler", None]: - """Search the current tree with XPath selectors and return the first result if possible, otherwise return `None` - - **Important: - It's recommended to use the identifier argument if you plan to use a different selector later - and want to relocate the same element(s)** - - Note: **Additional keyword arguments will be passed as XPath variables in the XPath expression!** - - :param selector: The XPath selector to be used. - :param adaptive: Enabled will make the function try to relocate the element if it was 'saved' before - :param identifier: A string that will be used to save/retrieve element's data in adaptive, - otherwise the selector will be used. - :param auto_save: Automatically save new elements for `adaptive` later - :param percentage: The minimum percentage to accept while `adaptive` is working and not going lower than that. - Be aware that the percentage calculation depends solely on the page structure, so don't play with this - number unless you must know what you are doing! - """ - for element in self.xpath( - selector, - identifier, - adaptive, - auto_save, - percentage, - _scrapling_first_match=True, - **kwargs, - ): - return element - return None - def css( self, selector: str, @@ -591,8 +570,7 @@ class Selector(SelectorsGeneration): adaptive: bool = False, auto_save: bool = False, percentage: int = 0, - **kwargs: Any, - ) -> Union["Selectors", List[Any], "TextHandlers"]: + ) -> "Selectors": """Search the current tree with CSS3 selectors **Important: @@ -610,6 +588,9 @@ class Selector(SelectorsGeneration): :return: `Selectors` class. """ + if self._is_text_node(self._root): + return Selectors() + try: if not self.__adaptive_enabled or "," not in selector: # No need to split selectors in this case, let's save some CPU cycles :) @@ -620,10 +601,9 @@ class Selector(SelectorsGeneration): adaptive, auto_save, percentage, - _scrapling_first_match=kwargs.pop("_scrapling_first_match", False), ) - results = [] + results = Selectors() for single_selector in split_selectors(selector): # I'm doing this only so the `save` function saves data correctly for combined selectors # Like using the ',' to combine two different selectors that point to different elements. @@ -634,10 +614,9 @@ class Selector(SelectorsGeneration): adaptive, auto_save, percentage, - _scrapling_first_match=kwargs.pop("_scrapling_first_match", False), ) - return results + return Selectors(results) except ( SelectorError, SelectorSyntaxError, @@ -652,7 +631,7 @@ class Selector(SelectorsGeneration): auto_save: bool = False, percentage: int = 0, **kwargs: Any, - ) -> Union["Selectors", "TextHandlers"]: + ) -> "Selectors": """Search the current tree with XPath selectors **Important: @@ -672,9 +651,9 @@ class Selector(SelectorsGeneration): :return: `Selectors` class. """ - _first_match = kwargs.pop( - "_scrapling_first_match", False - ) # Used internally only to speed up `css_first` and `xpath_first` + if self._is_text_node(self._root): + return Selectors() + try: if elements := self._root.xpath(selector, **kwargs): if not self.__adaptive_enabled and auto_save: @@ -684,7 +663,7 @@ class Selector(SelectorsGeneration): elif self.__adaptive_enabled and auto_save: self.save(elements[0], identifier or selector) - return self.__handle_elements(elements[0:1] if (_first_match and elements) else elements) + return self.__handle_elements(elements) elif self.__adaptive_enabled: if adaptive: element_data = self.retrieve(identifier or selector) @@ -693,7 +672,7 @@ class Selector(SelectorsGeneration): if elements is not None and auto_save: self.save(elements[0], identifier or selector) - return self.__handle_elements(elements[0:1] if (_first_match and elements) else elements) + return self.__handle_elements(elements) else: if adaptive: log.warning( @@ -704,7 +683,7 @@ class Selector(SelectorsGeneration): "Argument `auto_save` will be ignored because `adaptive` wasn't enabled on initialization. Check docs for more info." ) - return self.__handle_elements(elements[0:1] if (_first_match and elements) else elements) + return self.__handle_elements(elements) except ( SelectorError, @@ -725,6 +704,8 @@ class Selector(SelectorsGeneration): :param kwargs: The attributes you want to filter elements based on it. :return: The `Selectors` object of the elements or empty list """ + if self._is_text_node(self._root): + return Selectors() if not args and not kwargs: raise TypeError("You have to pass something to search with, like tag name(s), tag attributes, or both.") @@ -939,6 +920,8 @@ class Selector(SelectorsGeneration): # Operations on text functions def json(self) -> Dict: """Return JSON response if the response is jsonable otherwise throws error""" + if self._is_text_node(self._root): + return TextHandler(str(self._root)).json() if self._raw_body and isinstance(self._raw_body, (str, bytes)): if isinstance(self._raw_body, str): return TextHandler(self._raw_body).json() @@ -1059,6 +1042,9 @@ class Selector(SelectorsGeneration): :return: A ``Selectors`` container of ``Selector`` objects or empty list """ + if self._is_text_node(self._root): + return Selectors() + # We will use the elements' root from now on to get the speed boost of using Lxml directly root = self._root similar_elements = list() @@ -1103,6 +1089,8 @@ class Selector(SelectorsGeneration): :param case_sensitive: if enabled, the letters case will be taken into consideration :param clean_match: if enabled, this will ignore all whitespaces and consecutive spaces while matching """ + if self._is_text_node(self._root): + return Selectors() results = Selectors() if not case_sensitive: @@ -1147,6 +1135,9 @@ class Selector(SelectorsGeneration): :param case_sensitive: If enabled, the letters case will be taken into consideration in the regex. :param clean_match: If enabled, this will ignore all whitespaces and consecutive spaces while matching. """ + if self._is_text_node(self._root): + return Selectors() + results = Selectors() possible_targets = _find_all_elements_with_spaces(self._root) @@ -1309,31 +1300,33 @@ class Selectors(List[Selector]): """ return self.__class__([element for element in self if func(element)]) - # For easy copy-paste from Scrapy/parsel code when needed :) - def get(self, default=None): - """Returns the first item of the current list + def get(self, default: Optional[TextHandler] = None) -> Union[TextHandler, None]: + """Returns the serialized string of the first element, or ``default`` if empty. :param default: the default value to return if the current list is empty """ - return self[0] if len(self) > 0 else default + for x in self: + return x.get() + return default - def extract(self): - return self + def getall(self) -> TextHandlers: + """Serialize all elements and return as a TextHandlers list.""" + return TextHandlers([x.get() for x in self]) + extract = getall extract_first = get - get_all = extract @property - def first(self): - """Returns the first item of the current list or `None` if the list is empty""" - return self.get() + def first(self) -> Optional[Selector]: + """Returns the first Selector item of the current list or `None` if the list is empty""" + return self[0] if len(self) > 0 else None @property - def last(self): - """Returns the last item of the current list or `None` if the list is empty""" + def last(self) -> Optional[Selector]: + """Returns the last Selector item of the current list or `None` if the list is empty""" return self[-1] if len(self) > 0 else None @property - def length(self): + def length(self) -> int: """Returns the length of the current list""" return len(self) From 9acc8194c52b7fa3369bb6b709dd9b18f5e85875 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Fri, 6 Feb 2026 02:45:13 +0200 Subject: [PATCH 57/80] test: update the tests accordingly --- tests/cli/test_cli.py | 1 - tests/parser/test_general.py | 6 +++--- tests/parser/test_parser_advanced.py | 5 +++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py index e2f86f3..39345d0 100644 --- a/tests/cli/test_cli.py +++ b/tests/cli/test_cli.py @@ -17,7 +17,6 @@ def configure_selector_mock(): mock_response.html_content = "Test content" mock_response.encoding = "utf-8" mock_response.get_all_text.return_value = "Test content" - mock_response.css_first.return_value = mock_response mock_response.css.return_value = [mock_response] return mock_response diff --git a/tests/parser/test_general.py b/tests/parser/test_general.py index e5f8d59..808b65d 100644 --- a/tests/parser/test_general.py +++ b/tests/parser/test_general.py @@ -147,7 +147,7 @@ class TestTextMatching: class TestSimilarElements: def test_finding_similar_products(self, page): """Test finding similar product elements""" - first_product = page.css_first(".product") + first_product = page.css(".product").first similar_products = first_product.find_similar() assert len(similar_products) == 2 @@ -255,7 +255,7 @@ class TestElementNavigation: class TestJSONAndAttributes: def test_json_conversion(self, page): """Test converting content to JSON""" - script_content = page.css("#page-data::text")[0] + script_content = page.css("#page-data::text")[0].get() assert issubclass(type(script_content.sort()), str) page_data = script_content.json() assert page_data["totalProducts"] == 3 @@ -282,7 +282,7 @@ class TestJSONAndAttributes: assert list(key_value[0].keys()) == ["data-id"] # JSON attribute conversion - attr_json = page.css_first("#products").attrib["schema"].json() + attr_json = page.css("#products").first.attrib["schema"].json() assert attr_json == {"jsonable": "data"} assert isinstance(page.css("#products")[0].attrib.json_string, bytes) diff --git a/tests/parser/test_parser_advanced.py b/tests/parser/test_parser_advanced.py index 3ac81cf..57086ba 100644 --- a/tests/parser/test_parser_advanced.py +++ b/tests/parser/test_parser_advanced.py @@ -121,11 +121,12 @@ class TestAdvancedSelectors: # ::text pseudo-element texts = page.css("p::text") assert len(texts) == 2 - assert isinstance(texts[0], TextHandler) + assert isinstance(texts[0], Selector) + assert isinstance(texts[0].get(), TextHandler) # ::attr() pseudo-element attrs = page.css("div::attr(class)") - assert "container" in attrs + assert "container" in attrs.getall() def test_complex_attribute_operations(self, complex_html): """Test complex attribute handling""" From 05f62fba818679ee79d7509536ce44da792362d7 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Fri, 6 Feb 2026 03:14:23 +0200 Subject: [PATCH 58/80] fix(response): Force the body of the response to always be bytes --- scrapling/engines/toolbelt/convertor.py | 8 ++++---- scrapling/engines/toolbelt/custom.py | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/scrapling/engines/toolbelt/convertor.py b/scrapling/engines/toolbelt/convertor.py index 9dff73d..4b4caa2 100644 --- a/scrapling/engines/toolbelt/convertor.py +++ b/scrapling/engines/toolbelt/convertor.py @@ -117,12 +117,12 @@ class ResponseFactory: history = cls._process_response_history(first_response, parser_arguments) try: if "html" in final_response.all_headers().get("content-type", ""): - page_content = cls._get_page_content(page) + page_content = cls._get_page_content(page).encode("utf-8") else: page_content = final_response.body() except Exception as e: # pragma: no cover log.error(f"Error getting page content: {e}") - page_content = "" + page_content = b"" return Response( **{ @@ -254,12 +254,12 @@ class ResponseFactory: history = await cls._async_process_response_history(first_response, parser_arguments) try: if "html" in (await final_response.all_headers()).get("content-type", ""): - page_content = await cls._get_async_page_content(page) + page_content = (await cls._get_async_page_content(page)).encode("utf-8") else: page_content = await final_response.body() except Exception as e: # pragma: no cover log.error(f"Error getting page content in async: {e}") - page_content = "" + page_content = b"" return Response( **{ diff --git a/scrapling/engines/toolbelt/custom.py b/scrapling/engines/toolbelt/custom.py index 29b9e17..58a7485 100644 --- a/scrapling/engines/toolbelt/custom.py +++ b/scrapling/engines/toolbelt/custom.py @@ -14,6 +14,7 @@ from scrapling.core._types import ( Union, Optional, Callable, + Sequence, TYPE_CHECKING, AsyncGenerator, ) @@ -42,6 +43,9 @@ class Response(Selector): meta: Dict[str, Any] | None = None, **selector_config: Any, ): + if isinstance(content, str): + content = content.encode("utf-8") + adaptive_domain: str = cast(str, selector_config.pop("adaptive_domain", "")) self.status = status self.reason = reason @@ -64,6 +68,11 @@ class Response(Selector): self.meta: Dict[str, Any] = meta or {} self.request: Optional["Request"] = None # Will be set by crawler + @property + def body(self) -> bytes: + """Return the raw body of the response as bytes.""" + return cast(bytes, cast(Sequence, self._raw_body)) + def follow( self, url: str, From d00c34ee7f12b933b64c3b713978bab0045afea9 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Fri, 6 Feb 2026 03:19:00 +0200 Subject: [PATCH 59/80] style(parser): Improve the type hint for `find_by_text` and `find_by_regex` --- scrapling/parser.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/scrapling/parser.py b/scrapling/parser.py index 0edaf94..1ae6db1 100644 --- a/scrapling/parser.py +++ b/scrapling/parser.py @@ -1074,6 +1074,26 @@ class Selector(SelectorsGeneration): return Selectors(map(self.__element_convertor, similar_elements)) + @overload + def find_by_text( + self, + text: str, + first_match: Literal[True] = ..., + partial: bool = ..., + case_sensitive: bool = ..., + clean_match: bool = ..., + ) -> "Selector": ... + + @overload + def find_by_text( + self, + text: str, + first_match: Literal[False], + partial: bool = ..., + case_sensitive: bool = ..., + clean_match: bool = ..., + ) -> "Selectors": ... + def find_by_text( self, text: str, @@ -1122,6 +1142,24 @@ class Selector(SelectorsGeneration): return results[0] return results + @overload + def find_by_regex( + self, + query: str | Pattern[str], + first_match: Literal[True] = ..., + case_sensitive: bool = ..., + clean_match: bool = ..., + ) -> "Selector": ... + + @overload + def find_by_regex( + self, + query: str | Pattern[str], + first_match: Literal[False], + case_sensitive: bool = ..., + clean_match: bool = ..., + ) -> "Selectors": ... + def find_by_regex( self, query: str | Pattern[str], From 66476d42be021722b9bd8fe1c7c2ec1054ca1e62 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 01:26:21 +0200 Subject: [PATCH 60/80] feat(browsers): Add option to block requests to specific domains --- scrapling/engines/_browsers/_base.py | 30 ++++++---- scrapling/engines/_browsers/_controllers.py | 8 ++- scrapling/engines/_browsers/_stealth.py | 8 ++- scrapling/engines/_browsers/_types.py | 3 + scrapling/engines/_browsers/_validators.py | 4 ++ scrapling/engines/toolbelt/navigation.py | 66 +++++++++++++++------ scrapling/fetchers/chrome.py | 6 +- scrapling/fetchers/stealth_chrome.py | 2 + 8 files changed, 92 insertions(+), 35 deletions(-) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index 01bced5..8bd442d 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -24,11 +24,16 @@ from scrapling.parser import Selector from scrapling.engines._browsers._page import PageInfo, PagePool from scrapling.engines._browsers._validators import validate, PlaywrightConfig, StealthConfig from scrapling.engines._browsers._config_tools import __default_chrome_useragent__, __default_useragent__ -from scrapling.engines.toolbelt.navigation import construct_proxy_dict, intercept_route, async_intercept_route +from scrapling.engines.toolbelt.navigation import ( + construct_proxy_dict, + create_intercept_handler, + create_async_intercept_handler, +) from scrapling.core._types import ( Any, Dict, List, + Set, Optional, Callable, TYPE_CHECKING, @@ -105,6 +110,7 @@ class SyncSession: timeout: int | float, extra_headers: Optional[Dict[str, str]], disable_resources: bool, + blocked_domains: Optional[Set[str]] = None, context: Optional[BrowserContext] = None, ) -> PageInfo[Page]: # pragma: no cover """Get a new page to use""" @@ -117,9 +123,8 @@ class SyncSession: if extra_headers: page.set_extra_http_headers(extra_headers) - if disable_resources: - page.route("**/*", intercept_route) - + if disable_resources or blocked_domains: + page.route("**/*", create_intercept_handler(disable_resources, blocked_domains)) page_info = self.page_pool.add_page(page) page_info.mark_busy() return page_info @@ -173,6 +178,7 @@ class SyncSession: extra_headers: Optional[Dict[str, str]], disable_resources: bool, proxy: Optional[ProxyType] = None, + blocked_domains: Optional[Set[str]] = None, ) -> Generator["PageInfo[Page]", None, None]: """Acquire a page - either from persistent context or fresh context with proxy.""" if proxy: @@ -184,13 +190,13 @@ class SyncSession: try: context = self._initialize_context(self._config, context) - page_info = self._get_page(timeout, extra_headers, disable_resources, context=context) + page_info = self._get_page(timeout, extra_headers, disable_resources, blocked_domains, context=context) yield page_info finally: context.close() else: # Standard mode: use PagePool with persistent context - page_info = self._get_page(timeout, extra_headers, disable_resources) + page_info = self._get_page(timeout, extra_headers, disable_resources, blocked_domains) try: yield page_info finally: @@ -261,6 +267,7 @@ class AsyncSession: timeout: int | float, extra_headers: Optional[Dict[str, str]], disable_resources: bool, + blocked_domains: Optional[Set[str]] = None, context: Optional[AsyncBrowserContext] = None, ) -> PageInfo[AsyncPage]: # pragma: no cover """Get a new page to use""" @@ -288,8 +295,8 @@ class AsyncSession: if extra_headers: await page.set_extra_http_headers(extra_headers) - if disable_resources: - await page.route("**/*", async_intercept_route) + if disable_resources or blocked_domains: + await page.route("**/*", create_async_intercept_handler(disable_resources, blocked_domains)) return self.page_pool.add_page(page) @@ -342,6 +349,7 @@ class AsyncSession: extra_headers: Optional[Dict[str, str]], disable_resources: bool, proxy: Optional[ProxyType] = None, + blocked_domains: Optional[Set[str]] = None, ) -> AsyncGenerator["PageInfo[AsyncPage]", None]: """Acquire a page - either from persistent context or fresh context with proxy.""" if proxy: @@ -353,13 +361,15 @@ class AsyncSession: try: context = await self._initialize_context(self._config, context) - page_info = await self._get_page(timeout, extra_headers, disable_resources, context=context) + page_info = await self._get_page( + timeout, extra_headers, disable_resources, blocked_domains, context=context + ) yield page_info finally: await context.close() else: # Standard mode: use PagePool with persistent context - page_info = await self._get_page(timeout, extra_headers, disable_resources) + page_info = await self._get_page(timeout, extra_headers, disable_resources, blocked_domains) try: yield page_info finally: diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index b43807c..5f0b247 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -43,6 +43,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -110,6 +111,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): :param extra_headers: A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param wait_selector: Wait for a specific CSS selector to be in a specific state. :param wait_selector_state: The state to wait for the selector given with `wait_selector`. The default state is `attached`. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -138,7 +140,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): proxy = static_proxy with self._page_generator( - params.timeout, params.extra_headers, params.disable_resources, proxy + params.timeout, params.extra_headers, params.disable_resources, proxy, params.blocked_domains ) as page_info: final_response = [None] page = page_info.page @@ -208,6 +210,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -277,6 +280,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): :param extra_headers: A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param wait_selector: Wait for a specific CSS selector to be in a specific state. :param wait_selector_state: The state to wait for the selector given with `wait_selector`. The default state is `attached`. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -306,7 +310,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): proxy = static_proxy async with self._page_generator( - params.timeout, params.extra_headers, params.disable_resources, proxy + params.timeout, params.extra_headers, params.disable_resources, proxy, params.blocked_domains ) as page_info: final_response = [None] page = page_info.page diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 5564376..730cd7e 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -47,6 +47,7 @@ class StealthySession(SyncSession, StealthySessionMixin): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -198,6 +199,7 @@ class StealthySession(SyncSession, StealthySessionMixin): :param extra_headers: A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param wait_selector: Wait for a specific CSS selector to be in a specific state. :param wait_selector_state: The state to wait for the selector given with `wait_selector`. The default state is `attached`. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -227,7 +229,7 @@ class StealthySession(SyncSession, StealthySessionMixin): proxy = static_proxy with self._page_generator( - params.timeout, params.extra_headers, params.disable_resources, proxy + params.timeout, params.extra_headers, params.disable_resources, proxy, params.blocked_domains ) as page_info: final_response = [None] page = page_info.page @@ -302,6 +304,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -454,6 +457,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): :param extra_headers: A dictionary of extra headers to add to the request. _The referer set by the `google_search` argument takes priority over the referer set here if used together._ :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param wait_selector: Wait for a specific CSS selector to be in a specific state. :param wait_selector_state: The state to wait for the selector given with `wait_selector`. The default state is `attached`. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -484,7 +488,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): proxy = static_proxy async with self._page_generator( - params.timeout, params.extra_headers, params.disable_resources, proxy + params.timeout, params.extra_headers, params.disable_resources, proxy, params.blocked_domains ) as page_info: final_response = [None] page = page_info.page diff --git a/scrapling/engines/_browsers/_types.py b/scrapling/engines/_browsers/_types.py index d298248..cd5ea19 100644 --- a/scrapling/engines/_browsers/_types.py +++ b/scrapling/engines/_browsers/_types.py @@ -9,6 +9,7 @@ from curl_cffi.requests import ( from scrapling.core._types import ( Dict, List, + Set, Tuple, Mapping, Optional, @@ -84,6 +85,7 @@ if TYPE_CHECKING: # pragma: no cover cdp_url: Optional[str] useragent: Optional[str] extra_flags: Optional[List[str]] + blocked_domains: Optional[Set[str]] retries: int retry_delay: int | float @@ -99,6 +101,7 @@ if TYPE_CHECKING: # pragma: no cover selector_config: Optional[Dict] extra_headers: Optional[Dict[str, str]] wait_selector_state: SelectorWaitStates + blocked_domains: Optional[Set[str]] proxy: Optional[str | Dict[str, str]] class StealthSession(PlaywrightSession, total=False): diff --git a/scrapling/engines/_browsers/_validators.py b/scrapling/engines/_browsers/_validators.py index 2bda436..af2baef 100644 --- a/scrapling/engines/_browsers/_validators.py +++ b/scrapling/engines/_browsers/_validators.py @@ -10,6 +10,7 @@ from scrapling.core._types import ( Any, Dict, List, + Set, Tuple, Optional, Callable, @@ -83,6 +84,7 @@ class PlaywrightConfig(Struct, kw_only=True, frozen=False, weakref=True): cdp_url: Optional[str] = None useragent: Optional[str] = None extra_flags: Optional[List[str]] = None + blocked_domains: Optional[Set[str]] = None retries: RetriesCount = 3 retry_delay: Seconds = 1 @@ -145,6 +147,7 @@ class _fetch_params: wait_selector_state: SelectorWaitStates network_idle: bool load_dom: bool + blocked_domains: Optional[Set[str]] solve_cloudflare: bool selector_config: Dict @@ -183,6 +186,7 @@ def validate_fetch( # solve_cloudflare defaults to False for models that don't have it (PlaywrightConfig) result.setdefault("solve_cloudflare", False) + result.setdefault("blocked_domains", None) return _fetch_params(**result) diff --git a/scrapling/engines/toolbelt/navigation.py b/scrapling/engines/toolbelt/navigation.py index 1b44f5a..e9e74ae 100644 --- a/scrapling/engines/toolbelt/navigation.py +++ b/scrapling/engines/toolbelt/navigation.py @@ -11,7 +11,7 @@ from msgspec import Struct, structs, convert, ValidationError from playwright.sync_api import Route from scrapling.core.utils import log -from scrapling.core._types import Dict, Tuple +from scrapling.core._types import Dict, Set, Tuple, Optional, Callable from scrapling.engines.constants import DEFAULT_DISABLED_RESOURCES __BYPASSES_DIR__ = Path(__file__).parent / "bypasses" @@ -23,30 +23,58 @@ class ProxyDict(Struct): password: str = "" -def intercept_route(route: Route): - """This is just a route handler, but it drops requests that its type falls in `DEFAULT_DISABLED_RESOURCES` +def create_intercept_handler(disable_resources: bool, blocked_domains: Optional[Set[str]] = None) -> Callable: + """Create a route handler that blocks both resource types and specific domains. - :param route: PlayWright `Route` object of the current page - :return: PlayWright `Route` object + :param disable_resources: Whether to block default resource types. + :param blocked_domains: Set of domain names to block requests to. + :return: A sync route handler function. """ - if route.request.resource_type in DEFAULT_DISABLED_RESOURCES: - log.debug(f'Blocking background resource "{route.request.url}" of type "{route.request.resource_type}"') - route.abort() - else: - route.continue_() + disabled_resources = DEFAULT_DISABLED_RESOURCES if disable_resources else set() + domains = blocked_domains or set() + + def handler(route: Route): + if route.request.resource_type in disabled_resources: + log.debug(f'Blocking background resource "{route.request.url}" of type "{route.request.resource_type}"') + route.abort() + elif domains: + hostname = urlparse(route.request.url).hostname or "" + if any(hostname == d or hostname.endswith("." + d) for d in domains): + log.debug(f'Blocking request to blocked domain "{hostname}" ({route.request.url})') + route.abort() + else: + route.continue_() + else: + route.continue_() + + return handler -async def async_intercept_route(route: async_Route): - """This is just a route handler, but it drops requests that its type falls in `DEFAULT_DISABLED_RESOURCES` +def create_async_intercept_handler(disable_resources: bool, blocked_domains: Optional[Set[str]] = None) -> Callable: + """Create an async route handler that blocks both resource types and specific domains. - :param route: PlayWright `Route` object of the current page - :return: PlayWright `Route` object + :param disable_resources: Whether to block default resource types. + :param blocked_domains: Set of domain names to block requests to. + :return: An async route handler function. """ - if route.request.resource_type in DEFAULT_DISABLED_RESOURCES: - log.debug(f'Blocking background resource "{route.request.url}" of type "{route.request.resource_type}"') - await route.abort() - else: - await route.continue_() + disabled_resources = DEFAULT_DISABLED_RESOURCES if disable_resources else set() + domains = blocked_domains or set() + + async def handler(route: async_Route): + if route.request.resource_type in disabled_resources: + log.debug(f'Blocking background resource "{route.request.url}" of type "{route.request.resource_type}"') + await route.abort() + elif domains: + hostname = urlparse(route.request.url).hostname or "" + if any(hostname == d or hostname.endswith("." + d) for d in domains): + log.debug(f'Blocking request to blocked domain "{hostname}" ({route.request.url})') + await route.abort() + else: + await route.continue_() + else: + await route.continue_() + + return handler def construct_proxy_dict(proxy_string: str | Dict[str, str] | Tuple) -> Dict: diff --git a/scrapling/fetchers/chrome.py b/scrapling/fetchers/chrome.py index 0d50c19..591e5e9 100644 --- a/scrapling/fetchers/chrome.py +++ b/scrapling/fetchers/chrome.py @@ -13,7 +13,8 @@ class DynamicFetcher(BaseFetcher): :param url: Target url. :param headless: Run the browser in headless/hidden (default), or headful/visible mode. - :param disable_resources: Drop requests of unnecessary resources for a speed boost. + :param disable_resources: Drop requests for unnecessary resources for a speed boost. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -55,7 +56,8 @@ class DynamicFetcher(BaseFetcher): :param url: Target url. :param headless: Run the browser in headless/hidden (default), or headful/visible mode. - :param disable_resources: Drop requests of unnecessary resources for a speed boost. + :param disable_resources: Drop requests for unnecessary resources for a speed boost. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. diff --git a/scrapling/fetchers/stealth_chrome.py b/scrapling/fetchers/stealth_chrome.py index 58574d3..6a70246 100644 --- a/scrapling/fetchers/stealth_chrome.py +++ b/scrapling/fetchers/stealth_chrome.py @@ -19,6 +19,7 @@ class StealthyFetcher(BaseFetcher): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. @@ -67,6 +68,7 @@ class StealthyFetcher(BaseFetcher): :param headless: Run the browser in headless/hidden (default), or headful/visible mode. :param disable_resources: Drop requests for unnecessary resources for a speed boost. Requests dropped are of type `font`, `image`, `media`, `beacon`, `object`, `imageset`, `texttrack`, `websocket`, `csp_report`, and `stylesheet`. + :param blocked_domains: A set of domain names to block requests to. Subdomains are also matched (e.g., ``"example.com"`` blocks ``"sub.example.com"`` too). :param useragent: Pass a useragent string to be used. Otherwise the fetcher will generate a real Useragent of the same browser and use it. :param cookies: Set cookies for the next request. :param network_idle: Wait for the page until there are no network connections for at least 500 ms. From 5f557a7f9f0efc66745013a67f37a9cb3f6e68c1 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 01:28:58 +0200 Subject: [PATCH 61/80] test: add tests for the new feature --- tests/fetchers/test_utils.py | 152 ++++++++++++++++++++++++++++++- tests/fetchers/test_validator.py | 22 +++++ 2 files changed, 173 insertions(+), 1 deletion(-) diff --git a/tests/fetchers/test_utils.py b/tests/fetchers/test_utils.py index fea3f3f..9c08f7f 100644 --- a/tests/fetchers/test_utils.py +++ b/tests/fetchers/test_utils.py @@ -4,8 +4,11 @@ from pathlib import Path from scrapling.engines.toolbelt.custom import StatusText, Response from scrapling.engines.toolbelt.navigation import ( construct_proxy_dict, - js_bypass_path + create_intercept_handler, + create_async_intercept_handler, + js_bypass_path, ) +from scrapling.engines.constants import DEFAULT_DISABLED_RESOURCES from scrapling.engines.toolbelt.fingerprints import ( generate_convincing_referer, get_os_name, @@ -300,3 +303,150 @@ class TestResponse: # Should handle 'bytes' content properly assert response.status == 200 + + +class _MockRequest: + """Minimal mock for Playwright's Request object.""" + def __init__(self, url: str, resource_type: str = "document"): + self.url = url + self.resource_type = resource_type + + +class _MockRoute: + """Minimal mock for Playwright's sync Route object.""" + def __init__(self, url: str, resource_type: str = "document"): + self.request = _MockRequest(url, resource_type) + self.aborted = False + self.continued = False + + def abort(self): + self.aborted = True + + def continue_(self): + self.continued = True + + +class _AsyncMockRoute: + """Minimal mock for Playwright's async Route object.""" + def __init__(self, url: str, resource_type: str = "document"): + self.request = _MockRequest(url, resource_type) + self.aborted = False + self.continued = False + + async def abort(self): + self.aborted = True + + async def continue_(self): + self.continued = True + + +class TestCreateInterceptHandler: + """Test the unified sync route handler factory.""" + + def test_blocks_disabled_resource_types(self): + handler = create_intercept_handler(disable_resources=True) + route = _MockRoute("https://example.com/image.png", resource_type="image") + handler(route) + assert route.aborted + + def test_continues_allowed_resource_types(self): + handler = create_intercept_handler(disable_resources=True) + route = _MockRoute("https://example.com/page", resource_type="document") + handler(route) + assert route.continued + + def test_blocks_exact_domain(self): + handler = create_intercept_handler(disable_resources=False, blocked_domains={"ads.example.com"}) + route = _MockRoute("https://ads.example.com/tracker.js") + handler(route) + assert route.aborted + + def test_blocks_subdomain(self): + handler = create_intercept_handler(disable_resources=False, blocked_domains={"example.com"}) + route = _MockRoute("https://sub.example.com/page") + handler(route) + assert route.aborted + + def test_continues_non_blocked_domain(self): + handler = create_intercept_handler(disable_resources=False, blocked_domains={"ads.example.com"}) + route = _MockRoute("https://safe.example.com/page") + handler(route) + assert route.continued + + def test_resource_blocking_takes_priority_over_domain(self): + """When both are active, resource type check comes first.""" + handler = create_intercept_handler(disable_resources=True, blocked_domains={"example.com"}) + route = _MockRoute("https://example.com/style.css", resource_type="stylesheet") + handler(route) + assert route.aborted + + def test_domain_blocking_with_resources_disabled(self): + """Non-blocked resource type from a blocked domain should still be aborted.""" + handler = create_intercept_handler(disable_resources=True, blocked_domains={"tracker.io"}) + route = _MockRoute("https://tracker.io/api", resource_type="document") + handler(route) + assert route.aborted + + def test_no_blocking_continues(self): + handler = create_intercept_handler(disable_resources=False) + route = _MockRoute("https://example.com/page") + handler(route) + assert route.continued + + def test_does_not_block_partial_domain_match(self): + """'example.com' should not block 'notexample.com'.""" + handler = create_intercept_handler(disable_resources=False, blocked_domains={"example.com"}) + route = _MockRoute("https://notexample.com/page") + handler(route) + assert route.continued + + def test_multiple_blocked_domains(self): + handler = create_intercept_handler(disable_resources=False, blocked_domains={"ads.com", "tracker.io"}) + route_ads = _MockRoute("https://ads.com/banner") + route_tracker = _MockRoute("https://cdn.tracker.io/script.js") + route_safe = _MockRoute("https://example.com/page") + handler(route_ads) + handler(route_tracker) + handler(route_safe) + assert route_ads.aborted + assert route_tracker.aborted + assert route_safe.continued + + +class TestCreateAsyncInterceptHandler: + """Test the unified async route handler factory.""" + + @pytest.mark.asyncio + async def test_blocks_disabled_resource_types(self): + handler = create_async_intercept_handler(disable_resources=True) + route = _AsyncMockRoute("https://example.com/font.woff", resource_type="font") + await handler(route) + assert route.aborted + + @pytest.mark.asyncio + async def test_blocks_domain(self): + handler = create_async_intercept_handler(disable_resources=False, blocked_domains={"ads.example.com"}) + route = _AsyncMockRoute("https://ads.example.com/track") + await handler(route) + assert route.aborted + + @pytest.mark.asyncio + async def test_continues_non_blocked(self): + handler = create_async_intercept_handler(disable_resources=False, blocked_domains={"ads.example.com"}) + route = _AsyncMockRoute("https://safe.example.com/page") + await handler(route) + assert route.continued + + @pytest.mark.asyncio + async def test_blocks_subdomain(self): + handler = create_async_intercept_handler(disable_resources=False, blocked_domains={"tracker.io"}) + route = _AsyncMockRoute("https://cdn.tracker.io/script.js") + await handler(route) + assert route.aborted + + @pytest.mark.asyncio + async def test_does_not_block_partial_domain_match(self): + handler = create_async_intercept_handler(disable_resources=False, blocked_domains={"example.com"}) + route = _AsyncMockRoute("https://notexample.com/page") + await handler(route) + assert route.continued diff --git a/tests/fetchers/test_validator.py b/tests/fetchers/test_validator.py index 209fae0..a682f9e 100644 --- a/tests/fetchers/test_validator.py +++ b/tests/fetchers/test_validator.py @@ -77,3 +77,25 @@ class TestValidators: config = validate(params, StealthConfig) assert config.timeout == 60000 # Should be increased + + def test_playwright_config_blocked_domains(self): + """Test PlaywrightConfig with blocked_domains""" + params = {"blocked_domains": {"ads.example.com", "tracker.io"}} + + config = validate(params, PlaywrightConfig) + + assert config.blocked_domains == {"ads.example.com", "tracker.io"} + + def test_playwright_config_blocked_domains_default_none(self): + """Test PlaywrightConfig blocked_domains defaults to None""" + config = validate({}, PlaywrightConfig) + + assert config.blocked_domains is None + + def test_stealth_config_blocked_domains(self): + """Test StealthConfig inherits blocked_domains""" + params = {"blocked_domains": {"ads.example.com"}} + + config = validate(params, StealthConfig) + + assert config.blocked_domains == {"ads.example.com"} From 5ec929435be237daf9622619edcc5bee5bd25f31 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 16:30:00 +0200 Subject: [PATCH 62/80] style: Fix all mypy errors and add type hints to untyped function bodies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Resolved all 65 mypy errors across 14 files and added type annotations to all previously untyped function bodies. Final result: 0 errors with --check-untyped-defs enabled, all 454 tests pass.** `scrapling/core/_types.py` - Removed broken Self = object fallback — now requires typing_extensions for Python < 3.11 `scrapling/core/storage.py` - Fixed str/bytes mismatch in _get_hash() — used separate _identifier_bytes variable instead of reassigning from str to bytes `scrapling/core/custom_types.py` - split() return type: Union[List, "TextHandlers"] → list[Any] (avoids LSP violation with parent list[str]) - format() kwargs: **kwargs: str → **kwargs: object (matches parent str.format signature) - AttributesHandler.__init__: Added mapping: Any = None, **kwargs: Any and -> None - json_string property: Added -> bytes return type `scrapling/core/mixins.py` - Changed self: "Selector" to self: Any on all mixin methods (mypy can't handle forward-reference self types on non-subclass mixins) - Added Dict[str, int] annotation for counter variable - Removed unused TYPE_CHECKING / Selector imports `scrapling/parser.py (~30 errors)` - Added body: str | bytes pre-annotation for dual-type if/elif assignment - Used Dict[str, Any] kwargs dict for HTMLParser(...) to bypass incomplete lxml stubs missing default_doctype - Changed base_url=url or None → base_url=url or "" (avoids str | None vs str | bytes) - bool(adaptive) to guarantee bool type for __adaptive_enabled - Declared __text: Optional[TextHandler], __tag: Optional[str], __attributes: Optional[AttributesHandler] at top of __init__ - cast(List, ...) for all XPath() call results (_find_all_elements, _find_all_elements_with_spaces) - Added Dict[float, List[Any]] for score_table, Dict[str, Any] for attributes - Changed score, checks = 0, 0 → score: float = 0; checks: int = 0 (two locations) - Renamed target → target_element in save() to avoid variable redefinition with different types - Wrapped node_text.clean() / .lower() in TextHandler(...) to preserve type `scrapling/engines/_browsers/_page.py` - Added PageInfo[SyncPage] | PageInfo[AsyncPage] union type annotation to page_info variable `scrapling/engines/_browsers/_validators.py` - Convert method_kwargs (TypedDict) to plain Dict[str, Any] before dynamic key access `scrapling/engines/_browsers/_base.py` - Added _config declaration to BaseSessionMixin - Used cast(StealthConfig, self._config) in __generate_stealth_options to access stealth-only attributes - Added Tuple[str, ...] annotation for flags - Removed redundant narrower StealthConfig type annotation on self._config in StealthySessionMixin.__validate__ - Widened SyncSession and AsyncSession fields (playwright, context, browser) to Any to support both playwright and patchright types - Added -> None to both start() methods `scrapling/engines/_browsers/_stealth.py` - Added Optional, ProxyType imports - Annotated proxy: Optional[ProxyType] in both sync/async fetch loops - Annotated outer_box: Any at first declaration, removed duplicate type annotations in subsequent branches - Added -> None to sync and async start() - Added config: Any parameter type to _initialize_context - Removed redundant self.context: AsyncBrowserContext re-annotations in conditional branches `scrapling/engines/_browsers/_controllers.py` - Added Optional, ProxyType imports - Annotated proxy: Optional[ProxyType] in both sync/async fetch loops - Added -> None to async start() - Removed redundant self.context: AsyncBrowserContext re-annotations `scrapling/spiders/request.py` - Added Optional import, typed _fp: Optional[bytes] = None - Removed redundant body: bytes re-annotation `scrapling/spiders/session.py` - Used separate client variable instead of reassigning session = session._client (avoids type incompatibility and fixes a bug where session._make_request was called instead of client._make_request) - Added -> None to SessionManager.__init__ `scrapling/engines/toolbelt/convertor.py` - Added list[Response] annotation for history in both sync/async methods `scrapling/engines/static.py` - FetcherClient.__init__ and AsyncFetcherClient.__init__: Added **kwargs: Any and -> None `scrapling/core/shell.py` - Wrapped re_sub(...) result in TextHandler(...) to maintain correct type - Added -> None to CurlParser.__init__ - Added full type signature to create_wrapper, replaced wrapper.__signature__ = ... with setattr(wrapper, "__signature__", ...) to satisfy mypy - Added Callable to imports --- scrapling/core/_types.py | 22 +----- scrapling/core/custom_types.py | 12 ++- scrapling/core/mixins.py | 21 ++--- scrapling/core/shell.py | 15 ++-- scrapling/core/storage.py | 9 +-- scrapling/engines/_browsers/_base.py | 38 ++++----- scrapling/engines/_browsers/_controllers.py | 13 ++-- scrapling/engines/_browsers/_page.py | 4 +- scrapling/engines/_browsers/_stealth.py | 28 +++---- scrapling/engines/_browsers/_validators.py | 9 ++- scrapling/engines/static.py | 4 +- scrapling/engines/toolbelt/convertor.py | 6 +- scrapling/parser.py | 85 ++++++++++----------- scrapling/spiders/request.py | 6 +- scrapling/spiders/session.py | 10 +-- 15 files changed, 133 insertions(+), 149 deletions(-) diff --git a/scrapling/core/_types.py b/scrapling/core/_types.py index f19e706..f2fc097 100644 --- a/scrapling/core/_types.py +++ b/scrapling/core/_types.py @@ -32,6 +32,7 @@ from typing import ( Coroutine, SupportsIndex, ) +from typing_extensions import Self, Unpack # Proxy can be a string URL or a dict (Playwright format: {"server": "...", "username": "...", "password": "..."}) ProxyType = Union[str, Dict[str, str]] @@ -41,27 +42,6 @@ PageLoadStates = Literal["commit", "domcontentloaded", "load", "networkidle"] extraction_types = Literal["text", "html", "markdown"] StrOrBytes = Union[str, bytes] -if TYPE_CHECKING: # pragma: no cover - from typing_extensions import Unpack -else: # pragma: no cover - - class _Unpack: - @staticmethod - def __getitem__(*args, **kwargs): - pass - - Unpack = _Unpack() - - -try: - # Python 3.11+ - from typing import Self # novermin -except ImportError: # pragma: no cover - try: - from typing_extensions import Self # Backport - except ImportError: - Self = object - # Copied from `playwright._impl._api_structures.SetCookieParam` class SetCookieParam(TypedDict, total=False): diff --git a/scrapling/core/custom_types.py b/scrapling/core/custom_types.py index 45ab4d5..d06ac29 100644 --- a/scrapling/core/custom_types.py +++ b/scrapling/core/custom_types.py @@ -35,9 +35,7 @@ class TextHandler(str): lst = super().__getitem__(key) return TextHandler(lst) - def split( - self, sep: str | None = None, maxsplit: SupportsIndex = -1 - ) -> Union[List, "TextHandlers"]: # pragma: no cover + def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[Any]: # pragma: no cover return TextHandlers([TextHandler(s) for s in super().split(sep, maxsplit)]) def strip(self, chars: str | None = None) -> Union[str, "TextHandler"]: # pragma: no cover @@ -61,7 +59,7 @@ class TextHandler(str): def expandtabs(self, tabsize: SupportsIndex = 8) -> Union[str, "TextHandler"]: # pragma: no cover return TextHandler(super().expandtabs(tabsize)) - def format(self, *args: object, **kwargs: str) -> Union[str, "TextHandler"]: # pragma: no cover + def format(self, *args: object, **kwargs: object) -> Union[str, "TextHandler"]: # pragma: no cover return TextHandler(super().format(*args, **kwargs)) def format_map(self, mapping) -> Union[str, "TextHandler"]: # pragma: no cover @@ -291,7 +289,7 @@ class AttributesHandler(Mapping[str, _TextHandlerType]): __slots__ = ("_data",) - def __init__(self, mapping=None, **kwargs): + def __init__(self, mapping: Any = None, **kwargs: Any) -> None: mapping = ( {key: TextHandler(value) if isinstance(value, str) else value for key, value in mapping.items()} if mapping is not None @@ -324,8 +322,8 @@ class AttributesHandler(Mapping[str, _TextHandlerType]): yield AttributesHandler({key: value}) @property - def json_string(self): - """Convert current attributes to JSON string if the attributes are JSON serializable otherwise throws error""" + def json_string(self) -> bytes: + """Convert current attributes to JSON bytes if the attributes are JSON serializable otherwise throws error""" return dumps(dict(self._data)) def __getitem__(self, key: str) -> _TextHandlerType: diff --git a/scrapling/core/mixins.py b/scrapling/core/mixins.py index 0b66c07..c2e7420 100644 --- a/scrapling/core/mixins.py +++ b/scrapling/core/mixins.py @@ -1,7 +1,4 @@ -from scrapling.core._types import TYPE_CHECKING - -if TYPE_CHECKING: - from scrapling.parser import Selector +from scrapling.core._types import Any, Dict class SelectorsGeneration: @@ -11,7 +8,11 @@ class SelectorsGeneration: Inspiration: https://searchfox.org/mozilla-central/source/devtools/shared/inspector/css-logic.js#591 """ - def _general_selection(self: "Selector", selection: str = "css", full_path: bool = False) -> str: # type: ignore[name-defined] + # Note: This is a mixin class meant to be used with Selector. + # The methods access Selector attributes (._root, .parent, .attrib, .tag, etc.) + # through self, which will be a Selector instance at runtime. + + def _general_selection(self: Any, selection: str = "css", full_path: bool = False) -> str: """Generate a selector for the current element. :return: A string of the generated selector. """ @@ -36,7 +37,7 @@ class SelectorsGeneration: # if classes and css: # part += f".{'.'.join(classes)}" # else: - counter = {} + counter: Dict[str, int] = {} for child in target.parent.children: counter.setdefault(child.tag, 0) counter[child.tag] += 1 @@ -56,28 +57,28 @@ class SelectorsGeneration: return " > ".join(reversed(selectorPath)) if css else "//" + "/".join(reversed(selectorPath)) @property - def generate_css_selector(self: "Selector") -> str: # type: ignore[name-defined] + def generate_css_selector(self: Any) -> str: """Generate a CSS selector for the current element :return: A string of the generated selector. """ return self._general_selection() @property - def generate_full_css_selector(self: "Selector") -> str: # type: ignore[name-defined] + def generate_full_css_selector(self: Any) -> str: """Generate a complete CSS selector for the current element :return: A string of the generated selector. """ return self._general_selection(full_path=True) @property - def generate_xpath_selector(self: "Selector") -> str: # type: ignore[name-defined] + def generate_xpath_selector(self: Any) -> str: """Generate an XPath selector for the current element :return: A string of the generated selector. """ return self._general_selection("xpath") @property - def generate_full_xpath_selector(self: "Selector") -> str: # type: ignore[name-defined] + def generate_full_xpath_selector(self: Any) -> str: """Generate a complete XPath selector for the current element :return: A string of the generated selector. """ diff --git a/scrapling/core/shell.py b/scrapling/core/shell.py index 3a1511e..0bd6efc 100644 --- a/scrapling/core/shell.py +++ b/scrapling/core/shell.py @@ -30,6 +30,7 @@ from scrapling.core.custom_types import TextHandler from scrapling.engines.toolbelt.custom import Response from scrapling.core.utils._shell import _ParseHeaders, _CookieParser from scrapling.core._types import ( + Callable, Dict, Any, cast, @@ -82,7 +83,7 @@ class NoExitArgumentParser(ArgumentParser): # pragma: no cover class CurlParser: """Builds the argument parser for relevant curl flags from DevTools.""" - def __init__(self): + def __init__(self) -> None: from scrapling.fetchers import Fetcher as __Fetcher self.__fetcher = __Fetcher @@ -467,19 +468,21 @@ Type 'exit' or press Ctrl+D to exit. return result - def create_wrapper(self, func, get_signature=True, signature_name=None): + def create_wrapper( + self, func: Callable, get_signature: bool = True, signature_name: Optional[str] = None + ) -> Callable: """Create a wrapper that preserves function signature but updates page""" @wraps(func) - def wrapper(*args, **kwargs): + def wrapper(*args: Any, **kwargs: Any) -> Any: result = func(*args, **kwargs) return self.update_page(result) if get_signature: # Explicitly preserve and unpack signature for IPython introspection and autocompletion - wrapper.__signature__ = _unpack_signature(func, signature_name) # pyright: ignore + setattr(wrapper, "__signature__", _unpack_signature(func, signature_name)) else: - wrapper.__signature__ = signature(func) # pyright: ignore + setattr(wrapper, "__signature__", signature(func)) return wrapper @@ -601,7 +604,7 @@ class Convertor: " ", ): # Remove consecutive white-spaces - txt_content = re_sub(f"[{s}]+", s, txt_content) + txt_content = TextHandler(re_sub(f"[{s}]+", s, txt_content)) yield txt_content yield "" diff --git a/scrapling/core/storage.py b/scrapling/core/storage.py index 8e04599..d93a320 100644 --- a/scrapling/core/storage.py +++ b/scrapling/core/storage.py @@ -63,12 +63,11 @@ class StorageSystemMixin(ABC): # pragma: no cover def _get_hash(identifier: str) -> str: """If you want to hash identifier in your storage system, use this safer""" _identifier = identifier.lower().strip() - if isinstance(_identifier, str): - # Hash functions have to take bytes - _identifier = _identifier.encode("utf-8") + # Hash functions have to take bytes + _identifier_bytes = _identifier.encode("utf-8") - hash_value = sha256(_identifier).hexdigest() - return f"{hash_value}_{len(_identifier)}" # Length to reduce collision chance + hash_value = sha256(_identifier_bytes).hexdigest() + return f"{hash_value}_{len(_identifier_bytes)}" # Length to reduce collision chance @lru_cache(1, typed=True) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index 8bd442d..e379882 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -5,16 +5,12 @@ from contextlib import contextmanager, asynccontextmanager from playwright.sync_api._generated import Page from playwright.sync_api import ( Frame, - Browser, BrowserContext, - Playwright, Response as SyncPlaywrightResponse, ) from playwright.async_api._generated import Page as AsyncPage from playwright.async_api import ( Frame as AsyncFrame, - Browser as AsyncBrowser, - Playwright as AsyncPlaywright, Response as AsyncPlaywrightResponse, BrowserContext as AsyncBrowserContext, ) @@ -37,6 +33,7 @@ from scrapling.core._types import ( Optional, Callable, TYPE_CHECKING, + cast, overload, Tuple, ProxyType, @@ -61,12 +58,12 @@ class SyncSession: self.max_pages = max_pages self.page_pool = PagePool(max_pages) self._max_wait_for_page = 60 - self.playwright: Playwright | Any = None - self.context: BrowserContext | Any = None - self.browser: Optional[Browser] = None + self.playwright: Any = None + self.context: Any = None + self.browser: Any = None self._is_alive = False - def start(self): + def start(self) -> None: pass def close(self): # pragma: no cover @@ -215,13 +212,13 @@ class AsyncSession: self.max_pages = max_pages self.page_pool = PagePool(max_pages) self._max_wait_for_page = 60 - self.playwright: AsyncPlaywright | Any = None - self.context: AsyncBrowserContext | Any = None - self.browser: Optional[AsyncBrowser] = None + self.playwright: Any = None + self.context: Any = None + self.browser: Any = None self._is_alive = False self._lock = Lock() - async def start(self): + async def start(self) -> None: pass async def close(self): @@ -378,6 +375,8 @@ class AsyncSession: class BaseSessionMixin: + _config: "PlaywrightConfig | StealthConfig" + @overload def __validate_routine__(self, params: Dict, model: type[StealthConfig]) -> StealthConfig: ... @@ -404,7 +403,7 @@ class BaseSessionMixin: return config def __generate_options__(self, extra_flags: Tuple | None = None) -> None: - config: PlaywrightConfig | StealthConfig = self._config # type: ignore[has-type] + config: PlaywrightConfig | StealthConfig = self._config self._context_options.update( { "proxy": config.proxy, @@ -466,7 +465,7 @@ class DynamicSessionMixin(BaseSessionMixin): class StealthySessionMixin(BaseSessionMixin): def __validate__(self, **params): - self._config: StealthConfig = self.__validate_routine__(params, model=StealthConfig) + self._config = self.__validate_routine__(params, model=StealthConfig) self._context_options.update( { "is_mobile": False, @@ -482,22 +481,23 @@ class StealthySessionMixin(BaseSessionMixin): self.__generate_stealth_options() def __generate_stealth_options(self) -> None: - flags = tuple() - if not self._config.cdp_url: + config = cast(StealthConfig, self._config) + flags: Tuple[str, ...] = tuple() + if not config.cdp_url: flags = DEFAULT_FLAGS + DEFAULT_STEALTH_FLAGS - if self._config.block_webrtc: + if config.block_webrtc: flags += ( "--webrtc-ip-handling-policy=disable_non_proxied_udp", "--force-webrtc-ip-handling-policy", # Ensures the policy is enforced ) - if not self._config.allow_webgl: + if not config.allow_webgl: flags += ( "--disable-webgl", "--disable-webgl-image-chromium", "--disable-webgl2", ) - if self._config.hide_canvas: + if config.hide_canvas: flags += ("--fingerprinting-canvas-image-data-noise",) super(StealthySessionMixin, self).__generate_options__(flags) diff --git a/scrapling/engines/_browsers/_controllers.py b/scrapling/engines/_browsers/_controllers.py index 5f0b247..5d9e801 100644 --- a/scrapling/engines/_browsers/_controllers.py +++ b/scrapling/engines/_browsers/_controllers.py @@ -8,11 +8,10 @@ from playwright.sync_api import ( from playwright.async_api import ( async_playwright, Locator as AsyncLocator, - BrowserContext as AsyncBrowserContext, ) from scrapling.core.utils import log -from scrapling.core._types import Unpack +from scrapling.core._types import Optional, ProxyType, Unpack from scrapling.engines.toolbelt.proxy_rotation import is_proxy_error from scrapling.engines.toolbelt.convertor import Response, ResponseFactory from scrapling.engines.toolbelt.fingerprints import generate_convincing_referer @@ -134,6 +133,7 @@ class DynamicSession(SyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): + proxy: Optional[ProxyType] = None if self._config.proxy_rotator and static_proxy is None: proxy = self._config.proxy_rotator.get_proxy() else: @@ -238,7 +238,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): self.__validate__(**kwargs) super().__init__(max_pages=self._config.max_pages) - async def start(self): + async def start(self) -> None: """Create a browser for this instance and context.""" if not self.playwright: self.playwright = await async_playwright().start() @@ -246,16 +246,14 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): if self._config.cdp_url: self.browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) if not self._config.proxy_rotator and self.browser: - self.context: AsyncBrowserContext = await self.browser.new_context(**self._context_options) + self.context = await self.browser.new_context(**self._context_options) elif self._config.proxy_rotator: self.browser = await self.playwright.chromium.launch(**self._browser_options) else: persistent_options = ( self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} ) - self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **persistent_options - ) + self.context = await self.playwright.chromium.launch_persistent_context(**persistent_options) if self.context: self.context = await self._initialize_context(self._config, self.context) @@ -304,6 +302,7 @@ class AsyncDynamicSession(AsyncSession, DynamicSessionMixin): ) for attempt in range(self._config.retries): + proxy: Optional[ProxyType] = None if self._config.proxy_rotator and static_proxy is None: proxy = self._config.proxy_rotator.get_proxy() else: diff --git a/scrapling/engines/_browsers/_page.py b/scrapling/engines/_browsers/_page.py index 655d3d1..481016e 100644 --- a/scrapling/engines/_browsers/_page.py +++ b/scrapling/engines/_browsers/_page.py @@ -61,7 +61,9 @@ class PagePool: raise RuntimeError(f"Maximum page limit ({self.max_pages}) reached") if isinstance(page, AsyncPage): - page_info = cast(PageInfo[AsyncPage], PageInfo(page, "ready", "")) + page_info: PageInfo[SyncPage] | PageInfo[AsyncPage] = cast( + PageInfo[AsyncPage], PageInfo(page, "ready", "") + ) else: page_info = cast(PageInfo[SyncPage], PageInfo(page, "ready", "")) diff --git a/scrapling/engines/_browsers/_stealth.py b/scrapling/engines/_browsers/_stealth.py index 730cd7e..3c9ea58 100644 --- a/scrapling/engines/_browsers/_stealth.py +++ b/scrapling/engines/_browsers/_stealth.py @@ -13,7 +13,7 @@ from patchright.sync_api import sync_playwright from patchright.async_api import async_playwright from scrapling.core.utils import log -from scrapling.core._types import Any, Unpack +from scrapling.core._types import Any, Optional, ProxyType, Unpack from scrapling.engines.toolbelt.proxy_rotation import is_proxy_error from scrapling.engines.toolbelt.convertor import Response, ResponseFactory from scrapling.engines.toolbelt.fingerprints import generate_convincing_referer @@ -78,7 +78,7 @@ class StealthySession(SyncSession, StealthySessionMixin): self.__validate__(**kwargs) super().__init__() - def start(self): + def start(self) -> None: """Create a browser for this instance and context.""" if not self.playwright: self.playwright = sync_playwright().start() @@ -146,7 +146,7 @@ class StealthySession(SyncSession, StealthySessionMixin): # Waiting for the verify spinner to disappear, checking every 1s if it disappeared page.wait_for_timeout(500) - outer_box = {} + outer_box: Any = {} iframe = page.frame(url=__CF_PATTERN__) if iframe is not None: self._wait_for_page_stability(iframe, True, False) @@ -156,14 +156,14 @@ class StealthySession(SyncSession, StealthySessionMixin): # Double-checking that the iframe is loaded page.wait_for_timeout(500) - outer_box: Any = iframe.frame_element().bounding_box() + outer_box = iframe.frame_element().bounding_box() if not iframe or not outer_box: if "Just a moment..." not in (ResponseFactory._get_page_content(page)): log.info("Cloudflare captcha is solved") return - outer_box: Any = page.locator(box_selector).last.bounding_box() + outer_box = page.locator(box_selector).last.bounding_box() # Calculate the Captcha coordinates for any viewport captcha_x, captcha_y = outer_box["x"] + randint(26, 28), outer_box["y"] + randint(25, 27) @@ -223,6 +223,7 @@ class StealthySession(SyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): + proxy: Optional[ProxyType] = None if self._config.proxy_rotator and static_proxy is None: proxy = self._config.proxy_rotator.get_proxy() else: @@ -335,7 +336,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): self.__validate__(**kwargs) super().__init__(max_pages=self._config.max_pages) - async def start(self): + async def start(self) -> None: """Create a browser for this instance and context.""" if not self.playwright: self.playwright = await async_playwright().start() @@ -344,16 +345,14 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): self.browser = await self.playwright.chromium.connect_over_cdp(endpoint_url=self._config.cdp_url) if not self._config.proxy_rotator: assert self.browser is not None - self.context: AsyncBrowserContext = await self.browser.new_context(**self._context_options) + self.context = await self.browser.new_context(**self._context_options) elif self._config.proxy_rotator: self.browser = await self.playwright.chromium.launch(**self._browser_options) else: persistent_options = ( self._browser_options | self._context_options | {"user_data_dir": self._user_data_dir} ) - self.context: AsyncBrowserContext = await self.playwright.chromium.launch_persistent_context( - **persistent_options - ) + self.context = await self.playwright.chromium.launch_persistent_context(**persistent_options) if self.context: self.context = await self._initialize_context(self._config, self.context) @@ -367,7 +366,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): else: raise RuntimeError("Session has been already started") - async def _initialize_context(self, config, ctx: AsyncBrowserContext) -> AsyncBrowserContext: + async def _initialize_context(self, config: Any, ctx: AsyncBrowserContext) -> AsyncBrowserContext: """Initialize the browser context.""" for script in _compiled_stealth_scripts(): await ctx.add_init_script(script=script) @@ -404,7 +403,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): # Waiting for the verify spinner to disappear, checking every 1s if it disappeared await page.wait_for_timeout(500) - outer_box = {} + outer_box: Any = {} iframe = page.frame(url=__CF_PATTERN__) if iframe is not None: await self._wait_for_page_stability(iframe, True, False) @@ -414,14 +413,14 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): # Double-checking that the iframe is loaded await page.wait_for_timeout(500) - outer_box: Any = await (await iframe.frame_element()).bounding_box() + outer_box = await (await iframe.frame_element()).bounding_box() if not iframe or not outer_box: if "Just a moment..." not in (await ResponseFactory._get_async_page_content(page)): log.info("Cloudflare captcha is solved") return - outer_box: Any = await page.locator(box_selector).last.bounding_box() + outer_box = await page.locator(box_selector).last.bounding_box() # Calculate the Captcha coordinates for any viewport captcha_x, captcha_y = outer_box["x"] + randint(26, 28), outer_box["y"] + randint(25, 27) @@ -482,6 +481,7 @@ class AsyncStealthySession(AsyncSession, StealthySessionMixin): ) for attempt in range(self._config.retries): + proxy: Optional[ProxyType] = None if self._config.proxy_rotator and static_proxy is None: proxy = self._config.proxy_rotator.get_proxy() else: diff --git a/scrapling/engines/_browsers/_validators.py b/scrapling/engines/_browsers/_validators.py index af2baef..e2424f4 100644 --- a/scrapling/engines/_browsers/_validators.py +++ b/scrapling/engines/_browsers/_validators.py @@ -157,15 +157,16 @@ def validate_fetch( session: Any, model: type[PlaywrightConfig] | type[StealthConfig], ) -> _fetch_params: # pragma: no cover - result = {} - overrides = {} + result: Dict[str, Any] = {} + overrides: Dict[str, Any] = {} + kwargs_dict: Dict[str, Any] = dict(method_kwargs) # Get all field names that _fetch_params needs fetch_param_fields = {f.name for f in fields(_fetch_params)} for key in fetch_param_fields: - if key in method_kwargs: - overrides[key] = method_kwargs[key] + if key in kwargs_dict: + overrides[key] = kwargs_dict[key] elif hasattr(session, "_config") and hasattr(session._config, key): result[key] = getattr(session._config, key) diff --git a/scrapling/engines/static.py b/scrapling/engines/static.py index 884fe0c..204c105 100644 --- a/scrapling/engines/static.py +++ b/scrapling/engines/static.py @@ -753,7 +753,7 @@ class FetcherSession: class FetcherClient(_SyncSessionLogic): __slots__ = ("__enter__", "__exit__") - def __init__(self, **kwargs): + def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) self.__enter__: Any = None self.__exit__: Any = None @@ -763,7 +763,7 @@ class FetcherClient(_SyncSessionLogic): class AsyncFetcherClient(_ASyncSessionLogic): __slots__ = ("__aenter__", "__aexit__") - def __init__(self, **kwargs): + def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) self.__aenter__: Any = None self.__aexit__: Any = None diff --git a/scrapling/engines/toolbelt/convertor.py b/scrapling/engines/toolbelt/convertor.py index 4b4caa2..1a8d799 100644 --- a/scrapling/engines/toolbelt/convertor.py +++ b/scrapling/engines/toolbelt/convertor.py @@ -38,7 +38,7 @@ class ResponseFactory: @classmethod def _process_response_history(cls, first_response: SyncResponse, parser_arguments: Dict) -> list[Response]: """Process response history to build a list of `Response` objects""" - history = [] + history: list[Response] = [] current_request = first_response.request.redirected_from try: @@ -101,6 +101,7 @@ class ResponseFactory: :param first_response: An earlier or initial Playwright `Response` object that may serve as a fallback response in the absence of the final one. :param parser_arguments: A dictionary containing additional arguments needed for parsing or further customization of the returned `Response`. These arguments are dynamically unpacked into the `Response` object. + :param meta: Additional meta data to be saved with the response. :return: A fully populated `Response` object containing the page's URL, content, status, headers, cookies, and other derived metadata. :rtype: Response @@ -145,7 +146,7 @@ class ResponseFactory: cls, first_response: AsyncResponse, parser_arguments: Dict ) -> list[Response]: """Process response history to build a list of `Response` objects""" - history = [] + history: list[Response] = [] current_request = first_response.request.redirected_from try: @@ -238,6 +239,7 @@ class ResponseFactory: :param first_response: An earlier or initial Playwright `Response` object that may serve as a fallback response in the absence of the final one. :param parser_arguments: A dictionary containing additional arguments needed for parsing or further customization of the returned `Response`. These arguments are dynamically unpacked into the `Response` object. + :param meta: Additional meta data to be saved with the response. :return: A fully populated `Response` object containing the page's URL, content, status, headers, cookies, and other derived metadata. :rtype: Response diff --git a/scrapling/parser.py b/scrapling/parser.py index 1ae6db1..820bc71 100644 --- a/scrapling/parser.py +++ b/scrapling/parser.py @@ -118,8 +118,11 @@ class Selector(SelectorsGeneration): if root is None and content is None: raise ValueError("Selector class needs HTML content, or root arguments to work") - self.__text = None + self.__text: Optional[TextHandler] = None + self.__tag: Optional[str] = None + self.__attributes: Optional[AttributesHandler] = None if root is None: + body: str | bytes if isinstance(content, str): body = content.strip().replace("\x00", "") or "" elif isinstance(content, bytes): @@ -128,17 +131,18 @@ class Selector(SelectorsGeneration): raise TypeError(f"content argument must be str or bytes, got {type(content)}") # https://lxml.de/api/lxml.etree.HTMLParser-class.html - parser = HTMLParser( + _parser_kwargs: Dict[str, Any] = dict( recover=True, remove_blank_text=True, remove_comments=(not keep_comments), encoding=encoding, compact=True, huge_tree=huge_tree, - default_doctype=True, + default_doctype=True, # Supported by lxml but missing from stubs strip_cdata=(not keep_cdata), ) - self._root = cast(HtmlElement, fromstring(body or "", parser=parser, base_url=url or None)) + parser = HTMLParser(**_parser_kwargs) + self._root = cast(HtmlElement, fromstring(body or "", parser=parser, base_url=url or "")) self._raw_body = content else: @@ -164,7 +168,7 @@ class Selector(SelectorsGeneration): self._root = cast(HtmlElement, root) self._raw_body = "" - self.__adaptive_enabled = adaptive + self.__adaptive_enabled = bool(adaptive) if self.__adaptive_enabled: if _storage is not None: @@ -277,8 +281,8 @@ class Selector(SelectorsGeneration): if self._is_text_node(self._root): return "#text" if not self.__tag: - self.__tag = self._root.tag - return self.__tag + self.__tag = str(self._root.tag) + return self.__tag or "" @property def text(self) -> TextHandler: @@ -313,11 +317,11 @@ class Selector(SelectorsGeneration): if self._is_text_node(self._root): return TextHandler(str(self._root)) - ignored_elements = set() + ignored_elements: set[Any] = set() if ignore_tags: for element in self._root.iter(*ignore_tags): ignored_elements.add(element) - ignored_elements.update(set(_find_all_elements(element))) + ignored_elements.update(cast(list, _find_all_elements(element))) _all_strings = [] for node in self._root.iter(): @@ -395,7 +399,7 @@ class Selector(SelectorsGeneration): """Return all elements under the current element in the DOM tree""" if self._is_text_node(self._root): return Selectors() - below = _find_all_elements(self._root) + below = cast(List, _find_all_elements(self._root)) return self.__elements_convertor(below) if below is not None else Selectors() @property @@ -533,7 +537,7 @@ class Selector(SelectorsGeneration): :param selector_type: If True, the return result will be converted to `Selectors` object :return: List of pure HTML elements that got the highest matching score or 'Selectors' object """ - score_table = {} + score_table: Dict[float, List[Any]] = {} # Note: `element` will most likely always be a dictionary at this point. if isinstance(element, self.__class__): element = element._root @@ -541,11 +545,11 @@ class Selector(SelectorsGeneration): if issubclass(type(element), HtmlElement): element = _StorageTools.element_to_dict(element) - for node in _find_all_elements(self._root): + for node in cast(List, _find_all_elements(self._root)): # Collect all elements in the page, then for each element get the matching score of it against the node. # Hence: the code doesn't stop even if the score was 100% # because there might be another element(s) left in page with the same score - score = self.__calculate_similarity_score(element, node) + score = self.__calculate_similarity_score(cast(Dict, element), node) score_table.setdefault(score, []).append(node) if score_table: @@ -710,7 +714,7 @@ class Selector(SelectorsGeneration): if not args and not kwargs: raise TypeError("You have to pass something to search with, like tag name(s), tag attributes, or both.") - attributes = dict() + attributes: Dict[str, Any] = dict() tags: Set[str] = set() patterns: Set[Pattern] = set() results, functions, selectors = Selectors(), [], [] @@ -809,21 +813,19 @@ class Selector(SelectorsGeneration): :param candidate: The element to compare with the original element. :return: A percentage score of how similar is the candidate to the original element """ - score, checks = 0, 0 + score: float = 0 + checks: int = 0 data = _StorageTools.element_to_dict(candidate) - # Possible TODO: - # Study the idea of giving weight to each test below so some are more important than others - # Current results: With weights some websites had better score while it was worse for others - score += 1 if original["tag"] == data["tag"] else 0 # * 0.3 # 30% + score += 1 if original["tag"] == data["tag"] else 0 checks += 1 if original["text"]: - score += SequenceMatcher(None, original["text"], data.get("text") or "").ratio() # * 0.3 # 30% + score += SequenceMatcher(None, original["text"], data.get("text") or "").ratio() checks += 1 # if both don't have attributes, it still counts for something! - score += self.__calculate_dict_diff(original["attributes"], data["attributes"]) # * 0.3 # 30% + score += self.__calculate_dict_diff(original["attributes"], data["attributes"]) checks += 1 # Separate similarity test for class, id, href,... this will help in full structural changes @@ -838,23 +840,19 @@ class Selector(SelectorsGeneration): None, original["attributes"][attrib], data["attributes"].get(attrib) or "", - ).ratio() # * 0.3 # 30% + ).ratio() checks += 1 - score += SequenceMatcher(None, original["path"], data["path"]).ratio() # * 0.1 # 10% + score += SequenceMatcher(None, original["path"], data["path"]).ratio() checks += 1 if original.get("parent_name"): # Then we start comparing parents' data if data.get("parent_name"): - score += SequenceMatcher( - None, original["parent_name"], data.get("parent_name") or "" - ).ratio() # * 0.2 # 20% + score += SequenceMatcher(None, original["parent_name"], data.get("parent_name") or "").ratio() checks += 1 - score += self.__calculate_dict_diff( - original["parent_attribs"], data.get("parent_attribs") or {} - ) # * 0.2 # 20% + score += self.__calculate_dict_diff(original["parent_attribs"], data.get("parent_attribs") or {}) checks += 1 if original["parent_text"]: @@ -862,14 +860,14 @@ class Selector(SelectorsGeneration): None, original["parent_text"], data.get("parent_text") or "", - ).ratio() # * 0.1 # 10% + ).ratio() checks += 1 # else: # # The original element has a parent and this one not, this is not a good sign # score -= 0.1 if original.get("siblings"): - score += SequenceMatcher(None, original["siblings"], data.get("siblings") or []).ratio() # * 0.1 # 10% + score += SequenceMatcher(None, original["siblings"], data.get("siblings") or []).ratio() checks += 1 # How % sure? let's see @@ -890,14 +888,14 @@ class Selector(SelectorsGeneration): the docs for more info. """ if self.__adaptive_enabled: - target = element - if isinstance(target, self.__class__): - target: HtmlElement = target._root + target_element: Any = element + if isinstance(target_element, self.__class__): + target_element = target_element._root - if self._is_text_node(target): - target: HtmlElement = target.getparent() + if self._is_text_node(target_element): + target_element = target_element.getparent() - self._storage.save(target, identifier) + self._storage.save(target_element, identifier) else: raise RuntimeError( "Can't use `adaptive` features while it's disabled globally, you have to start a new class instance." @@ -987,7 +985,8 @@ class Selector(SelectorsGeneration): candidate_attributes = ( self.__get_attributes(candidate, ignore_attributes) if ignore_attributes else candidate.attrib ) - score, checks = 0, 0 + score: float = 0 + checks: int = 0 if original_attributes: score += sum( @@ -1116,16 +1115,16 @@ class Selector(SelectorsGeneration): if not case_sensitive: text = text.lower() - possible_targets = _find_all_elements_with_spaces(self._root) + possible_targets = cast(List, _find_all_elements_with_spaces(self._root)) if possible_targets: for node in self.__elements_convertor(possible_targets): """Check if element matches given text otherwise, traverse the children tree and iterate""" - node_text = node.text + node_text: TextHandler = node.text if clean_match: - node_text = node_text.clean() + node_text = TextHandler(node_text.clean()) if not case_sensitive: - node_text = node_text.lower() + node_text = TextHandler(node_text.lower()) if partial: if text in node_text: @@ -1178,7 +1177,7 @@ class Selector(SelectorsGeneration): results = Selectors() - possible_targets = _find_all_elements_with_spaces(self._root) + possible_targets = cast(List, _find_all_elements_with_spaces(self._root)) if possible_targets: for node in self.__elements_convertor(possible_targets): """Check if element matches given regex otherwise, traverse the children tree and iterate""" diff --git a/scrapling/spiders/request.py b/scrapling/spiders/request.py index 3351100..edfc387 100644 --- a/scrapling/spiders/request.py +++ b/scrapling/spiders/request.py @@ -7,7 +7,7 @@ import orjson from w3lib.url import canonicalize_url from scrapling.engines.toolbelt.custom import Response -from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Union, Tuple, TYPE_CHECKING +from scrapling.core._types import Any, AsyncGenerator, Callable, Dict, Optional, Union, Tuple, TYPE_CHECKING if TYPE_CHECKING: from scrapling.spiders.spider import Spider @@ -42,7 +42,7 @@ class Request: self.meta: dict[str, Any] = meta if meta else {} self._retry_count: int = _retry_count self._session_kwargs = kwargs if kwargs else {} - self._fp = None + self._fp: Optional[bytes] = None def copy(self) -> "Request": """Create a copy of this request.""" @@ -89,7 +89,7 @@ class Request: body = b"" else: post_data = self._session_kwargs.get("json", {}) - body: bytes = orjson.dumps(post_data) if post_data else b"" + body = orjson.dumps(post_data) if post_data else b"" data: Dict[str, str | Tuple] = { "sid": self.sid, diff --git a/scrapling/spiders/session.py b/scrapling/spiders/session.py index 8f5e7af..cc07042 100644 --- a/scrapling/spiders/session.py +++ b/scrapling/spiders/session.py @@ -12,7 +12,7 @@ Session = FetcherSession | AsyncDynamicSession | AsyncStealthySession class SessionManager: """Manages pre-configured session instances.""" - def __init__(self): + def __init__(self) -> None: self._sessions: dict[str, Session] = {} self._default_session_id: str | None = None self._started: bool = False @@ -109,17 +109,17 @@ class SessionManager: await session.__aenter__() if isinstance(session, FetcherSession): - session = session._client + client = session._client - if isinstance(session, _ASyncSessionLogic): - response = await session._make_request( + if isinstance(client, _ASyncSessionLogic): + response = await client._make_request( method=cast(SUPPORTED_HTTP_METHODS, request._session_kwargs.pop("method", "GET")), url=request.url, **request._session_kwargs, ) else: # Sync session or other types - shouldn't happen in async context - raise TypeError(f"Session type {type(session)} not supported for async fetch") + raise TypeError(f"Session type {type(client)} not supported for async fetch") else: response = await session.fetch(url=request.url, **request._session_kwargs) From e7773427415689fa4a0448e79751da3bf9c1404f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 16:30:32 +0200 Subject: [PATCH 63/80] build: pump up version and deps --- pyproject.toml | 11 ++++++----- scrapling/__init__.py | 2 +- setup.cfg | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4a6a7ed..328725e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "scrapling" # Static version instead of a dynamic version so we can get better layer caching while building docker, check the docker file to understand -version = "0.4beta" +version = "0.4alpha" description = "Scrapling is an undetectable, powerful, flexible, high-performance Python library that makes Web Scraping easy and effortless as it should be!" readme = {file = "docs/README.md", content-type = "text/markdown"} license = {file = "LICENSE"} @@ -58,10 +58,11 @@ classifiers = [ ] dependencies = [ "lxml>=6.0.2", - "cssselect>=1.3.0", - "orjson>=3.11.5", + "cssselect>=1.4.0", + "orjson>=3.11.7", "tld>=0.13.1", - "w3lib>=2.3.0" + "w3lib>=2.4.0", + "typing_extensions", ] [project.optional-dependencies] @@ -70,7 +71,7 @@ fetchers = [ "curl_cffi>=0.14.0", "playwright==1.56.0", "patchright==1.56.0", - "browserforge>=1.2.3", + "browserforge>=1.2.4", "msgspec>=0.20.0", "anyio>=4.12.1" ] diff --git a/scrapling/__init__.py b/scrapling/__init__.py index ce26cba..c6ba45f 100644 --- a/scrapling/__init__.py +++ b/scrapling/__init__.py @@ -1,5 +1,5 @@ __author__ = "Karim Shoair (karim.shoair@pm.me)" -__version__ = "0.4beta" +__version__ = "0.4alpha" __copyright__ = "Copyright (c) 2024 Karim Shoair" from typing import Any, TYPE_CHECKING diff --git a/setup.cfg b/setup.cfg index e4b4fc0..92a14e5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = scrapling -version = 0.4beta +version = 0.4alpha author = Karim Shoair author_email = karim.shoair@pm.me description = Scrapling is an undetectable, powerful, flexible, high-performance Python library that makes Web Scraping easy and effortless as it should be! From 16852cb1ac8b6061e77dbda13b28b8bc296b9c8f Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 16:37:47 +0200 Subject: [PATCH 64/80] style: Use shorter and more accurate naming for constants --- scrapling/engines/_browsers/_base.py | 12 ++++-------- scrapling/engines/constants.py | 8 ++++---- scrapling/engines/toolbelt/navigation.py | 6 +++--- tests/fetchers/test_constants.py | 25 ++++++++++-------------- tests/fetchers/test_utils.py | 1 - 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/scrapling/engines/_browsers/_base.py b/scrapling/engines/_browsers/_base.py index e379882..51ce308 100644 --- a/scrapling/engines/_browsers/_base.py +++ b/scrapling/engines/_browsers/_base.py @@ -40,11 +40,7 @@ from scrapling.core._types import ( Generator, AsyncGenerator, ) -from scrapling.engines.constants import ( - DEFAULT_STEALTH_FLAGS, - HARMFUL_DEFAULT_ARGS, - DEFAULT_FLAGS, -) +from scrapling.engines.constants import STEALTH_ARGS, HARMFUL_ARGS, DEFAULT_ARGS class SyncSession: @@ -389,8 +385,8 @@ class BaseSessionMixin: # Dark color scheme bypasses the 'prefersLightColor' check in creepjs self._context_options: Dict[str, Any] = {"color_scheme": "dark", "device_scale_factor": 2} self._browser_options: Dict[str, Any] = { - "args": DEFAULT_FLAGS, - "ignore_default_args": HARMFUL_DEFAULT_ARGS, + "args": DEFAULT_ARGS, + "ignore_default_args": HARMFUL_ARGS, } if "__max_pages" in params: params["max_pages"] = params.pop("__max_pages") @@ -484,7 +480,7 @@ class StealthySessionMixin(BaseSessionMixin): config = cast(StealthConfig, self._config) flags: Tuple[str, ...] = tuple() if not config.cdp_url: - flags = DEFAULT_FLAGS + DEFAULT_STEALTH_FLAGS + flags = DEFAULT_ARGS + STEALTH_ARGS if config.block_webrtc: flags += ( diff --git a/scrapling/engines/constants.py b/scrapling/engines/constants.py index f658416..4bc0014 100644 --- a/scrapling/engines/constants.py +++ b/scrapling/engines/constants.py @@ -1,5 +1,5 @@ # Disable loading these resources for speed -DEFAULT_DISABLED_RESOURCES = { +EXTRA_RESOURCES = { "font", "image", "media", @@ -12,7 +12,7 @@ DEFAULT_DISABLED_RESOURCES = { "stylesheet", } -HARMFUL_DEFAULT_ARGS = ( +HARMFUL_ARGS = ( # This will be ignored to avoid detection more and possibly avoid the popup crashing bug abuse: https://issues.chromium.org/issues/340836884 "--enable-automation", "--disable-popup-blocking", @@ -21,7 +21,7 @@ HARMFUL_DEFAULT_ARGS = ( "--disable-extensions", ) -DEFAULT_FLAGS = ( +DEFAULT_ARGS = ( # Speed up chromium browsers by default "--no-pings", "--no-first-run", @@ -36,7 +36,7 @@ DEFAULT_FLAGS = ( "--disable-search-engine-choice-screen", ) -DEFAULT_STEALTH_FLAGS = ( +STEALTH_ARGS = ( # Explanation: https://peter.sh/experiments/chromium-command-line-switches/ # Generally this will make the browser faster and less detectable # "--incognito", diff --git a/scrapling/engines/toolbelt/navigation.py b/scrapling/engines/toolbelt/navigation.py index e9e74ae..5c19427 100644 --- a/scrapling/engines/toolbelt/navigation.py +++ b/scrapling/engines/toolbelt/navigation.py @@ -12,7 +12,7 @@ from playwright.sync_api import Route from scrapling.core.utils import log from scrapling.core._types import Dict, Set, Tuple, Optional, Callable -from scrapling.engines.constants import DEFAULT_DISABLED_RESOURCES +from scrapling.engines.constants import EXTRA_RESOURCES __BYPASSES_DIR__ = Path(__file__).parent / "bypasses" @@ -30,7 +30,7 @@ def create_intercept_handler(disable_resources: bool, blocked_domains: Optional[ :param blocked_domains: Set of domain names to block requests to. :return: A sync route handler function. """ - disabled_resources = DEFAULT_DISABLED_RESOURCES if disable_resources else set() + disabled_resources = EXTRA_RESOURCES if disable_resources else set() domains = blocked_domains or set() def handler(route: Route): @@ -57,7 +57,7 @@ def create_async_intercept_handler(disable_resources: bool, blocked_domains: Opt :param blocked_domains: Set of domain names to block requests to. :return: An async route handler function. """ - disabled_resources = DEFAULT_DISABLED_RESOURCES if disable_resources else set() + disabled_resources = EXTRA_RESOURCES if disable_resources else set() domains = blocked_domains or set() async def handler(route: async_Route): diff --git a/tests/fetchers/test_constants.py b/tests/fetchers/test_constants.py index 36662c6..91afd4c 100644 --- a/tests/fetchers/test_constants.py +++ b/tests/fetchers/test_constants.py @@ -1,9 +1,4 @@ -from scrapling.engines.constants import ( - DEFAULT_DISABLED_RESOURCES, - DEFAULT_STEALTH_FLAGS, - HARMFUL_DEFAULT_ARGS, - DEFAULT_FLAGS, -) +from scrapling.engines.constants import EXTRA_RESOURCES, STEALTH_ARGS, HARMFUL_ARGS, DEFAULT_ARGS class TestConstants: @@ -11,18 +6,18 @@ class TestConstants: def test_default_disabled_resources(self): """Test default disabled resources""" - assert "image" in DEFAULT_DISABLED_RESOURCES - assert "font" in DEFAULT_DISABLED_RESOURCES - assert "stylesheet" in DEFAULT_DISABLED_RESOURCES - assert "media" in DEFAULT_DISABLED_RESOURCES + assert "image" in EXTRA_RESOURCES + assert "font" in EXTRA_RESOURCES + assert "stylesheet" in EXTRA_RESOURCES + assert "media" in EXTRA_RESOURCES def test_harmful_default_args(self): """Test harmful default arguments""" - assert "--enable-automation" in HARMFUL_DEFAULT_ARGS - assert "--disable-popup-blocking" in HARMFUL_DEFAULT_ARGS + assert "--enable-automation" in HARMFUL_ARGS + assert "--disable-popup-blocking" in HARMFUL_ARGS def test_flags(self): """Test default stealth flags""" - assert "--no-pings" in DEFAULT_FLAGS - # assert "--incognito" in DEFAULT_STEALTH_FLAGS - assert "--disable-blink-features=AutomationControlled" in DEFAULT_STEALTH_FLAGS + assert "--no-pings" in DEFAULT_ARGS + # assert "--incognito" in STEALTH_ARGS + assert "--disable-blink-features=AutomationControlled" in STEALTH_ARGS diff --git a/tests/fetchers/test_utils.py b/tests/fetchers/test_utils.py index 9c08f7f..4637a63 100644 --- a/tests/fetchers/test_utils.py +++ b/tests/fetchers/test_utils.py @@ -8,7 +8,6 @@ from scrapling.engines.toolbelt.navigation import ( create_async_intercept_handler, js_bypass_path, ) -from scrapling.engines.constants import DEFAULT_DISABLED_RESOURCES from scrapling.engines.toolbelt.fingerprints import ( generate_convincing_referer, get_os_name, From b1ce0b414b167d7d5b08c9016cc954868ebe2818 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sat, 7 Feb 2026 17:28:44 +0200 Subject: [PATCH 65/80] ops: Add mypy and pyright to the code quality workflow --- .github/workflows/code-quality.yml | 36 +++++++++++++++++++++++++++++- pyproject.toml | 14 +++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 6e15d6a..4afdfb4 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -51,7 +51,9 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install bandit[toml] ruff vermin + pip install bandit[toml] ruff vermin mypy pyright + pip install -e ".[all]" + pip install lxml-stubs - name: Run Bandit (Security Linter) id: bandit @@ -86,6 +88,22 @@ jobs: vermin -t=3.10- --violations --eval-annotations --no-tips scrapling/ echo "::endgroup::" + - name: Run Mypy (Static Type Checker) + id: mypy + continue-on-error: true + run: | + echo "::group::Mypy - Static Type Checker" + mypy scrapling/ + echo "::endgroup::" + + - name: Run Pyright (Static Type Checker) + id: pyright + continue-on-error: true + run: | + echo "::group::Pyright - Static Type Checker" + pyright scrapling/ + echo "::endgroup::" + - name: Check results and create summary if: always() run: | @@ -127,6 +145,22 @@ jobs: all_passed=false fi + # Check Mypy + if [ "${{ steps.mypy.outcome }}" == "success" ]; then + echo "✅ **Mypy (Type Checker)**: Passed" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **Mypy (Type Checker)**: Failed" >> $GITHUB_STEP_SUMMARY + all_passed=false + fi + + # Check Pyright + if [ "${{ steps.pyright.outcome }}" == "success" ]; then + echo "✅ **Pyright (Type Checker)**: Passed" >> $GITHUB_STEP_SUMMARY + else + echo "❌ **Pyright (Type Checker)**: Failed" >> $GITHUB_STEP_SUMMARY + all_passed=false + fi + echo "" >> $GITHUB_STEP_SUMMARY if [ "$all_passed" == "true" ]; then diff --git a/pyproject.toml b/pyproject.toml index 328725e..3d884e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,4 +105,16 @@ include-package-data = true [tool.setuptools.packages.find] where = ["."] -include = ["scrapling*"] \ No newline at end of file +include = ["scrapling*"] + +[tool.mypy] +python_version = "3.10" +warn_unused_configs = true +ignore_missing_imports = true +check_untyped_defs = true + +[tool.pyright] +pythonVersion = "3.10" +typeCheckingMode = "basic" +include = ["scrapling"] +ignore = ["tests", "benchmarks.py"] \ No newline at end of file From 3eaa7ffc25b750f85adfc5122e379e58ace09fe4 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:42:35 +0200 Subject: [PATCH 66/80] ops: exclude site directory from git --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 0cd51e1..f27bc08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +site/* + # AI related files .claude/* CLAUDE.md From 219db79195358c54758c39dd4badd9f90a0157ad Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:44:04 +0200 Subject: [PATCH 67/80] docs: update logo and media --- docs/assets/cover_dark.png | Bin 0 -> 113787 bytes docs/assets/cover_dark.svg | 1 + docs/assets/cover_light.png | Bin 0 -> 51944 bytes docs/assets/cover_light.svg | 1 + docs/assets/favicon.ico | Bin 15406 -> 267230 bytes docs/assets/logo.png | Bin 169382 -> 58096 bytes docs/assets/main_cover.png | Bin 0 -> 454701 bytes docs/assets/poster.png | Bin 160079 -> 0 bytes images/poster.png | Bin 160079 -> 0 bytes 9 files changed, 2 insertions(+) create mode 100644 docs/assets/cover_dark.png create mode 100644 docs/assets/cover_dark.svg create mode 100644 docs/assets/cover_light.png create mode 100644 docs/assets/cover_light.svg mode change 100755 => 100644 docs/assets/favicon.ico create mode 100644 docs/assets/main_cover.png delete mode 100644 docs/assets/poster.png delete mode 100644 images/poster.png diff --git a/docs/assets/cover_dark.png b/docs/assets/cover_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..cac13a3d6578a302f8c376abf8e0eca19844dbce GIT binary patch literal 113787 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 z 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 \ No newline at end of file diff --git a/docs/assets/cover_light.png b/docs/assets/cover_light.png new file mode 100644 index 0000000000000000000000000000000000000000..7b8b61f0150b15a09b9044c03dfc5e7adf89998a GIT binary patch literal 51944 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 G;r|0K \ No newline at end of file diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico old mode 100755 new mode 100644 index 0f8ec66f11bb782122cc89b68c0d84a68c8347c1..5865afb58ee2568adc5c9dd6e44eb6d183052955 GIT binary patch literal 267230 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 L{O<%#$qD=m{rkq! diff --git a/docs/assets/logo.png b/docs/assets/logo.png index e4ced0df16f27b4e254af67d8fa62def667c4025..3c4f0cd80119976493548fbd20049122a5a1d922 100644 GIT binary patch literal 58096 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ΞOdUUyIB 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

%3*(zUtm>yN(xNHCZDRkkVS{*-=y>ErO;}VTMR5 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�&!IJ5qgLH<6hBl%$G&$sVPJi-~ zpKLu5U)nX7UDj?ko15?6%&+d)HKD%K8S>_jfw#JlpvGvxAjyT5B}5&vEJtH#5Xf9$ z1DGMz@6}wY$5WKSMKJJDGzAVs12VEA8%r`Ci9!Pv1w{`L+G~BgwaMD@B>*=+7SB(! z*(_Hyn-3p4J-ussvb@*1V*J(x3;KuuzOWVcFTvhhFFR}HM>_5Hc}2UmpXM152xipq zF2;b>PynciLBtEiI-M50FTQxl(s^%sl&n|*z%$W)ss6j z)32VMn7q)8^HrsmXSt|21Ur06P<4fS>Lg5bEU@8KA?D2_xji~z@FX@f$!b%1E&u0P zb7y}lFKTxJTW6k#?Dl_QFL)9Zdz4kHF3#@RxpPn~-%nMK^c{PHf(J?Fwhs*qe$CbL zwP^6((GP!k(-YeiQ2yl2mmJk9TCbXzocK2^>;NS*bxIKx8sSSXBDAd5klN6YG=_(1 zG>}F!qs9mhV`Uu_>sSfwe#SgOO@tK-?n23iBvO1R!JbfqKe?$Y1VmZ1rfK|3*8M+x zWzCuy^jY~&o7Lw4?8RlUm~QGInt4KuX7Ds2y38_(j2k1x07r-dik`z?SjDUT)~-xu zw#=*q++SpQeJ+Aen~8;t7mNR#5K3D7d`a1!CJ`as)zfFCw>m`Hs%}()cNLQZ5B{3g z`)L8Anz zvJk2SXA~uz2?r7$c<=}(=UnttcZ)Xbr?>-8sm)FL9(sr)|Bt{xm7Y-XxI20(hR^dW={S;_^Xk3kl9?say|7zESp2ktG$mn5v+Fi0|2e z(*W-g_mmaqo;!y#IGeQdK^$ikhvcW96b0Q_(q!T;5+ca}D24PCN*D*yLof-*r;+gs zFMr;%Z*4w(qd7S?Iy#A<9(dr4*ZtY9&h*R!X8u;E?uAAiMYBbvnTU#rs?m!l0$(s< zuz^((vlODSi-0Nw6~-l2ma|)}iTz8He8nrz|Jt?RxbnM?!>HxSP|*Fl>Oj{%Fg~}K znLKEEdg^(8W@gcS53ZkU&K=-XPgLiYh)52Y8UdCtqo3u=ve9w#_XXaHjE;VwH8L{t zpr5n&yX9nizJyWX^C)oQ6fVn<*Bj704=1wu1o$&%Swt;r^bL|~cc~^%60CoK0Pk0x z07O))#-y+C@i03GVgm;#)H(MI5q(uw&fRj}oBq|8ulm$K-qqjH`vpLM{XRQasOTdp zCvN^dLh>Zk4ebATN(U!8N(fc?otyQ`&N*j4-;w74eifm|ksK_&r@CkhipotCqy<4@ z^1Brn1KdEN(i9=mjod7%*F)u>e*DcZ-~8imUfqWP?L~m3A&62YF)97X`Fl_fEwm6yHKK2ob63|YVx&d-W(BF1DBm_U+>j*7|w znyfmG_-9E5D*#D3gYl6}gccJMA-syqozp`}zSA;mpZktK?|kVaAKcL22A`{r?ntyy@; z!hbb5H2iPsjruK6oiH;6SrZYchR{<8K&4T_*x$lHhNhsXGjSOq4(3J5qFhoG{`CgA z+~>tB26oIW+S}hiJDW4lYVLSZT>;?>9NH%is2x49V`kBY4I66co+^)q6ZDw!hMLW$ zqO2WG=l_(-&v;*cX{I&v$(hNizbMJ^FuOq?{KBPvH$8n^;e$+ zxEI&+SG@Z3P&r%0)hWj6b!4=bjilUIrF#m@sW>xE6E^yj?|${I|I)pB$(et05zSsp z^Dj1U12j0P+yx~%`Gtg=2>&I?Pyh!N2)MO~0KP2CNdZ10%s>C5Yp=ScfA~MDZrW`v zhGuCwbtK^q_r7=$ynh{uVE~x~WuOI(rHPpZV}>fGx#ox8{Nko3 z;2DsSx4viI?wwnoR}`I>wWnK$5?CaH{RFa1q0T8(G#q1wU{NU`ooE4q22q3r$O#er ztX3QR|LTT2zVxL}?%LP(*mM8vU9TvMa>ScoDNYAeoT{pk)G#+vkS3y<#`~mEgLapq z;p~?lH=*9JtiT8iqrS-XMf@N3d_e?6gH3Riekoo=OjJeTTL5nJ#;bj)pZ@YE{{Dgf zo8K=0`s;VBQ&*h%1ywy;)n$Z*)SaaIPX&O)8ed=_Oce^j4nVH>(YL?+uYa@uq`cxa zZ&>0{zMyFPH_`05H15ZQ;Z;d>=oSF6@{bur!o&qqK`<#o3Gg9b`Y$T@*&ki|wVV2f z|L+M4kh1b^Z=1Jc)70{^Y`z$Ju0sJU){QhAF?*FSlAaqGyIWjVj?flsBox9#a+KWVFVOGnhL}>ITr7r{L#OZEv zdjDX(@x`n*_`^dM4cxhA&6@JDejY~N^{(NG%{ve6Ot(%k%Kik7r{HAYDZ@-(RTUym z)ly!gS@hVHV1?_##5-zRuv=7qB&J`Q8Yo7u8y%h5w+hEqbBek<&4Xt_@Ip|I>|*!A zu4FhFb%&o51gwV;+)b+nV!)^XL8cl)yd-5_BNdcT{p%%K?8Ot8Y3omwcsjL15RfqP#AL>)PCwG& z|DxAkxVZ4;ivfE#%|FvT=Q7xNrOrPd_1%}e@*wW9_ZJa3(LnmAe}MGY)&}^uE1vt@ zEkC;UYyHFj(HG3A@FIX60DiP;)vD_s+%b7(tJOZMG=Cb%11PKq-vve2_Ni<4jtI*{ z`vrr*tB4XjtSIfE%;}3uFLQr&-}b9VMn>*gzI=K6(a!2eMn-g^oh>W9e-q7~M{;qN zXC;6J4H^a%!G;p_3&rdiW#(sR*3KuazI9||WZPbrCJF$KjEvNFWA<=oV(X$^8+R|WXFweyP*qdssH!ocSx8cR>BXviW|(MzxgpjO)$K0RpHp%9TvuHEoqa=A zSs_McW5I$B@GOYDTZrQc%y(HvGam^3)d?MPeJB(K!Jz2rVusc6ov0;hanv6;0$~J2 zi3C3=l1v~f29aDyG<`-&@Dr|lpUuRegvcy`9;=YomR{NyzW2RbKlQhNJ1za_-hKhl zU%&p6U!hyJj17=d^CAxD#>Oy~1b_r9pkOy^aaRn*yNXfafBoO1 z9xa;X>OhvBAT`N=1#pQ}ND-yLq8>Q-4TR_cfeNfFcR=hjnh##KXb3x=#%%vT`0)Sr zGHuP8HRbb0M!vORVCd%^6kjRI@_l9L5A{SX2s|}{K@fl*CI>c_4ndYMh&;-&8tst*m{t4iZkC8(OC@Juu zP`qZXcKbw<_qN)&ZO+ipPXO%ALzDo}8D6x%OiaAM)V+OXdioh=nD2lgRq-ln0@2Jl zm_Uux;FBvoTDQcEGiOF2>D9Rh8@25F>hQmZP~6#5xa<4$D8E~PN$ zluAUUC{SY@6j(4T78O&~+>W$h>D_%A7?Xho+ z{`hwtY7HP)mkoLKb5t}301N7aaNsBiRb^l&5QO=%lhf&bop$GtDGuMTw=UW_Z+Xis zKP3mxOi!J)>!F8_H5P}eb4MyLEP^aNoLvhWQd}^yF@_bGDnUPLZ1qc;RhyjRvop{6t!cHvO zlb5fA2=TOSbR(+(P&6?8qA^wE{8gf(u7RK?b|8h_l1jQrp&3OeR2Q;|eCbt18XaGp zwyixQ#jK$ZysOz<|KVnHvcDbl3xNJg9oNQ<8GJU|3G%q>SnugTilR%|iGiRYLp`E- zJMt{s20+ev%Ug!GKd|j6^L~Y9@_HH$BH2*Yvho3C=pJG_5T<<+Gr>Z%Z8bEs@aLxi zyWObYs5|}Q*tfrQ-w(h0>@GUx79*Zlmc@wx76Bqo z1#|-XuL%5oY?DY%3z+%@m+G1t`I2DZD(UDi1j4?lP0LwSoFK^11oVSO3#L zZNWYSO^>|iJ@a?Brk0z@E1>RtiW~-!+yEaZ^(m7>Q&pCdIipo~Du_f>qQ`#(1jsH0 zfZgw!A(fIT4?siyUsVVt%74%Xbu)-9@e8WSLL5(m@MghYkUWTxS4_9so2MTtzp!f6 zM}N6y&BaCkt?w5A{RO~v25X&iYCkv`Fr$dUi^jK&5cq)eQ3NnpieNGeIvy3-T5B}6 zjEs!v)Px-d%9}uWGk`$|l_b3REG391KM&Ago?*MpLaQLE05#0}3^14nxE_M5UipF( z{-)pcKL$8&%64uxyT2xX{K~hzZCztZuHC+U^PkiE7dq4V;&Q4$O$GGksp?=R-Z=-W zhP`5*22h+J@ZiZKz4r$Qvu71GuEyY^TTWiJYWt0kKoHE^)47&Kjov)OGE#&Zbs!>% zA5I}ani6DQuL&WuTCJJ=^19WU&8GamPLR!JQ-Au?Ukz_9{QO#H^Zq9O9W3!OqwVL* z(lKUJcryTMnwY7K9RKKEApq57mSv)#n)kk4mYqp6PP#n%?!aLED@*1yzFCnKKlZVG z1tbzcn9t;gd$F_4+dH*Z%V~6GW&q5*g>M+Ds#58K!>zAkf+Dde9LO|_;808gNMvD2i72&)j$#2B5*3<900I!@#U`o>m29yu{hy22^`0hu$&l@FpxNvP}g4M_l%${^9?)Rt20rGBQ5i zXxvmo?LS&pybk2My)WiMouuSN6M&+0mf~D2z&9GKTS(F%7X9J}Rd{?kQ~vKP%hoL3 zR(=t{J->kfz-pj0k}4$5dV>*k>^3PvSomJ8P|G)wQOXj zm|g~vMFeIU&80vpfrfN!mB34h1hk-67jsUEkVtJ=t3@Gw;Z&|47#jF|QFeYQ;x?C= zAAdZQ3V*;&XGB|$@x~KNU)G(=%mD^?F)Jn94h5jzz=+O3BB4J#IB~?E?7}0zhY*D( zVGp9wSNf+lPze$mAoRhWIv`0<5k!B$;0T-|Lc$}WfY2-qio%VFh(W9zRD>?i)tBYl z*)A5Iamgiru`ilP^;f?Dc>G5IMQb*oC#cA*7_u94<(Zg%@lA?IUEB-_h`|V8QpF9` z=Cohor}eo6ml6<|X+TNE5a)#vo?}w?Yv}AK(Go<3=8Z~nny@=m-NzjA@BHXnU)W-%qd!zM&TWuPqe+W0u=J6b;H=>fDghZF^w3Ue zuiv$E>%22x^Ty9-tZ%sb>W^3X>grswjjgQXs+i*F2LXglKNJVSy8wjql-fY2@u)ZT z6)T!qKDhSS?_YoOD>^NIFdR;X$k9R$6V#w@>jk|7yFVQK@#|7pIA#pd)>=tCtS zzbRc&Zwdkk{D)vFEol_M9`|r|2Y*re8)^SlAZS$_gb`$_yysl0I>3 zY^+%VShr$iLaNd6G9jYxmS7 zv#kA{Ge$<%UNbtn6#%?91EiF2swZMuvZ0pLt9E^g6-v+p4J-YeU6kKB|3Cf03x~2v zIbdSq)@N8zo<`zaqaB1&>Y7#N)2WIf#8MW9RO$Bdk7=a58(FBxW;1_3h?@q62EIlN z{_>j9Pi*TRO8fpgV&TBro9~}i5m{))mx$OQ5Dcp-%mVe&2pCNy6m_UJi~xpc?{_NE z_$Q|SR!AUIp%_7&bjg|SUd#jttfNQ+1yFS#d(@iILQvwClQe_LIyi6wpem~B4mHQO z&~wLmZ~9l)^m7BAyvy}3!5_bt9d^_aM!uQm=aFzUm{evj5xY;$-U1OQquPrk%Ph;< zh3_0WGd=xkhzv*XKtRMLJwFU8X#fzbg4h*^Xkbwh9#(n}k%yGJ=D_`i{_*QyA8qvy z|HmH-exwg>ShudT{;sv_m!I^!o6MIF`=WdiL>r>2RI4`rSU{?zo-VpQh3GiIx$qd6 z*@CiNyg;2g=dztAAAih!>(;Ha!;U^-$QQ+7Ed479%K}iO8a-m-WEqC;$s>8DG&Ae? za$CLbzw*HP^^YVul#@?hl^=4*q4j#r4u$B-PJ8CPMPcW7?-z>*8yn*tzqnz` zD_;2Av8hsK`O@!i=9h|O6|-=K*c*QNi(h!G zUfqB5`vt($Y&DyD@P>zvr1=XG%uECURnyq&NBhpmZi+&jxUVx)EkT=W-Y)?$AgU%I zW?s8ne|nDv$xJ5d#iK9$eK*a-%ocmYLTe1_fk&Qn|4^gmTCM5B z&HFPAl0h`Z!vw@V4wA)Uk0%0`srTlKqVNyPjD7i`hwlB2gZGRx-Z(p(-Fg+Jbx~`2 z=B=G}`!w@BK)_rDP*s77QW5C;5(6lMfqmsWt4^rFibm*5h{}|6?rZf%{hiM zPX!ys{J$g?33;9ZRZUQR)#Z1se$p?cQlo|@p9sJrW5jS(12FM1gSKe<+a1n@_$i-6j_nHwxS97v8Y6j7;?x}?JCB9s;# zxTEVQ=t#~1M4fXntV6osT?!I{F!Y4Uu_Mm+0$89B*#XFPfL!4kjqm^Pn$c~2*RFl% zTjMfow1y9m5mL~827?r)5eucQ!*0WnBqZvjOW&SgT{epVEx zPVJh=8@0xGTU`t4mQmED;ji{)$I`?g)PU?pVj80Jt~d+ZsT*XQ_y44TqbB8V;%M7qJk3Gr9yw*A$Z0m+*p%?Sc8z&xF*QxzWO4QH6R z2S(odp6`tQ-w)i~f8F~9z|&@pZ`w55W%+`#@UF7`NuK}Fc!kyIla(qro(e)U7k5bn zj`kieadHm|FJZJ7iYG$!4~GGqQPCTWdgTEN^3RTrjvD%~|Gs`u5I|>Sr1|BCci%ig z+H8^RXcCJcG5~P`?}MQPWlwh(MhjOFigV7)#JpeXJ%=)p9hBNG&<-{r>mCd7*zHM@ zt-`4TLhMvE%QEM@&jf&+bIv)#Gx_l1>0L9&(A#T3oaenC2IvAbrKn)4o+mu<#zUn- zQHns6iT4j;3giYre>^;U&J|hdZ@cQMLw5pC2}XIZ`91*Ps*nB6?QdB1@3wYo(k?qT zMbGD&*`mPB53G;)L)YCWNFZ5P>!_M&#-77W;nY)P&}nw45N|||*2pFQX?*muzv>f?pCqe40{A1>k;j~H zq;<;Y`=ayWcz84RTPCSyXZ15k>JFqb0O^+H2BlUR-x`y>ScQUUZw!cPXs2{C%j)a$ z%)M_YoB8UOzx?ICLC2G5ty?$dPdVwhdkd+5OUOmu`~A(hFc|X$7=RW=>VZ5@&{AC~ zP(d=Egn$k2?KoeS$C;Ifc(4%%Nif46fU>6ND;hOpOo=KYslbeoJv`2xA#O#EH2hmj2 ziRv;{=Tx$ZwKx3m_WqmQF94nv>lsHL_dH*gFDpCcQ3QP$`a`?%zew^O?FM|sNns4< z4Xs=v`$|o)jQJw+L9r z`7e2XXQ0*EAewC!r$+M!k#up^8yhzZ=D|@N78`2miFPGGltq!5_qAGC8SVXAf~EFXK3D>E!%g`ytLEmoIf+uemM*aom1yBjrx{2iDDP#LMm31eT`^R zt*Lo0Ag9E+Z)c7CqYC#q3V%6!pfmn-LaR26joGosKWA4VeAq#@n)$^b=LS+Zg>JrGBURbVs@3>%Yn#|_~h6sbxGB0@waj1I!#(<;*F zK}4+k6bG<}^z&)O+~ZDp(az(a^}O-hZoIC~33#$>LjCoJt(Two#+0P9&0wso;~Pk^}LR(S~aJz#^FV)bEc@C zuFjp}qLzmU2~9mzd?ACCb94-d{GWJ82dm&P66)oRR))Ua;e8|z1u}ptd#%N*OmXST zG(ihILsdio3cZ$sjQJ8OV)1ts!p#u=Kp_9uhVb(*eei?3`fqi=0C>u-6=$sccci_o z@SSIZQpR4*A-U3otEy)3K! zGxj^;J7b@0w)%JCsk2T${lcN4d9`P3-L~}|-j`>Y;-E}iDJDWPi&G<$FdYb;eQ>TAdzFA{*TY zNq?!O`G?i%%>x4i-xG18b83ELpP$m*ci*t;-z{jvpYM(DR^!2{Za|z$X zihu6m>Kn%|gn{BTdjCcq02PF>EB4nezbJ_g8F_?JRxDAp97~Pxc}10Rnh+QqjNv1} z#4I8VB*aAwp%e%CfNJ)Ic|79hYd*TFM87H7Cztjw!5_EEPG>(~mdlh@jYI_+BKrW1 zfSXZ+=t?RER@|*MF}uVx1fvK@1))X}Gs3(_Sr%gEp@Qiw%YKzR`QYrV{{68}Hh&|Y zv)OFwqbTnB#os=RVBbQFjeK{VHo zSaC3Tg;R>EsksmqClm{OJQq#*2qTOJGs1g{73Ns_P?m-x-l76EB-ha#lul?qn%4m^ zr~}NrE6YL%nao`NzD9lEU0G54SZ93G!;#(pv_1&PZWiBBOK0t1UR>#vmw5O)JbcGU zxGe7o;~pu>cn`1}4PwRsbhLF^f3?aU>Ho$Kip9T7Md0-ja_%m?E+A8j5nj zU_hOq%h10lLTp5^BULeK*QpXQHAqxM1_p)%(6@SDUN|-P;r&;wS<@$*_Yr`n7>qYE z;%bW*58ZS7{eKPP+e9JC^hQv@p2=OR*d+#dkzI{%fc7l?oYm|A0j4t__Iqz|d3GN( zyH=cD>GFXezx+8zj{g=f?tLK(y}$nGXRKMl^A^_BBy{ASpcbmj2n}ZEJf5o)dlitAb&us5rR~?CL+P# zA=yt}nRWKrs|GpCAG>qw_W$6$KhLT2l9IflelJCH z_86c>To2Y0d?wKN;ZSh1n&g8@BMD3cvL(y&@3~s`^?}86#vPJ<$C)`oT!yH+{KtAu(2z}X<31taOy#8DImm`hqzh=>IOKqc)CFmN=BPl|n^ zfNF6tC8~j85ZHkd!G_R?iij752Hu&L287UF%A}D$Q>Wk0YPBC6zHIJwYaSt~u)ltD zHJeRcJ3e0T>}sC{k=KdpD^;~YIH7f|KN%hQD{?UemJkIA)(TN35J&y&@&!ba=MPf4 zVDbiHwGo9@KMIc{LP^Gqfb_fs=vcr#x|$eODgrp?pjie0G}u;__7Mucbk#@y?v`$S z(O>-n;7PpB7{hAelV&z-x+RB}efz*!yCx*8fL93XT6WF26pFpy$Uc!l#` z*aoakFC8Tdqs$on3?XgtY!SXq6zz67HA9iI-Kkrx-mxJ++n4j;F*H<8)N20FojdK3 z=DE#gQ)7}`|3%-6Yt^b%`CSiedksC`PG3G370r-1tR&ee{D=xj^cjo{`70|~S0{w1w3&B8P%MJ$DoACeXr{F=m>5?Py! zH#&q5fS?8xNGT~cKolD5fk-t)vK0s^m6B@8gh8Y+s574o3-h}3$IYO+M38*0qG+@K3B5Dzh2qA$&Pr_)_fbY_bX7MW) zhE!SzsiGzVZ@!!om2Ggk-DTO%%+ns|J0q67dU3MwSd`QtV{d z^nsb@kpdw#1D?jQ7bkov$efr7l0sFPM8!4 zFi}+o$FgYkD6BHiDFG}H)wr33T0liS&F-i7-*yY?m(Dx<@a=0Z?vDfd1;CTF`@iIp zdi$ZB%ggE38q$s?(TI(`RK^bpcqPwhr`r>?Bp_n8n}BrlI(6Hr>1?>Yph zuIRWXF|8v)xMHpf{EP!YiMzjrfpKM4$fPz5FSu3VBm~WT32;W7&ZxK<2&O>U4f>s= z-wkpG&=y3e0hHo&I&*Gktya4)AIKjdYMZio`P9T+cXh_b#(rZ4oQ53z;^FsuU(Y)0 zg1M7czR=3f8$hn0_lv7c*lzr9%8ZDzZ>vmYlQ>*b6kqgrK?MyUr4m{!SS7_whsR7+ z1STSzRo%}--q^pFd#MN*8PQ^J(aWIjT!_3zT)seo93ahlZGiw<;0l_> zgPzy}u4J--BfZ70>wD{k8y?21PN5LPjR9Y zvLx(2Z}z1u&;H-?{b$|UY&JXn+x^6@K0EUdSZ-H)e+N0fAomARPs-dl4eP3J&PZXQSp158#T zj4|xdwVkQ6qlbth2dpNLIVpn_-h<|a09A#6c!hK*C;&_vxTP$MyNZc&y%kdr_^s`6 z&w=UZo%ZVK!J&caS~j?)$m`p_GrDGX|0()|7N7H+BgfaS9skbe-S-dBdlk{s2@a9S z(w@IZ@IbE{l?BZgEcAqxRh5|}d>1LnI;01&*P%AXO_zZFN;7xez|i2=jQHs{zxe4* z{lkCn-Q&^GQNLnE^LulaZJ9KMs>$haZiy&zkuc1uD8{jv4zYd8r29`zJ>%#m%>Rkr zlAEkLkFI;OBwl}l^D&R|)-vo+IRLE~U-wc}pF>f@|L@|@+`Hs9+f1uuIT%)SjPH%tU=7E6$ z-ZwnV{kCqk6)RR)pEvOPtraVpndCRWz{vk;=8raFZm{E}3E@a8CB+6Y8cvBt%OIEu zoG{n`8N)z79QSmJ1TO_Op(Id>o~7TBYyNk0m+XJ})t~#=mi|3^Z1?B0SFKu5Ov{I| zEI%#J^8GT+t+Y}M444e9$_fg@`)=lQ3J4NW0cnV!P#8R_q;z5P$vGI6EIAH&L_7g? z;UG632nmT}5M-gj?F1@faVvB2w?&PrrWUORMMOz>D|dOb&&;#k?>*#@Lpr}j$<$wu zM>E^M1i$|};2DR%*vwWEG7H9p=1aH0jxZfVWJ{IZk<3%2%j88*kV-c(5C}G0W>Vz~ z#d{T?f72NFWuONB4>itzQ+qGTwpBvRJj_Z-94`q%U+qa77DoS83TP}rZ%U&ACP9W2 z-czTkr~wV2gnv5dixg2kpm3QJm$?j(LGNv0t21-V)b#XeZRY2-I{y4w1z(U4%|39~ z3?_~{>Nzv(*8Qvx2|miTVZ#^?Ip~?YG{X&MvVhZ2mDD>%no4?r)om7+{m?=Fhh_Zkyt?1EZr!^6tpBkt^iDpxm@Ko~l&sP0NC5|` zG$#OIM87ALD57C3*md*)dggnv@u;l*RAYcq9Os7&r@#!cln4+M27sgxf;dA8PKAP` z9tli^xE)3W$xJ9P5qhU$0?h@O+hXnDO}pB6-0{onclGad9|3q$T(9%r_O=6dZrZh~ zEd0L*k!f1EMaD@jx13F+Mu(IS72g^lKLgp~RNz~41O||~C>=fsOFf8=uaV4s4JlcB-fGSp-kZNouiL4dR{N4m_ zcKJL((reP4tOZy%u(FwQ29l#Udm@Jef*U`*21nTR#)p^ND&k)#9}>H;njTY=&WGLE zVD%Ap>zBkQkmN%ceaqt}5jjQzRjpX(MuT||6_|=EoXfUro_$S-pL^JPac*axxh;*w zvv+-EO zhzWrA)Eo8B=8eH`f8z`Pd~4s*^@-bm&RuoMp(fcSQrgQMaCqjjyd>3v3NYyVE!y+C z*qjIUZ{YthDUrHVfr_FO-+Vzu@`C_0c5#LDkyK!aR=#B+{5jg5hdhWX*Nl~UQNpC8 zBBFZdWWB0>$`$e%Kl#AMzJlcOU41LyN8M>%q0`d~hbG6TUSD>K6~UkNY({-%b5Ch**m5k|@ANg7}oQmzXJ+Zl z+Wz7H#MXHyE?sbMeGvaiXx{+1o%E5s>7WvF0D>(;tn1C9rZWxr0%;gP3jH-OWH(6s z%e|k&!c3p4!f5nU1qeyXszywFB%-!ZU@?HIvMsVo(iHz<91e(PP(2bN=UL`2z@kM1 z{oC9}0QSlC^4E+UXWri0ZgtLv@gQM%npsh8dN5V=gqTwRRU|i-#J8{9fhDe%yo5ZN_>U|VIyR-j@?z##WjPqcNvVUR4TL`jnfre3q08~j)A64Jq zt>V+5q9P2Zo+5s*>Nrzx(UmpEZh&25k-$fgZn!+n5|hD0WLk&^1lU5sj(WX*Z_Q=b z4malfWb}%U?*1)@($g+s4uGs!F)~!R>1UN@Zv*8VWi}i1J>afY2(Pdk8wZBxOyhqd zYU1>3DtgtxEdBa0Fy0@<>^t}Qytlr4IcTqj$lD;g6zb}PnlCyUEu4eXkA*%y9Ly$N z5h#14pNu6!bP0@DVzd#43QW3^qJUFMw2DZn=MjzUZWHPA3!q|3)8sdV9vdnVkt}mw zArk^wr@4Fr-hJ=$A9>$~{%wAIR-Xj;DAw5{7e1p?+AGS^zgdXIBx(r??>hYg72mpx zzoU}eB^xg3V(1m^ruvgrWggq|Xb~hrNrSasyRAR~7eVO0_FG)@!(mLSIJ zatH))Bm~K#jgC-?&H|EZb4h;`}_v@pd z+terf?OW^huQ_Ae!@Fj-lWYmNSVU$)Bo7C6*VsY2mI3ibR}!S|d&rbXmK;l@f)XQx zxaXBeRpIyaJZWUP=gZ4q+XK3rf^wUzIygdiE*XZ~po96a72gM*yD4 zYrRPot|8AbwuC-2iJw>;pmhBoS7fxJr&1D@tP5A<+opt_MW#Rv{XqSHiLSwU) zqF}0ru(~Y-poFTLIK6jZVDLjybKm&(m7l%)5w4-2&%<~kCIA(wC*6k&FMRLdWZwF( zs(KbBJJO6PvQOg+Wy#Rbx=>$yyP{cGa3xRiPXUQb<|D~Zx*{Y+(ofg|qPuAtSyqJw zQ>Rn;Nhf48)&ahwRFNz4S#nM5zWZ8zPQYWk`W%2qc+=7bchmj% z57jvNoaw37x$RD8g{q|KDMTgMqG|})_VL7x*6LP;YXle1l*$*rWrC3QGpW?CqgHn6G5hc6EFjq0hR&cKyfsm!CMyG z3VqTUs0G_$iRs_8@b6Kbnp0<*!8E}aVb3r?0{_8)u-}Ai*)aSI!waO(8B7Qg3lhJ#6vvUm}k7l*uR+x}b3)P4iDdH5GXUMcB0vYUd+Ap7)nE0ej&__rMN{lotWTFvI_ z-iD2b9X32u&UF4xj2}l)+|RO%L|bJb>6kwfAkNH z%7NH|L?)7obcMiRm+B-?ku-Zi+So!b1N9ctDiMqVLY5>*?|o^Y_w=tUeeq{(=O+yv zaKNnoUGI+oo{)9!MSniGGdcOJ>7C=3c(YTWn5QC^{8Lj`od7dh6{%f0{Ya&-ukf)r z|I!HSR~ekixEIlAL)B^e>yqL=OJNmdK zM;&`I*WYo=<~=vkrjCt`J!PNW1D|okiDvd(dK@NIKAiN}#G;!^8JkLRS#17nlau=A z2kY40hyM4awHm+v%#MwX@vhr$oH^>a=j<@r7V~x(M1}=Y3zj>8R35!mW^a`y+}r(y zw_K~OO)3W|jZ?!Y?(KasD`HYK211gOR(NCz60Amr(Q~4^v8i_FouMSHLv)TWJBO6W zx1aQq(|6tSld-A({eNs$-wOBEV2Z$m5aTTUjHhp#w-Qb|pm_njbMz2x z6H)+DQY1O}C1zejL~;RLcqgf5$c(7P{CGzMKmjUFMKTc?P}N~T=72W86b!(uZbTL$ zN&|~P5^*3-nbiV{kYL0f57|Ai4m>o7HL65el zXM)gW?^agiA^;W1F_7JAK0=YPGe9KjDzFFVC%v?&oQNwNA;ksvh6Gd@2B8K}kX}Sh z6pLVdMOl>NHZiWN{=(RU2&7XXj>TD59bwrNNEh*qaPV!pgc9BZnM3V|7& zQOfvqJL?+!q-vlF#uSO!9Etre(U6NYXjPYsgxHm~h;}r~3ZZX7WhIR2$UVwQFT)XnDRv zr}O!?#f{sL6Dw*Z{E(Ek-%NY@pw3Kjlo7|HTk0nKKKNd^@aXa?1~s%9Di3aW^) zGDHZFKBFr!6M->!7bF`bW0z1+?OCz)*KS@iKzN9_6lfqJ4?!zugZNW1ID+$h(RoQp zz8ESU1I7gS3a~{ICCxtXOfH!y$)c*tM%MJt3~>v~(DNa~ZR&QOui%&hq8U z+mF#9#;ZU7@r})9^RI4Lzj2p&$yKtGC38Kkhs3?c0^~0mJ%NK$XgaJDQ-oc+l0*tl z^P=#K1#GUm6c!o_^oW}(Gn0sMO4I`yV2S!80!J9cX{Ax{0#$0(@MZfA=8^55sBJAd zeQUGXoaz?={Q}@ITPvE)?7_7g7EDd-dXG1GDMXx#ONKQ}?*1{nSCXAgbn!QknzA&A z%KI;w;{+y*!Bv?75U=8<^IX5}RIbZv+1*8fhs9yC@K%_Yjzd`#)VBGFR-<)T;iuO6 zBbP5{^v(yaxB~dK4QX_AbWaZMZ|@$Y*<9Y4T6=FX1z_jaL*&RKH_8L`!5zb!Hf?H6 zT;|}M3myohMm?cX z!#nQD#6_u)?O(rh;6#*M2RZuc|yYfVfY(=ObrGie_H<*W|Gsn|3#Ti43w{_w85Hh;g_Y>q!x zhgh@OwDT@}$7tL8-5$k%ci{e_+7NY2JbgH&QiR?lV)X3R>H%}>I+#`z<={lh7;8?e zFgZp|X&gAP;tB>^!oX0jbb%tmICf?ghaSa7A;rKvMNLFCv)t9h%JOBciShX&Lw|SQ zO#7Drw)UUIy$fgcS6pYF_ogFDU%bYfz0J%YY8J9mBw46c34IirsSiY}NDMTI=TJDx zT=d7Mz-bEmF?i7D&TS>+=LY$?kh^M5@2uAc?ix5+f^D zDzL1U=dH##Fs~?P4x8RRzN9l<%!ZYDUdsnut-i=PJu_*-9NfnMxhy=?fF9Ztb+(t8h z6TusYXAi9{z5I0S>!X_<;d_2k76&hS<$13$UtU;t%GUs@qS5;=X8$l`MuwSxC~px` z+t{Mn&xSI+aK(yKHuk%%J>P?oi{7<=dwS}ynaP>sW;(5frS}6Os`Yw32Qdf064H+G zW^=qR>+qzgl&Wq^p67RDwc7XU_4-5gMs35Dmw)uI+vLXr(`0^ZHv<^mr8+ zgv)%I&8tAIv>@sUuU{p>jij6EB@jsE9cpIM)dyy46$Q=H%ywGgf2etFbpE2b-~agEG&lAi$36nESJy=sH5(6)-*q(2 zUYDs`Vu17XD6NWBNv6EP_+B-I06<8Mc~`6i*0E|9fX;~*VwZ<(rnd*3a~oXUeS1-3 z-dIs=+dVouYWwhk!=4rhqkso66aU)@^4|0ZRwU+>8g2Tqc53%fkQEjQg*6`T4ilfZIG&PHw#Bnrk}EW>YGZ^cnYIdZ(>_ru z36UNP=wv^^ig`kKUrALk^EBTJn$4!J1+uBN8|HVWrWO_L_QH;D*SBujbZ{ow@!tFA zlUO36Ll6-&6A)QS-4p?wIKbBxDVI`oiObysTFUhoyz`ywhrOR%vt~`Px8K*V zUcTmmlUJ?!=f!Qz4c5K-EGLqgb|XfT>bC169$u>6Uo#Zv(IlvcK^mE*)gg{v7l3N3 z==y%7_~Q5%5>JXr7ZnQz5KdHrX@a!+(;05DXTzYBolz^Wjx1pz4m;~@E0KX#nwbiRv%f^ix-Bi6kFtvN; zh+SKEpWSZFyw;;U7#^7uQB}!AGm9O7nMp=k5M2hMVe~qHOXI~HTj9Ym}merenB$y)sU5h#u{n@w4}cCGwm{rbin8JbI%z0jbq^2XC?oIf))Ra146 zAs0Y=bWU{Uy+w+u5I%Wc3ZPlIutEwN-WMm79UknIqB8f#ldg6#EGQygHO-xa8DHehP=i8NBpUGqw5m(578R?xe6vXQQwOf0 z$R-)!mU(%5*HXaCQ`=XaJ%Arc^0d=Vo1T5>p?5hcKc$Lq5LqM7-NMXe#}PQY(`p~+ z&1OTj=7JP5Gz+59SuApkLy}#uf)cS$A$>#`4N}=I8--8_`*5fnRF%PrP#AsBb6*t4 z6rIjO)$HZlynOAv*S+Z*na!+!G8&OkX%z8LB`umfY8>*X!;xtO5HlT>29RRZr_wX{ zXx55mGn;ki#<@RRd+#aJ(|mrpbN4Y5#f}B4I!{#>sB`l(*T@3;6#VpESG!Xhs0_vz z!QexKlou{a>tLV}N;nYXM&6gzY+Y@7$73pQ8@u#UfBxIw{Vne~<$d{|1agFmHnLoN z=(;6V%IrFQSI*|Kf{xB55zbFxpQKsB>SHg|H3U+TkW7e#h-#$&vm0L;n+J5^e~3nM zlm*gMOs9gU!2w3+6u`0L+b7Qt*4NmnUY z(CdQPb7IHyCvdA0Gnk@bvsK}wy6lId`U@xShPm}6W6PJ%X+K?Osg6P9uGv!A~{I!mlbBSw{0zsFz~(=XPp0|x%p^`@GL z4|&ciiS?gGRH&j{A|lX@r;G%OM%vJyG8CcTKm%5-T9xnI>1S=9oIJ(<eAy zczm}y{o2hQYB1R zQ7Gu`2CBg*K%;0iTJ0&^!WWaSVgeGvkt-{GSPfL(D#E>rb8u?GJ{PaIP zBqAIg?O)^cf=kySU^jrSfEzI=h5(n`PwTSgZE6tm#qoD`ZCfD}rqjMBzVd#aHD0wGN>GBQ$| z!N8))@rikNY}hp4Nxldo7XbELqhDf$*JO{QB6O;xN+7?nd&E}?Rdmfhss}RC=BPp% zNo6u(GN|lU=Wd)oclHgB7XsL9Hm%ugZrid2|GZ&hQ%%6x6nBhh2<=uCn#J(3I7{m# z0Wu5$dJH-k!6S69NH=UcHBRA=MX7*Bx~R^NBz_ot&?*i-vRG8Kr$0WHY}Bc~vq-f1e3TtBVK2@qv+`;4`M zfTX3rC{a6wD!338xhg)+Fi(o)nXoLM-)^-I7{~`@*Wln7fcyJf>K_J;J?+=XyWTZC zwRQT1=F3%`_VkNjm>;b(y9rse*mB1CbQmfNfN1~^1M&$G`NrW(=iC~leEq}!k9aOe zMn)RrXe{>A#WE|4{fy=Q0zJ)}Khb+01X!LdOhuJedd8fF3Q~;DB^o5j$%#}_R&v_2 zBzhAw1R=vn8iGJdMWu93r$lhOy6je``SrEA`Bh*4^rt8G#R6}|IU}!Pt9WD4DPA8f z7K2PR>b)rv!k@apI3wsgP2taS@89&}AAkGdC;Rg|GBQ#t8w=(Zt@ewjrzTHsx7x>u zbB77I6yz*3lNiIrL=OR6w73s2U~;I9F&TkTiY^kagsF%R6_YtnNElKnBy-eETF$u# zoajwXFlxZhzxAchJ%}gZxfvN5aenqe%fR-_3vcfb)f1fN+J*T+i-r&}_a_PY;+&)B zf$4s*2dbBzkU{h~0Eb?l))N~XlZ8VLQFt{OHGopZkXIJtAt%i#pa_|3q9ywfmL&QZ@kbw-+9|j`;=GtA%`tL9LD3#?ARXZb)sJP1Ovn*$ne_~fkCjz zocq$-FZ$ET7_I!IS}RsGvlCaGID7HpWv5QGi_>N%r(f)?II}E^m(uLnBo+x!kJF$k z4l!yYrOWN3qKdZw5LNRPk*)fJ6csfRN?M!=N}`1DPGUBIWs;nDyPH~f(w{~g-3$R%uS_hT(@Q7u zqN;Xt0V3>QSprs{w3`Vci9{IuLAp`u@#PGW#F1lAi4uiWaa7H60S_=@uruA^$=Cki z{+B%G#NvhsOKJw7W$jH^T1qVDlv3={7jp9wfh<4 z6T9D37R8I`ZC;jTvxFF+F|Q80luV#|f?eLi%u`&~;S9Y8V^DHvj6|^jcf!odg(mW1 zik#}bT{$y7`PCPn{+gc`b86eJ8y#)!3-{jvz7#1#>T{L*iYlHtsL%0LH% z%X9Z+Qv%3}X46go@a8!!`PqIGTLzbTmTxuB)5u~$VI5IJBDMR_S_Ygy($Y*wsz$kb zI`5Ni4VFA?1x9i4B(o5xqXvV4p28`GjKjI@F3WDM4>rEu$lUb@E}Hf5hd%V7j)?GU zPw<6`+WGAx?|9E=idLuNeYwnKwfza^=$-wipGG_&JUEtG|CsTGD%70a@)AM4t1u>~ zw3PTk2sK6yM@l8xWmLz%YbgSxhhkXS6OciSKog1wsL;HoWzl)DFN-mUAmV>g#7IQWr%lWW#oTxK&{c1>@0w-Ne32ZjgUFn9L6w=@QaK9koP zcV}5Ggp5UIV5|WgNUa>oRR9eFZHrqx&0vA9B!D>Yq28brIEZs#gos5+W1~GYbN=+i z*XcZ|p5u{`5nX)8 zw*4~SxyahZC&njseWYx+Plx$AfC8pQQ6m5)Rp?u0U%6&m z7th%YTnVSCl8RXewII-904pBD{ zI+h^)f*1*Uf`kiUIwZ=#l_D`)zyWI)b3NPt<<5ILW3N8{PrpAoJ6kvQ$xpVPFa)43 z?Xt~Q(5#!Qe5)#fMEoBnE*C&}wLpl}8GUl}1tV{L>-=4tC!f7_ynP1k!37Xm?leEr z!Rjh5WZPP0QZL&U^kLkHuc~5x&TAEiCqoZuj8UweB$XbZ~ z$~nEWUTgdUo#EYM-~LeN5r~xgOkp+FY?fzSa>>KP?ZF>{{vSm3wIX_|ii&6O`ww|0 z1{zhYiaJlan{aKI#s$7x-_XR^m6t|+U`z-N^#s$@AaV`6k*TrKw`y94C{`rR5~!C& zJy6Ia_dZ?SMqVE{5GrpiFgOU{%KldQJDRQjCHS3qw2Z7=smqrymyJu7$kK-&_Lp9I zDSJBA{@RD`)vAjx&K}q{wSTK9&+N=h9mmp+66X#VU?D^r5P_$e7*zn5o&GWznbMFDcaMDwKT7L_l%w)-11mM_B%hf*Z!Z@udw<#ASHdYhM2%-!5KPc8XO- zbM(nMk&y?#qCC#(h)?AZML*!Q76O$9O4@^d(r$Dj`gg;nqjiUQn9oRaXo?#Qjzt)aSMQt>Z)Jgh|2Nh)6@nlMoVnxF*7 zRpd*c zbrNABe8pK~w{6j`ZVn7SZ_yW3Rm6mm8bGRZ5(eo~0K2h1n7!`D-`=-W0L^Ao z$2M%J4Q=fVw54+bJl-?YZav$)Efy73IE#~cmb4UhAP9za$rBo4NrV=toq^w#KK%fAW#(*WSOpO|%gYE7Ut7 zx)L^FWY%ga_qD_SXLsE-XK37?J#Fp3ZnfJVY_+Cd1mgmsLOjgO=*{SZg@eGv0ivoR z;j9u1(6bt#28btNLcj@_iI@w+AoJb>l-x>YG-;{J?iv^v`Y!|Z!MD^@|Et#Q#+`>P z-Z8pzr9D|CXVGfA`r5Z~db2XSHm~RZLnyzX(ZfN+%rwaEpvEZD6NcG9$T?7nc^wio zw8@Ces!>3421>U7(ePIgXauoduoROX-l`Y}8Y}RsVj%#pNF;*jUe#PP(BBXrdG(1B{q@vcV`E%@%Pqx*yKfzT=3zhFrmnpeYWEv(mqO|SEP|NQ z;*J(%;gt=!M3}g%8I&q=u<}d|tf>TGCYV_TmfR%>S2bZ2J2Lk~OFZ&-i(LyyO| zeaO+r9!Ad-=y7~y_DX69NRUeH&_%+Tpm7t}!*$}y2OhX*a$mTG=biVC{qDGT{R?L% z+81^@oij@Fr-C?4LW^v&pif)}z&=+j@1KBfiKEof4@^$U%)WV@=rWV?wwsUR^ z1YcCuD>Kc$)fi}eZ`L!G+NmZ@9sqeC*3-{Gi_=9vQ(| zLL3M~Wg1)&8KbKv8A*D{PFuPr0Ett99x0$yU1vn2Xi^9#FFf=oneB*xn_JGb3-!;kx_fJaz;5@3Hl9pC_7a}C-6){cxc@4~>QMO!vK zywys-OT;ZEcrcB#t24ej$*YzlZE;B1r)sG9PpPHqhNjXWqMlgFqCDTZ{AiE%{?C8e ztIXFH+N*Kd_g+#W9U0`wZpGSbw0n1Ge*ZQu!-K`;fu15mwJRUT*z z)GnWM=s~w!@%MkdNV#6*;qt{zm1u5Jd-+E&xy+{-~bVI9!N^4uPW!ak=;9=_Ky} za3lIEt>0Mv5kP-Eofbz&o1M{5edM9jp8u?W7?`!_ZNu~S`@34Lez$WDA|{D^qzD$L z)!~oC7K?6z(Zm#i9TksS6{SMp3=G3h(M)_<9&M$6tC)OXKw3v`9U96X%grcc0K*Xw zv&h@h$Y6-p3MvpKREUsW7Yr^9qSndtC(_SC1`arGun>K|03T_$TmMj&#p^+vl{*(^ z!30>Ez=z>|Vr*6ie=>HW1Zcp5#gPHlKo`tp@GjDFw)Gfy+JFF*Hx-hXRGUgezo6rJA+@seDC6VET@bV4NfOGGlPMsPq? zsxzG?LdGf}cyh;l@6`HBupCY{l`*DJV~$`T5wMB~jdPbs>7+#YU<@z{gk1%wnX18# zFew*bam5w=v+faAe+1B9Ps=qnHiiS2oY;1ae50VeDa-U%F3VMn3rMTe2nc*nQkg}G zl8B^VggGijB)G&xXjviQeLu!^w0vkzu@!|W|Kkg%dv(CC;-oeKle_m^R+uPfn&KpP` zCcuDG6>&me1wW^W1uTwg649*sMnnS(Jvr1kr{+{mM4YHb;kk#)bVHV9S7k2$TbIj~ zqI%Qx(aUyz@@bmfnbwJ?yP2SQ!r7AJXAk22eIjH9FWl5FnriW+zEoZNIe(TBT zZrLvY`m4VlgSBD9FU$3}-#GQ+=RbQ>X|;zTvWez5f+!&vBCSEt#qBGlok|bxA0f(U zQJzwVDB-RPJypS7urE9d)&DFL=hn9}je<@B7MCSL}YO z&G-M1b<0nFQau0U0GCoQEIP*=O=?{&mAjPH1D3h@B&Wl)_ZF&zcHx#g)}F|hKLk7i~O zktQ`HpjG&Q(i!YIMOiGBcDA3DGhctfE6(}FD_(HYre?FbciH#s{dDo9l*+lFE4vm( zBt5#XJx=Q2(@(!}sC1ph+jea{#LDuu=Kbs7Z8lY-Kd}XL!eSs#Ix@g8x34Du2sm*# zmP8auBn}ZWH2h))ouY6f6%V;gzrS?ZGd{Ag-kFFty+D6PyvJIzW=#R`XXn4=J+oCX z*NiV0)rA1+F}o+wVB#1cS^6g5-rzA6Y!^g82|?b$TTmckA#S}lPBzM-n=c!iv!>v~5O=an4g$yTB$sr%3OocrRgz8* zpeWUeN#L2J+=LQw{xZj244r1CBlw8r#nAdqkZ zK|!H4M}p&}=dLx)i)X6r0kVIuAM2O9zxwORyjHDRm2YjeW^dm#xmK?h&TmE@xgvSffK#oQV+b69d#bSIta21+`gVOy7$UfO8-}y1=yt%NL56zP%F2)EFT*fbieA~!F~bIU;Xv_ zuV&M}1Kd8+Y_6Za?Y?JE?A|`&%knkivi&8zKbpMdqxY;q@JaI5m&yN7F#0Fv;ad7W{O z>M(p1-M;|9iWMuIug_m3R=nJse_f|6Um#!uDH;Z;(@)j}nnGt8jsg=uqs4FsDoIm4*!+LuY2+#gQ?4enmJQ-7FCu4h(<BG)ON+{Hv!Vt-%qXNqzX3IcLdBV=dQoL0y4+H$4gTZc>?ND}_wTo_z6`Lx`s-1y zyY9NHIO(M0r%>qj4!I%A@@)_iqdy=z)M@N#1JIua|H-#BgqDdUG618I2?A*<9?*3G z<`y&d4C%0S;;Ap%e&=mBP5nM!=V3=LKg1X1vA*=ric~9fIr9};JH+KlWd}@v1tAYP z;!6)bbnm12H~&Qr(ODO~bKZ2jd`YK0^B#aN6~R&wsne*8y@ytg1dI-^k^3!@VqPk# zSIUMBY7C1f1_{CLJj=f5oQ}fj)wKmfKY!kFhwuF4hdW0!BwYfNjlY^Xu2$e*XjI)bvJLIpe_- zgj^s{DT99yQd$rh2+@1E2PFD^j5}ef9Kta@pT_gN_Z;80IY0fp3%@%jYwa2x9ql}- zwwpmb6>AGdCzYgJ=t2NJyR<}q_xKt9sB3h_8JE;Cuw&8gotsakFV7X@>*1nMKXCRV zRE)$;2&Y64hy^5|vUSnQ5?(|Zat)E3=O+N%WAHz(HwM1Y7@Bj-mp}VYTSSE4>OZQF z`FlX}hBv`nEsQ?W_*ZDV1^<&C*H1!o2Ej0L6Wl>bmUmOP{gInw=VKOD60i>tOkErs4PyE$?-rB!YzXL7oUxNPXuit+)n@xW6|9$+HSqmGVnlpdy ze<65-k-KQVB!%!n02N{O;CAXHS)?*}2ZDs7K zY&IX&`}+U4ckV%Umt~&+exLXEJEu=ya)AU$M+kD)pdwH@IOP`9D!5vJ?oM2Fso7n( zHdE{Dx}!CFtEth$R_)I2)-dc2GjS%MpczM@heZh&m&+JLWVi_eX-T*kF5wbFu6;Y_ z{NCr;Ki>CuPCMYBBbYQipH#Zi-6yB}yua?>`@GNP`_)J>B51#1E~R8`pw*V#T@0Wp zMUAM70KeGo|FXxPwsvhf+kA0F)r%jfs_uV?Q9lKfkf$b1RqKJoS^<_wa{PVgm=vXm zW~D!)079Y=S`lazL@8unXqFEZ!$V(by#KwwebcoQw_f{=%U*bs$@U&lNZMci*~NDc z7rZ1CxQ(XIK{aL}3`O$nH4Kb`vayfV{Ucd?f_*RHln&DzpV~k(sLl%{5rLFv5P~#G z;uQoT6%{*K+2vu^_G|nKy*ge3aGYO)BbF?w77vf_nbpn@1G$SuIJ_5oOVzZ5Wq-PQ zNIBiOB5I#B3YmoJCHG9#t06|7zdUamT*>c#ZL0 zF~)b)CV0ust(MN?z-k5P@BIc;B%T$uYktlWz{@yk#qnoVozB0SnV$MhtMnLxWl@w? z9|Zg6gte4=_Lj}xr==zd(rQ_G(kMa(5i=!&>@AA&2aTfndkAvX@G$SXdEL7G@H+ni zW5utX-WfG{ND(Rn4pFml)~1sraR2a;lB(Oy!)FQzOvu1%&X%i0LS?y*tBU=1#Fr+^UO1U%&|k&qU>li%2TRt zJPT%T>$kWIlTbkJfwFp--3EqzLPlmWAv1%R7{D>YR#%_-vo`|ewM}EBH`Wu`J17ohu*ewG)}$3Jb(Wc z{;Vv8^IBkaYd&tgE)M|DD zs0Ue@bcmC`kO7kXo0LS?i2Ljl<=5wEWqPt`Iu9tS~ zoQhQii+WP(RLWJt6hO3Wul}+Lz9eR3Fsl7xX~A~8Ew|oz=i$An-svK;HdfWiG>nF_ zPz7L0s43q1?1Uk|NRt`7Fr?%Aui+p)q{>cdokZ@mEXr*9~Oz z#~q#5HzK(5&n|lK+~4}$js%XOviF#8pPgfU zBY53-g|#JZFdfYn|7NjLyT$)hw% zAVMvgX^f^-R6-#ZJBZyaEbu!WTYTkTe(8Vg_RZfj0FHCOPeUV^-qjV}#76N+5WgL( z>b+I38Wmv`LLh@sP05&Q-D)hzTIwt}>E*j>ox2alCPhw~o9XZzqB#H^W@{nydgVu2EjQAtu8MbX93(5t?{B$Zq)+WORepEK2u znBnk3LNE%F0&)`T1pqOqX_Y;ZavN73M9f)X8V#mUXaof&p?Ib>GW^#ty~R}S-Lq}U z)TT}C=r{O-|7Rb93L)D702F~qL_t)f&Hande1E7IdM40r(JHPr!*L{AMG%XoW}0$C z5DB%UkJQ>hA`r03YFf!hBbopy7>-p1DTlTODQ>n(uZA|Z4DH_RBcFc{ya~{8UI!*8 zC*yB^>f`&-o7uK&rZ-1e0b(4~G97)S?)GEtWy1L>`hlV<2jh7(5orKCijc#9NO$;RH3jL(SfXzAYXMmOJbQ4fp-Vf3wICWHyLAX)?EQ`%iv$6X2RP zYZ^~Hv*(0;d-q-d)inltJHT?DY>TjO&0DJsSl`{X?~KU)%y%tPq#q=0j@wZ@ay@cOznn07a2BdPK9oeG<7rlD@@29zAQO5kNFZ6hUE?Ml-ujL_ROE z*mlPq*G{$DZMNHOJ?lf~pHo%(&w9P;li7qN)fB8>if0nw87QwSB7(?n3E}%1y8rsF zTW@_O`Bbi1vqqlVRUNCbdv2`s3lt3J{C;1k9sOdi_NTbiO#6|Jhz)wcK%uA^)QJ5> zDVs&Yy5+~LxNc(Ix@kZ0FZ?}b&6=wu9CrWdF?K#sRn^&Mc8IAhC1eSU&@f4@evDeH zL%@V83InZ2U{=W8MJbz$qWJEj=E#-d$U}Bt^4ZV&ssES6djK5g^}Yj=*4@KRtjgbQ z7R{T3;6+1KSkQrHYHEZd2@^^*Wt!7Z#;WNc9ZgV05o0%>lHNn;S5b6MsW*QBDB0)* zN=G7+jJ}b8hCyFEO^uqfwV*Kf{~3)4z{t-!`ActPWK4VAPiwUQ$RMMX5FmtFq*{`D zO`(NKt?!>Qyw-O>AfPm;2rZPsC?-;1e_0lH3BqTVj}_mZSof#C`M*Kp--(Hj$GGFM z`=RBZG#3>YjE;@`yJo9#X;I)&i`8E1c6(NJ%`8TNbpy~1W-4N{LHJZrl(#loL%%;f zI`W^6XdHIgVI$aa$!9;?^`-R;fa5Hf-?cN=tQl&};vH4DdtMcLAFit2JA_3L1_X*m zQ%T!1ENb#K&+jJ1ytJ1ZMPfR{n;POA8773d>H}xK=cabMt!JON=7ZhY-lyhfI~Sxn zs=-Vp_tj-hfPn>@8L3v8i0qdTeo)4tPv3s~)z8mw^g8p*c2R|Uj+*ZD{(XbR2Ss>1 z1ccV^hSnePsw)fC4du0wN?}CLugP;VmS-Gg?&lY}~kU#(!Mikf|`X zFT5~potqnr`{s_&sH>`qV=!$YpebZSAPOL=pc1ob7^jM|*kzO_W7*q1aq-2ozL2jS z-UR44zoOgUof8wYW_HinANdUhIH#ttXvY|IQ52~yQ))Ss9H7^ty=fOUkZKl^N)7@n z44c_MjE3p&-FfehGtOA^;}D82q?*e!)G`<~oEP;Erm<@~)+7#S7RXq%+ZVFk?w`Op zQ{A?@n&U?$6u$wn!*esY)z6hAS*_OVM_+|F>%1hb7R|4Sq!5&_i@=X1l-DyfZn<^i zhWov9{|%iAvo=rx*bQJ$yWQRbK(+ye%(TiX#6~&Swa^%fvoTc1j!t*J_{A^AI*aBD z=otXVc_YLE{Ln}LG;=?+#opWbrW&5xlC`1p}ug6n7OtKE3kL zk!P~+0pIz)_br#I@oz-%du7=yM2b3-ARN3TXiit8Rz{Vi?MhIjKY~C2D8vZaC!xH% zH9GRu5ah3Kn7I6fR~#*K9LF;Nj`IeJyX~oR&9kefM!(!>#!j!-`B+u;-mfCcWF%-w z{!Z)iIjui0rxpY>6E!8GsYocyG`_Xd>3wWyWOS<6)4gW46m{c$Rw2^*6qWJNy)_9Q zf&v6UO*It!T4SU!(NTFAyN;fkzxkW>m0mp{a2yW+9OsS2gYnd!4y|Ty?v9VHgD|b^XBlQ-$+g z*6Qa*8V*zhRwmuDQ~-ARuYc%7HT`5^)!9L0T#AsSdHchQ21d=#N=vW7bp47|$F5YxM~wEFG8E$yLQ_bXQL<-Szl*>IFDIoMlBKbrew#!9dS1v6fk9^(H=uG+wD*y@2jGOO{25cV~i&3&cFTdFFap=PUuR+_<|I&ak$ZWY2CVYuG;1}9soFw0|1kglX(1*2WO5w;go%lI1Ta$ z8b$$Y%`b_koi{1^5}GW0^YC3x>LxWD%=49;2>M zwc$FckNJ*0MD1u;d-~)DSPoL4W)Kl}5qKYN^~dvbnV_~)PxW}@hC-=L zh71HkDC&y7S~Sa=0IB6rnAQE$_MU}_EcplK07B|MMMi*1Ge`(O3PtgaP`&GtO`Elq50w>z{aast)!Xevo|IA_|ZsE>O+01?F%e#^XWit ztQ+xbnf}z7m+AqQBLkuk0YpsIs1`%Y4AkDi`AzLsWc56O3HvR81PrPM0ZgUju29H@ zOIwG3{id5P>Hrtg4;+qjaN%A6j&ty20P26*rcLb%&BnJB{4yonZ{(~gh1uJuFRou3 z($wKC!VJA;G~dTYGP%sg-u6Hdq>T%vTy; zVUl>?^=1#aE%6y8PxJ6K)YBNSy>Me@%KSwB&nM;vxp52}F z3lCR|uLh0d@*Y1+Ubkbvb%`CK^t-cm${V*^kTtSItPun_)n!{@yLt1UQ?F}OD?^44 zSA==?1)per^vi;bTH%hCKVB|-nX>Q_r@Guu$b}oVS%K5fJLT6aeil5}y3bObxlNyBd(~n8O&9e;q}ZsVm__?^(J}bBI}v^2Cvun zD>;t*Jp6?nZ|CUxHP^46CmL+~+zl;eT*oJ+V)cv^*V7Xa^mx7ul`T2TF>N>bUh65veCYMqHHsayJxiNyC+ZIg|Y1%c%0rZ_X?X4_jH9NHg9dZE-yj?LCl zm+9g)W2spCzO+G_cD%~=;Oku^Q-TGpb#~r!?f3I%JQb+q#P~NWNzsK%NOu_~`UB*h z0;>##(5|aenL!gzx&k@Lb@YpdC?*coG}}9rp! ztnG9HcyDiu1@yrWs1ua>E^CoZLiZl(Z*LP-A>{GB{1$cCLZhS3S2>|t>chs>AC0Ui zfBExMQ>UoObr&ZW2P?E9=Y>Y!6csI@>2ehgx2$tsRG5O;b=+wCR@}1SqnYjZj*It( zjvrduy33S`|7cJA{#FSaKa&r35SeBA*KJ>q?qY^Ct-eV1f-!MaLuoHC6KB*~{R)@) z501LU<(d2g^#!K-`a6OcoVc@$0oh_CaA@wZXz#!)!7LBG1NNgWA5eNSR|DX7V(4@N z^iLISV%pd(15K4lo&8e`(+u&QqiSjq-4nl&V<~Y^(qe)$_w>A`E3X+q(Fy6SBz)7@;EJ?6|h_$&YaflKQ)AT;M)k)y@!GpNu?HFa|oBccUV9n=l=!~;atzdNC1o=(Nwb#@KEb39H z@El6|VKC_7&008{LVBpc--9h_@bT*_u9S+}3cIr>B?V;C4W4abFZaLt*7H@K`%&bC z+y#v5Iib_(aRo9iJ^AbPH`X`4Uzm6Afed(BM7Fk@nb@MzzDmS8D#wf>l0wEKcD%l< z42H?~@chYTIH^8p;oaT$HY+#!24WKwKbU1& z^4&-4V;yK@oMiCaUj9uo^=BG%7w#38g{0Wr&Sx$zk#>-Ukfg0d#a5D(5Z^Ege!eL5&nR*Tt%n%Uk)SSB%mziELWno z3E?6PkaT(r89ibWNuFNvu%>Uj`UzJNTdTLJsKr@m)0$BR!j6x15+VrhKidH zCWxIIEJ!$H0LJ$>1lpD#9^p3DIv1 zN`&(hY&U^`MoJE~u+RID(ie^Rwc$Vi6vBAHdUs|13@JgnBX23(c8hRu>z}ev7o?YQ z0z)STAZOV?nGC!~{GBvHxIQE4Qe6mVS6z%x)O(E8q!wu(U38Fpxq0sN&wX$$KxIeK zf9D#lH_8q!8h0D|dkhc1G3vZRdahEABKSS+eJj))eI1m7_z!S)_#!NRDkz9aaKP_CiV{^l)m7$73^_or66RTq=?K}vcP z{qXy!GN(l8fAB$bcqx!VvA>>k0-S$DsO~a{`gWG2NQ-Wu+>YVcdt*v<08La9RU;a7 zJhl)jeYUXXK>S)!v2(*#!E`vl3zpCXzrJ_(jx6qXGI-4G*C4>@GhE`!ISLK}NP@9o zvP+T1@W{0#imc@3Wf!Fw7GRPA18v1eq0y&B=|?EULVn1wOM&QLd*Utl4E@8|h1iULH(cZz~Op2pL!$w1Wfyd3Pl5!BS1CAAg8e|Fi>%Zeb|vF%oy zGdk??INeB6w|iIUxV&@=fATk*xF4>8tmT@W*|DO&5zmalLkUFOB-A%V2e#4Qu^g;y z!EISxZA@zMPUck>F#RcM)SWvW7RefUjHx$OAlwmV_TT)m~ohL6n2cQ2GC3 z%)2wWf{DtL%&_;Lp8)`%dIfX#il5IFe-qzJ{=5m$L+BmjJs#KA(|6TFm>e}UIf~Rm mAb5pM#s%{9{)-?e#E%qk?SB(gpHofd5dc_>gLM_!oAxh6vK}b_ diff --git a/docs/assets/main_cover.png b/docs/assets/main_cover.png new file mode 100644 index 0000000000000000000000000000000000000000..1cc3f1f5ddb823d7b6d006c7b24f352bf1337a3d GIT binary patch literal 454701 zcmXt2j3ql` z#>kR=tixCaGh^(2KEKD~`|th7{kZSzI_F&HJYTOX()f|yMK&Qe1_p+U2Kq2l1_owL z1_mYuR+h6TOR)p43=G^11~9EBzKrXc(RK?>o+0(bW7~RzZLRYPc{iWE&sbkFy6<%R z3MT%uT>3P8;)J}hv5}cwS64@`tBdu~iF8-?eY|9?{~wBaKcuCl-$Dz==3CHMq(`Z2 zX`zEl(JekU5)FhbVEa-4GBNq-{-K()-qQ5x$&5=cUp`+LM%|-mZA0dPhNBINaD3b< zg&rMHN`LxpP=c4jj6A1rXxLWm`~0K7R5?ml#oY* zVIMt_Cl?`aYO8kS!?T#41TOX4>@vT;tRYX3)k}*20AHN*}IR-!TtMAjljOh z$8pB{larH&87*kn=DNDL2tX6sHDHg;-JM7?i>p07gl4x-DJ&oL)@RY2$Vuq!AjB`l z+35M_w~;+1JlUPkph_N!>6YO*AyJ_WRzjUGvT+1rQ+HT<_AdI!eX?+C%$0XEw8qaqe~y8+L;L_z0&C zIc6feS298l%i!RT-43GD>2=BjjAV^JxUCae&`Q8-clY@Yx{vMb%q$W$DNf@r2Cfc& z!iZyEK!kW&r5n0{Wb#**hTW4&^^6;YvmYzHu$<`ju$JzFcrs~?hcFHFqx6=}A`y`H z!g~AI`XIDUCU6XwUaIN!U0F)hcamD?qmzrHk3XWV2am>4;FvsTg!D{vtE6l2W|$&2VbqaT|hu<1Hj2XQyZGbJHIea_nSbw|IWC z!aM`)RxrebykOO9^5hMrH>dVp zD(PhXFL%Ye_bv@j9&S_`zAs<_r1ht>qW^eX=S9W_)YuA@zm5qAI*E-)W9_Jbn>=Fp zeB5xmmAE4Ql0iIw4JI}Kmai8#)Co;Q(^Zc3|-)um!@ z%FJX<*39Gda21ct*u-u1$NEmgi*$7EV8?25%Z5ExfFf`sGwL)>PEg_kFF6JL`3ViN9naIh*f)cUSId(ulYrR}c^*aDM7Kho{?Tx-p~Qu1(_Uc2J7=L&q7eCH9sN7w9f2_uSyorx*>W0aH=5@rldZhDgV^(Wz1;`aW zHf%Q!#}f)3UCd$JzENuzjcXk?DJT4a0BWM9#j28$(**J>`! zIZZ5r-AC1t!wa1j;Ckr8-44$VbR%+!VzbpISA4?9k3wu%$_7vv#M_mcx z8o>)$?>(#t zO&;@UHX@x2{k?rKR~??_G@KqlV6#ssx|~oy7r9Nyt{u)J+lk&qdM%<|=M0U+FD4}d zMh`zZMXEE6NqzbUriZW)KGPiBFE$HVDEUpGMU^mgzpAB#1H533Or5_PDYE^xbjYnZ zbNdR>%!&iYtSnW>-6ru<(tef7g6N$P9}a>_2b6jCJ#hNAEg(o^-z|RFO-#$BdWEg1 z+XO6qq*z*9J0P&lVGT>ax3E*T8u;btKnHfvS$KRvTjRbZ?DsVwK!f2~_t!(+x$q

~=Bou^@CF@JTRalVz`8i;o z?s$C0y{#uP8F>;cIgoP^kZe(rtMaW}JsOW$D5C+#ymg~)fh2@gQch<}$%?3E#h|l_ zeX>EzaE9(;X+rk38CX+N;;hcyN?k?c+UO$-7lF)*rSguq0QbMR`|1Dr{KZstVWhrs z#ue>2o%&f#D+m#0L@3|6*{s$OrwrRKSNdFwPo7jc?=388tEz;>I%%LUdAea%jXs%c zIK>eN_!u7Vs%sDfQu+Gx+P-RLA$qq$h0sB_^0Qk9b&VXGypRI}X%L{K4WP(G?qP4U zbHQxebGlvA1SNZp#u!zoYQp7bF;NnM8gD*)B z;MO%=^i#C|R@Y-hO^dvzXizoiƘTU+4r$Lt1^EN&GSNU7c!$b&ZEf7jEZKO?hv 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⪙bC>j6)-x^&L-(F8T2{*m?Lm$lIqR9@wiq>81Uh< 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

FG6d#y*k*kjRQ6O5SSv_4V!W1T6Gtlmzx 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 +YCnMuNrVNhmD9PsiJTRT;)`0Sj;c;V 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

+U-4vpr%+@<(pO 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

x(DtYmFG+ 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%0ACXC&ZY}BTnRcpF>ZQ3hWuIQg1 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 z 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%0D9vZF!0 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%0D5Ks@ux?MY4? zTA6hWlWb@m6M&YTD%-OjTBa}$ZPyr-!k{1t6Bnt0cus2D#)Zj8c%rtR@Wf>oC7oPh z$g(mK=^52HQ4d{oDfOXPYMu1N!Luki)Lc6J@PGCoP^8)T!Iu&X71neH5+)yEiISdp z!l&YO=svf04C$iWDd~yJCRrpo(PX;%&h64uyPW4f!llbsJn7<2Gz`Su=vDChvWrW! zVrJ|w*6@=FKTL9+bKt$2Cz%LQoomOva?BevRm5XWf8s_$1n3W#0P12`T8`-?!<_FA z>9&U=eR47w2WDPVV6mFW8q_G60FwA*L>Cr$z*`w>@DR6}lM$6Bsh`?tuII8^O{L3c z#%Z#(Ae(5$JDr_?z4_}&1A9tl?EySOG^NpG;po{EN8#pZ}6LL-YU) z6Q`~j*ar@HAJ$rDJ6lzOF&wRL*tPzpu(-j)8?@z1y6#y|ZZ{&C|Sxcy)Aus|<7ZJa?x6?rP2Y*HTN_rVP4ufpGT`)&B- zXFm)0Ur|p<=)4BLgB;=K8!nt@(7eeEt3r|avE;E?<~fyMP!qf>G(_1zZN%NZ1WZlTG zWmkwqkX;RAcpXs=GB6?X|gq+Cpwma^jv? z9V6afCTrcc&9a`)3v=x2E!UGQF3KHy1I zu_?t@+!REZa`NtUQ6p1W_CG8)~aVgAh+9{>^O*}P}-lk*|*RUtE z%SU$cVWb$cB`$ySwIQ^hWJ^dcCu}mlsQ#11nl+ovTI3}gxNowlq;XM1M!H9cJh^U# z+itxDpF8qPu0B|`XCO@?ac+!e(mQz8uDjy(uX`;5Kj;L0ViHOZ7ELsn_G7VTe@1JYV@F1{+WKLZvL3B0{hk(mptDi+Xl9HsxGpo&Bn18>WE*-e=i zqz^}mLrBpBTNPyofvf$~pFR{j?X)8nEUcjA7`lNdg9MPXf)1lB9?8fOF$lF-goO(D z^Pm1gAho5q)E8ap%3g`a8G;WijX^y49LOsX9KrMtHJq;ZqWDfXru+gc5!s|=Iz9se z%qo=Ur1=r04s%(4q8zLJ1Us?P?bcz+&RdmWkzj=qC0VCF>AhQX^ww(f<ZR z$thlL6DCre#3kpHaB;O2mtC^>bVzLyO=vd(K&2bnbmGpMkCIKnnIDVRw)Pl{0-W)g zGxtPu$WxX?kUMnvz9m>nqPCv!`-HT<>?ET-X{6UmUGF; zPqOTZgeNTVWJ`MDS{cb-Seuef?InxklepwzG##H|ZI>9Xfi1DlmS9I3mq;gp`+}Hy zulUJ8atVGGEed?@3!k0UfBRE?-akpRq|6i7{kOo{>#T#rIcMd_7$5KWK__%+&_vgy z`z}SjWY)E%2y}Et$C?jfY*fRNV%sRic9P{F-pffyv`5U_(IxR{XHASXnvEYkyon4V z>PnPrMN&g)zjfaRT{IzuPpz6*5=6;B-lx_LYewtDGMR0nca02aGytld?=|Zi(u8RJ z)}qheZ|gI;(tLVxZR%=RyhVz`AX*fnse5dBOft(1iCa@KvQDvi}=OMW

?R7 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

k!mU#{nbE0P*>Gg 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 KMNUMnLSTYBDvXK% literal 0 HcmV?d00001 diff --git a/docs/assets/poster.png b/docs/assets/poster.png deleted file mode 100644 index 4efe93a8d69133f2fca0ad886ebd82bb121ac32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160079 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

m&(xRyjf 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%0AU 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 Mbpy?JS8pQz10Mx`WB>pF diff --git a/images/poster.png b/images/poster.png deleted file mode 100644 index 4efe93a8d69133f2fca0ad886ebd82bb121ac32e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160079 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

m&(xRyjf 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%0AU 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 Mbpy?JS8pQz10Mx`WB>pF From 0e2e9fb2ed6734f7e184caa33e72209abe029320 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:45:03 +0200 Subject: [PATCH 68/80] docs: moving readme files to be outside of the website build --- docs/requirements.txt | 6 +++--- {docs => repo_docs}/README.md | 20 ++++++++++++-------- {docs => repo_docs}/README_AR.md | 16 ++++++++++------ {docs => repo_docs}/README_CN.md | 16 ++++++++++------ {docs => repo_docs}/README_DE.md | 16 ++++++++++------ {docs => repo_docs}/README_ES.md | 16 ++++++++++------ {docs => repo_docs}/README_JP.md | 16 ++++++++++------ {docs => repo_docs}/README_RU.md | 16 ++++++++++------ 8 files changed, 75 insertions(+), 47 deletions(-) rename {docs => repo_docs}/README.md (94%) rename {docs => repo_docs}/README_AR.md (97%) rename {docs => repo_docs}/README_CN.md (97%) rename {docs => repo_docs}/README_DE.md (97%) rename {docs => repo_docs}/README_ES.md (97%) rename {docs => repo_docs}/README_JP.md (97%) rename {docs => repo_docs}/README_RU.md (98%) diff --git a/docs/requirements.txt b/docs/requirements.txt index c2c5d54..52ee54b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,8 +1,8 @@ -mkdocstrings>=1.0.0 +zensical>=0.0.21 +mkdocstrings>=1.0.3 mkdocstrings-python>=2.0.1 griffe-inherited-docstrings griffe-runtime-objects griffe-sphinx -mkdocs-material[imaging]>=9.7.1 -black>=25.12.0 +black>=26.1.0 pngquant \ No newline at end of file diff --git a/docs/README.md b/repo_docs/README.md similarity index 94% rename from docs/README.md rename to repo_docs/README.md index b4d1950..e34a85e 100644 --- a/docs/README.md +++ b/repo_docs/README.md @@ -1,13 +1,17 @@ -Automated translations: [العربيه](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_AR.md) | [Español](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_ES.md) | [Deutsch](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_DE.md) | [简体中文](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_CN.md) | [日本語](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_JP.md) | [Русский](https://github.com/D4Vinci/Scrapling/blob/main/docs/README_RU.md) +

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

- -

-
- main poster -
- Easy, effortless Web Scraping as it should be! -

+ [العربيه](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_AR.md) | [Español](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_ES.md) | [Deutsch](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_DE.md) | [简体中文](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_CN.md) | [日本語](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_JP.md) | [Русский](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_RU.md) +
Tests diff --git a/docs/README_AR.md b/repo_docs/README_AR.md similarity index 97% rename from docs/README_AR.md rename to repo_docs/README_AR.md index 8a21afb..0463398 100644 --- a/docs/README_AR.md +++ b/repo_docs/README_AR.md @@ -1,9 +1,13 @@ -

-
-
main poster -
- استخراج بيانات الويب بسهولة ويسر كما يجب أن يكون! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests diff --git a/docs/README_CN.md b/repo_docs/README_CN.md similarity index 97% rename from docs/README_CN.md rename to repo_docs/README_CN.md index ac83218..93fb5e1 100644 --- a/docs/README_CN.md +++ b/repo_docs/README_CN.md @@ -1,9 +1,13 @@ -

-
- main poster -
- 简单、轻松的网页抓取,本该如此! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests diff --git a/docs/README_DE.md b/repo_docs/README_DE.md similarity index 97% rename from docs/README_DE.md rename to repo_docs/README_DE.md index 3013d51..cec06af 100644 --- a/docs/README_DE.md +++ b/repo_docs/README_DE.md @@ -1,9 +1,13 @@ -

-
- main poster -
- Einfaches, müheloses Web Scraping, wie es sein sollte! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests diff --git a/docs/README_ES.md b/repo_docs/README_ES.md similarity index 97% rename from docs/README_ES.md rename to repo_docs/README_ES.md index a913608..9c27995 100644 --- a/docs/README_ES.md +++ b/repo_docs/README_ES.md @@ -1,9 +1,13 @@ -

-
- main poster -
- ¡Web Scraping fácil y sin esfuerzo como debería ser! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests diff --git a/docs/README_JP.md b/repo_docs/README_JP.md similarity index 97% rename from docs/README_JP.md rename to repo_docs/README_JP.md index 1427607..f86a7b1 100644 --- a/docs/README_JP.md +++ b/repo_docs/README_JP.md @@ -1,9 +1,13 @@ -

-
- main poster -
- 簡単で効率的なウェブスクレイピング、あるべき姿! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests diff --git a/docs/README_RU.md b/repo_docs/README_RU.md similarity index 98% rename from docs/README_RU.md rename to repo_docs/README_RU.md index fed6f26..12f0492 100644 --- a/docs/README_RU.md +++ b/repo_docs/README_RU.md @@ -1,9 +1,13 @@ -

-
- main poster -
- Простой, легкий веб-скрапинг, каким он и должен быть! -

+

+ + + + Scrapling Poster + + +
+ Web Scraping have never been easier! +

Tests From db41a6c4b6a0fe4ff201a2066a3ca29ca3357d44 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:46:14 +0200 Subject: [PATCH 69/80] docs: update pages with the new media for testing zensical --- docs/fetching/dynamic.md | 4 ++-- docs/fetching/static.md | 4 ++-- docs/index.md | 33 +++++++++++++++++++++++++++++++-- docs/parsing/main_classes.md | 7 +++---- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/docs/fetching/dynamic.md b/docs/fetching/dynamic.md index e62d7b1..007d76b 100644 --- a/docs/fetching/dynamic.md +++ b/docs/fetching/dynamic.md @@ -122,9 +122,9 @@ page = DynamicFetcher.fetch('https://example.com', proxy='http://username:passwo ### Downloading Files ```python -page = DynamicFetcher.fetch('https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/poster.png') +page = DynamicFetcher.fetch('https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/main_cover.png') -with open(file='poster.png', mode='wb') as f: +with open(file='main_cover.png', mode='wb') as f: f.write(page.body) ``` diff --git a/docs/fetching/static.md b/docs/fetching/static.md index 5b2a2dc..22ce625 100644 --- a/docs/fetching/static.md +++ b/docs/fetching/static.md @@ -275,8 +275,8 @@ def scrape_products(): ```python from scrapling.fetchers import Fetcher -page = Fetcher.get('https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/poster.png') -with open(file='poster.png', mode='wb') as f: +page = Fetcher.get('https://raw.githubusercontent.com/D4Vinci/Scrapling/main/images/main_cover.png') +with open(file='main_cover.png', mode='wb') as f: f.write(page.body) ``` diff --git a/docs/index.md b/docs/index.md index e61b458..68185e8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,11 +2,16 @@ .md-typeset h1 { display: none; } +[data-md-color-scheme="default"] .only-dark { display: none; } +[data-md-color-scheme="slate"] .only-light { display: none; } +

- poster + Scrapling + Scrapling +
@@ -86,10 +91,34 @@ Scrapling’s GitHub stars have grown steadily since its release (see chart belo + + ## Installation Scrapling requires Python 3.10 or higher: diff --git a/docs/parsing/main_classes.md b/docs/parsing/main_classes.md index ac8af75..40a66f3 100644 --- a/docs/parsing/main_classes.md +++ b/docs/parsing/main_classes.md @@ -1,9 +1,8 @@ ## Introduction -> 💡 **Prerequisites:** -> -> - You’ve completed or read the [Querying elements](../parsing/selection.md) page to understand how to find/extract elements from the [Selector](../parsing/main_classes.md#selector) object. ->

+!!! success "Prerequisites" + + - You’ve completed or read the [Querying elements](../parsing/selection.md) page to understand how to find/extract elements from the [Selector](../parsing/main_classes.md#selector) object. After exploring the various ways to select elements with Scrapling and its related features, let's take a step back and examine the [Selector](#selector) class in general, as well as other objects, to gain a better understanding of the parsing engine. From 2ae11d21da86ce680433c50cb397a8364d9f2f97 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:46:38 +0200 Subject: [PATCH 70/80] docs: full switch from mkdocs to zensical --- .readthedocs.yaml | 26 +++--- mkdocs.yml | 180 -------------------------------------- zensical.toml | 214 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+), 194 deletions(-) delete mode 100644 mkdocs.yml create mode 100644 zensical.toml diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d52ca2e..774b556 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,25 +1,23 @@ -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# See https://docs.readthedocs.com/platform/stable/intro/zensical.html for details +# Example: https://github.com/readthedocs/test-builds/tree/zensical -# Required version: 2 -# Set the OS, Python version, and other tools you might need build: os: ubuntu-24.04 apt_packages: - pngquant tools: python: "3.13" - -# Build documentation with Mkdocs -mkdocs: - configuration: mkdocs.yml - -# Optionally, but recommended, -# declare the Python requirements required to build your documentation -# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html -python: + jobs: install: - - requirements: docs/requirements.txt + - pip install -r docs/requirements.txt + build: + html: + - zensical build + post_build: + - mkdir -p $READTHEDOCS_OUTPUT/html/ + - cp --recursive site/* $READTHEDOCS_OUTPUT/html/ + + diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index c8b9709..0000000 --- a/mkdocs.yml +++ /dev/null @@ -1,180 +0,0 @@ -site_name: Scrapling -site_description: Scrapling - Easy, effortless Web Scraping as it should be! -site_author: Karim Shoair -repo_url: https://github.com/D4Vinci/Scrapling -site_url: https://scrapling.readthedocs.io/en/latest/ -repo_name: D4Vinci/Scrapling -copyright: Copyright © 2025 Karim Shoair - Change cookie settings - -theme: - name: material - language: en - logo: assets/logo.png - favicon: assets/favicon.ico - palette: - scheme: slate - primary: black - accent: deep purple - font: - text: Open Sans - code: JetBrains Mono - icon: - repo: fontawesome/brands/github-alt - features: - - announce.dismiss - - navigation.top - - navigation.footer - - navigation.instant - - navigation.indexes - - navigation.sections - - navigation.tracking - - navigation.instant - - navigation.instant.prefetch - - navigation.instant.progress -# - navigation.tabs -# - navigation.expand -# - toc.integrate - - search.share - - search.suggest - - search.highlight - - content.tabs.link - - content.width.full - - content.action.view - - content.action.edit - - content.code.copy - - content.code.select - - content.code.annotate - - content.code.annotation - -nav: - - Introduction: index.md - - Overview: overview.md - - What's New in v0.3: 'https://github.com/D4Vinci/Scrapling/releases/tag/v0.3' - - Performance Benchmarks: benchmarks.md - - User Guide: - - Parsing: - - Querying elements: parsing/selection.md - - Main classes: parsing/main_classes.md - - Adaptive scraping: parsing/adaptive.md - - Fetching: - - Fetchers basics: fetching/choosing.md - - HTTP requests: fetching/static.md - - Dynamic websites: fetching/dynamic.md - - Dynamic websites with hard protections: fetching/stealthy.md - - Command Line Interface: - - Overview: cli/overview.md - - Interactive shell: cli/interactive-shell.md - - Extract commands: cli/extract-commands.md - - Integrations: - - AI MCP server: ai/mcp-server.md - - Tutorials: - - A Free Alternative to AI for Robust Web Scraping: tutorials/replacing_ai.md - - Migrating from BeautifulSoup: tutorials/migrating_from_beautifulsoup.md - - Using Scrapeless browser: tutorials/external.md -# - Migrating from AutoScraper: tutorials/migrating_from_autoscraper.md - - Development: - - API Reference: - - Selector: api-reference/selector.md - - Fetchers: api-reference/fetchers.md - - MCP Server: api-reference/mcp-server.md - - Custom Types: api-reference/custom-types.md - - Writing your retrieval system: development/adaptive_storage_system.md - - Using Scrapling's custom types: development/scrapling_custom_types.md - - Support and Advertisement: donate.md - - Contributing: 'https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md' - - Changelog: 'https://github.com/D4Vinci/Scrapling/releases' - -markdown_extensions: - - admonition - - abbr -# - mkautodoc - - pymdownx.emoji - - pymdownx.details - - pymdownx.superfences - - pymdownx.highlight: - anchor_linenums: true - - pymdownx.inlinehilite - - pymdownx.snippets - - pymdownx.tabbed: - alternate_style: true - - tables - - codehilite: - css_class: highlight - - toc: - permalink: true - -plugins: - - search - - privacy: - links: false - - optimize - - social: - cards_layout_options: - background_color: "#1f1f1f" - font_family: Roboto - - mkdocstrings: - handlers: - python: - paths: [scrapling] - options: - docstring_style: sphinx - show_source: true - show_root_heading: true - show_if_no_docstring: true - inherited_members: true - members_order: source - separate_signature: true - unwrap_annotated: true - filters: - - '!^_' - - "^__" - merge_init_into_class: true - docstring_section_style: spacy - signature_crossrefs: true - show_symbol_type_heading: true - show_symbol_type_toc: true - show_inheritance_diagram: true - modernize_annotations: true - extensions: - - griffe_runtime_objects - - griffe_sphinx - - griffe_inherited_docstrings: - merge: true - -extra: - homepage: https://scrapling.readthedocs.io/en/latest/ - social: - - icon: fontawesome/brands/github - link: https://github.com/D4Vinci/Scrapling - - icon: fontawesome/brands/python - link: https://pypi.org/project/scrapling/ - - icon: fontawesome/brands/x-twitter - link: https://x.com/Scrapling_dev - - icon: fontawesome/brands/discord - link: https://discord.gg/EMgGbDceNQ - analytics: - provider: google - property: G-CS3DKLY73Z - feedback: - title: Was this page helpful? - ratings: - - icon: material/emoticon-happy-outline - name: This page was helpful - data: 1 - note: >- - Thanks for your feedback! - - icon: material/emoticon-sad-outline - name: This page could be improved - data: 0 - note: >- - Thanks for your feedback! - consent: - title: Cookie consent - description: >- - We use cookies to recognize your repeated visits and preferences, as well - as to measure the effectiveness of our documentation and whether users - find what they're searching for. With your consent, you're helping us to - make our documentation better. - -extra_css: - - stylesheets/extra.css \ No newline at end of file diff --git a/zensical.toml b/zensical.toml new file mode 100644 index 0000000..12ebfd2 --- /dev/null +++ b/zensical.toml @@ -0,0 +1,214 @@ +[project] +site_name = "Scrapling" +site_description = "Scrapling - Easy, effortless Web Scraping as it should be!" +site_author = "Karim Shoair" +repo_url = "https://github.com/D4Vinci/Scrapling" +site_url = "https://scrapling.readthedocs.io/en/latest/" +repo_name = "D4Vinci/Scrapling" +copyright = "Copyright © 2025 Karim Shoair - Change cookie settings" +docs_dir = "docs" +use_directory_urls = false +exclude_docs = """ +README*.md +""" +extra_css = ["stylesheets/extra.css"] + +nav = [ + {Introduction = "index.md"}, + {Overview = "overview.md"}, + {"What's New in v0.3" = "https://github.com/D4Vinci/Scrapling/releases/tag/v0.3"}, + {"Performance Benchmarks" = "benchmarks.md"}, + {"User Guide" = [ + {Parsing = [ + {"Querying elements" = "parsing/selection.md"}, + {"Main classes" = "parsing/main_classes.md"}, + {"Adaptive scraping" = "parsing/adaptive.md"} + ]}, + {Fetching = [ + {"Fetchers basics" = "fetching/choosing.md"}, + {"HTTP requests" = "fetching/static.md"}, + {"Dynamic websites" = "fetching/dynamic.md"}, + {"Dynamic websites with hard protections" = "fetching/stealthy.md"} + ]}, + {"Command Line Interface" = [ + {Overview = "cli/overview.md"}, + {"Interactive shell" = "cli/interactive-shell.md"}, + {"Extract commands" = "cli/extract-commands.md"} + ]}, + {Integrations = [ + {"AI MCP server" = "ai/mcp-server.md"} + ]} + ]}, + {Tutorials = [ + {"A Free Alternative to AI for Robust Web Scraping" = "tutorials/replacing_ai.md"}, + {"Migrating from BeautifulSoup" = "tutorials/migrating_from_beautifulsoup.md"}, + {"Using Scrapeless browser" = "tutorials/external.md"} + ]}, + {Development = [ + {"API Reference" = [ + {Selector = "api-reference/selector.md"}, + {Fetchers = "api-reference/fetchers.md"}, + {"MCP Server" = "api-reference/mcp-server.md"}, + {"Custom Types" = "api-reference/custom-types.md"} + ]}, + {"Writing your retrieval system" = "development/adaptive_storage_system.md"}, + {"Using Scrapling's custom types" = "development/scrapling_custom_types.md"} + ]}, + {"Support and Advertisement" = "donate.md"}, + {Contributing = "https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md"}, + {Changelog = "https://github.com/D4Vinci/Scrapling/releases"} +] + +[project.theme] +language = "en" +logo = "assets/logo.png" +favicon = "assets/favicon.ico" +features = [ + "navigation.path", + "announce.dismiss", + "navigation.top", + "navigation.footer", + "navigation.indexes", + "navigation.sections", + "navigation.tracking", + "navigation.instant", + "navigation.instant.prefetch", + "navigation.instant.progress", + # "navigation.tabs", + # "navigation.expand", + # "toc.integrate", + "search.share", + "search.suggest", + "search.highlight", +] + +[[project.theme.palette]] +media = "(prefers-color-scheme: light)" +scheme = "default" +accent = "green" +primary = "deep purple" +toggle.icon = "lucide/sun" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +media = "(prefers-color-scheme: dark)" +scheme = "slate" +accent = "light green" +primary = "deep purple" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +# Uncomment if needed: +# [project.theme.font] +# text = "Open Sans" +# code = "JetBrains Mono" + +[project.markdown_extensions.pymdownx.caret] +[project.markdown_extensions.pymdownx.mark] +[project.markdown_extensions.pymdownx.tilde] +[project.markdown_extensions.admonition] +[project.markdown_extensions.abbr] +#[project.markdown_extensions.mkautodoc] +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.superfences] +[project.markdown_extensions.pymdownx.inlinehilite] +[project.markdown_extensions.pymdownx.snippets] +[project.markdown_extensions.tables] + +[project.markdown_extensions.pymdownx.emoji] +emoji_index = "zensical.extensions.emoji.twemoji" +emoji_generator = "zensical.extensions.emoji.to_svg" + +[project.markdown_extensions.pymdownx.highlight] +pygments_lang_class = true +anchor_linenums = true +line_spans = "__span" + +[project.markdown_extensions.pymdownx.tabbed] +alternate_style = true + +[project.markdown_extensions.codehilite] +css_class = "highlight" + +[project.markdown_extensions.toc] +title = "On this page" +permalink = true +toc_depth = 3 + +[project.plugins.mkdocstrings.handlers.python] +inventories = ["https://docs.python.org/3/objects.inv"] +paths = ["scrapling"] + +[project.plugins.mkdocstrings.handlers.python.options] +docstring_style = "sphinx" +show_source = true +show_root_heading = true +show_if_no_docstring = true +inherited_members = true +members_order = "source" +separate_signature = true +unwrap_annotated = true +filters = "public" +merge_init_into_class = true +docstring_section_style = "spacy" +signature_crossrefs = true +show_symbol_type_heading = true +show_symbol_type_toc = true +show_inheritance_diagram = true +modernize_annotations = true +extensions = [ + "griffe_runtime_objects", + "griffe_sphinx", + {griffe_inherited_docstrings = {merge = true}} +] + +[[project.extra.social]] +icon = "fontawesome/brands/github" +link = "https://github.com/D4Vinci/Scrapling" + +[[project.extra.social]] +icon = "fontawesome/brands/x-twitter" +link = "https://x.com/Scrapling_dev" + +[[project.extra.social]] +icon = "fontawesome/brands/discord" +link = "https://discord.gg/EMgGbDceNQ" + +[[project.extra.social]] +icon = "fontawesome/brands/python" +link = "https://pypi.org/project/scrapling/" + +[[project.extra.social]] +icon = "fontawesome/brands/docker" +link = "https://hub.docker.com/r/pyd4vinci/scrapling" + +[project.extra.analytics] +provider = "google" +property = "G-CS3DKLY73Z" + +[project.extra.analytics.feedback] +title = "Was this page helpful?" + +[[project.extra.analytics.feedback.ratings]] +icon = "material/heart" +name = "This page was helpful" +data = 1 +note = "Thanks for your feedback!" + +[[project.extra.analytics.feedback.ratings]] +icon = "material/heart-broken" +name = "This page could be improved" +data = 0 +note = """ +Thanks for your feedback! Help us improve this page by +using our feedback form. +""" # TODO: add a new issue template for the docs + +[project.extra.consent] +title = "Cookie consent" +description = """ +We use cookies to recognize your repeated visits and preferences, as well +as to measure the effectiveness of our documentation and whether users +find what they're searching for. With your consent, you're helping us to +make our documentation better. +""" \ No newline at end of file From 09cd5e618307cb50b60993fa17f7955475ddeb37 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 20:54:26 +0200 Subject: [PATCH 71/80] docs(readme): update translation links --- repo_docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repo_docs/README.md b/repo_docs/README.md index e34a85e..a6c14eb 100644 --- a/repo_docs/README.md +++ b/repo_docs/README.md @@ -10,7 +10,7 @@

- [العربيه](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_AR.md) | [Español](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_ES.md) | [Deutsch](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_DE.md) | [简体中文](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_CN.md) | [日本語](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_JP.md) | [Русский](https://github.com/D4Vinci/Scrapling/blob/main/repo_docs/README_RU.md) + العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский
Tests From 12b731b14bce601a0fbcfb9f2c1ca809729c18a0 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 21:04:15 +0200 Subject: [PATCH 72/80] docs: move readme files to the root directory --- repo_docs/README.md => README.md | 2 +- repo_docs/README_AR.md => README_AR.md | 0 repo_docs/README_CN.md => README_CN.md | 0 repo_docs/README_DE.md => README_DE.md | 0 repo_docs/README_ES.md => README_ES.md | 0 repo_docs/README_JP.md => README_JP.md | 0 repo_docs/README_RU.md => README_RU.md | 0 7 files changed, 1 insertion(+), 1 deletion(-) rename repo_docs/README.md => README.md (97%) rename repo_docs/README_AR.md => README_AR.md (100%) rename repo_docs/README_CN.md => README_CN.md (100%) rename repo_docs/README_DE.md => README_DE.md (100%) rename repo_docs/README_ES.md => README_ES.md (100%) rename repo_docs/README_JP.md => README_JP.md (100%) rename repo_docs/README_RU.md => README_RU.md (100%) diff --git a/repo_docs/README.md b/README.md similarity index 97% rename from repo_docs/README.md rename to README.md index a6c14eb..395d953 100644 --- a/repo_docs/README.md +++ b/README.md @@ -10,7 +10,7 @@

- العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский + العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский
Tests diff --git a/repo_docs/README_AR.md b/README_AR.md similarity index 100% rename from repo_docs/README_AR.md rename to README_AR.md diff --git a/repo_docs/README_CN.md b/README_CN.md similarity index 100% rename from repo_docs/README_CN.md rename to README_CN.md diff --git a/repo_docs/README_DE.md b/README_DE.md similarity index 100% rename from repo_docs/README_DE.md rename to README_DE.md diff --git a/repo_docs/README_ES.md b/README_ES.md similarity index 100% rename from repo_docs/README_ES.md rename to README_ES.md diff --git a/repo_docs/README_JP.md b/README_JP.md similarity index 100% rename from repo_docs/README_JP.md rename to README_JP.md diff --git a/repo_docs/README_RU.md b/README_RU.md similarity index 100% rename from repo_docs/README_RU.md rename to README_RU.md From 9a108160c21f81c05bd33ea05378b9c17a8bbc5a Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 22:18:36 +0200 Subject: [PATCH 73/80] docs: move translated README files to docs folder again --- README_AR.md => docs/README_AR.md | 0 README_CN.md => docs/README_CN.md | 0 README_DE.md => docs/README_DE.md | 0 README_ES.md => docs/README_ES.md | 0 README_JP.md => docs/README_JP.md | 0 README_RU.md => docs/README_RU.md | 0 zensical.toml | 6 +++--- 7 files changed, 3 insertions(+), 3 deletions(-) rename README_AR.md => docs/README_AR.md (100%) rename README_CN.md => docs/README_CN.md (100%) rename README_DE.md => docs/README_DE.md (100%) rename README_ES.md => docs/README_ES.md (100%) rename README_JP.md => docs/README_JP.md (100%) rename README_RU.md => docs/README_RU.md (100%) diff --git a/README_AR.md b/docs/README_AR.md similarity index 100% rename from README_AR.md rename to docs/README_AR.md diff --git a/README_CN.md b/docs/README_CN.md similarity index 100% rename from README_CN.md rename to docs/README_CN.md diff --git a/README_DE.md b/docs/README_DE.md similarity index 100% rename from README_DE.md rename to docs/README_DE.md diff --git a/README_ES.md b/docs/README_ES.md similarity index 100% rename from README_ES.md rename to docs/README_ES.md diff --git a/README_JP.md b/docs/README_JP.md similarity index 100% rename from README_JP.md rename to docs/README_JP.md diff --git a/README_RU.md b/docs/README_RU.md similarity index 100% rename from README_RU.md rename to docs/README_RU.md diff --git a/zensical.toml b/zensical.toml index 12ebfd2..0bda1c8 100644 --- a/zensical.toml +++ b/zensical.toml @@ -74,9 +74,9 @@ features = [ "navigation.instant", "navigation.instant.prefetch", "navigation.instant.progress", - # "navigation.tabs", - # "navigation.expand", - # "toc.integrate", +# "navigation.tabs", +# "navigation.expand", +# "toc.integrate", "search.share", "search.suggest", "search.highlight", From 8d82d3c90da0d46ad89432a8c802fc3e9cdfff2c Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 22:39:50 +0200 Subject: [PATCH 74/80] docs: update readme file --- README.md | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 395d953..fe24864 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web

- العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский + العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский
Tests @@ -31,32 +31,20 @@

- - Selection methods - - · - - Choosing a fetcher - - · - - CLI - - · - - MCP mode - - · - - Migrating from Beautifulsoup - + Selection methods + · + Choosing a fetcher + · + CLI + · + MCP mode + · + Migrating from Beautifulsoup

-**Stop fighting anti-bot systems. Stop rewriting selectors after every website update.** +Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl. Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume and automatic proxy rotation — all in a few lines of Python. One library, zero compromises. -Scrapling isn't just another Web Scraping library. It's the first **adaptive** scraping library that learns from website changes and evolves with them. While other libraries break when websites update their structure, Scrapling automatically relocates your elements and keeps your scrapers running. - -Built for the modern Web, Scrapling features **its own rapid parsing engine** and fetchers to handle all Web Scraping challenges you face or will face. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. +Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. ```python >> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher From ca46070a1b45f274f9da888e929e577b2f34faed Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 22:43:00 +0200 Subject: [PATCH 75/80] docs: Improve README.md description formatting Reformatted the description of Scrapling for clarity and readability. --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fe24864..f1ff2fe 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,9 @@ Migrating from Beautifulsoup

-Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl. Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume and automatic proxy rotation — all in a few lines of Python. One library, zero compromises. +Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl. + +Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume and automatic proxy rotation — all in a few lines of Python. One library, zero compromises. Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. @@ -334,4 +336,4 @@ This project includes code adapted from: - [fakebrowser](https://github.com/kkoooqq/fakebrowser) and [BotBrowser](https://github.com/botswin/BotBrowser) for fingerprinting research --- -
Designed & crafted with ❤️ by Karim Shoair.

\ No newline at end of file +
Designed & crafted with ❤️ by Karim Shoair.

From 0c86d70307d377752658a0fd941da1b61df71a3d Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 23:33:10 +0200 Subject: [PATCH 76/80] docs: update the website main page --- docs/index.md | 62 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/docs/index.md b/docs/index.md index 68185e8..48fffcb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,27 +14,34 @@
-
- Easy, effortless Web Scraping as it should be! -

-
+

Effortless Web Scraping for the Modern Web


-**Stop fighting anti-bot systems. Stop rewriting selectors after every website update.** +Scrapling is an adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl. -Scrapling isn't just another Web Scraping library. It's the first **adaptive** scraping library that learns from website changes and evolves with them. While other libraries break when websites update their structure, Scrapling automatically relocates your elements and keeps your scrapers running. +Its parser learns from website changes and automatically relocates your elements when pages update. Its fetchers bypass anti-bot systems like Cloudflare Turnstile out of the box. And its spider framework lets you scale up to concurrent, multi-session crawls with pause/resume and automatic proxy rotation — all in a few lines of Python. One library, zero compromises. -Built for the modern Web, Scrapling features **its own rapid parsing engine** and fetchers to handle all Web Scraping challenges you face or will face. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. +Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# Fetch websites' source under the radar! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # Scrape data that survives website design changes! ->> # Later, if the website structure changes, pass `adaptive=True` ->> products = page.css('.product', adaptive=True) # and Scrapling still finds them! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # Fetch website under the radar! +products = page.css('.product', auto_save=True) # Scrape data that survives website design changes! +products = page.css('.product', adaptive=True) # Later, if the website structure changes, pass `adaptive=True` to find them! +``` +Or scale up to full crawls +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` ## Top Sponsors @@ -56,16 +63,27 @@ Built for the modern Web, Scrapling features **its own rapid parsing engine** an ## Key Features +### Spiders — A Full Crawling Framework +- 🕷️ **Scrapy-like Spider API**: Define spiders with `start_urls`, async `parse` callbacks, and `Request`/`Response` objects. +- ⚡ **Concurrent Crawling**: Configurable concurrency limits, per-domain throttling, and download delays. +- 🔄 **Multi-Session Support**: Unified interface for HTTP requests, and stealthy headless browsers in a single spider — route requests to different sessions by ID. +- 💾 **Pause & Resume**: Checkpoint-based crawl persistence. Press Ctrl+C for graceful shutdown; restart to resume from where you left off. +- 📡 **Streaming Mode**: Stream scraped items as they arrive via `async for item in spider.stream()` with real-time stats — ideal for UI, pipelines, and long-running crawls. +- 🛡️ **Blocked Request Detection**: Automatic detection and retry of blocked requests with customizable logic. +- 📦 **Built-in Export**: Export results through hooks and your own pipeline or the built-in JSON/JSONL with `result.items.to_json()` / `result.items.to_jsonl()` respectively. + ### Advanced Websites Fetching with Session Support - **HTTP Requests**: Fast and stealthy HTTP requests with the `Fetcher` class. Can impersonate browsers' TLS fingerprint, headers, and use HTTP/3. -- **Dynamic Loading**: Fetch dynamic websites with full browser automation through the `DynamicFetcher` class supporting Playwright's Chromium, and Google's Chrome. -- **Anti-bot Bypass**: Advanced stealth capabilities with `StealthyFetcher` and fingerprint spoofing. Can bypass all types of Cloudflare's Turnstile/Interstitial with automation easily. +- **Dynamic Loading**: Fetch dynamic websites with full browser automation through the `DynamicFetcher` class supporting Playwright's Chromium and Google's Chrome. +- **Anti-bot Bypass**: Advanced stealth capabilities with `StealthyFetcher` and fingerprint spoofing. Can easily bypass all types of Cloudflare's Turnstile/Interstitial with automation. - **Session Management**: Persistent session support with `FetcherSession`, `StealthySession`, and `DynamicSession` classes for cookie and state management across requests. +- **Proxy Rotation**: Built-in `ProxyRotator` with round-robin or custom strategies across all session types, plus per-request proxy overrides. +- **Domain Blocking**: Block requests to specific domains (and their subdomains) in browser-based fetchers. - **Async Support**: Complete async support across all fetchers and dedicated async session classes. ### Adaptive Scraping & AI Integration - 🔄 **Smart Element Tracking**: Relocate elements after website changes using intelligent similarity algorithms. -- 🎯 **Smart Flexible Selection**: CSS selectors, XPath selectors, filter-based search, text search, regex search, and more. +- 🎯 **Smart Flexible Selection**: CSS selectors, XPath selectors, filter-based search, text search, regex search, and more. - 🔍 **Find Similar Elements**: Automatically locate elements similar to found elements. - 🤖 **MCP Server to be used with AI**: Built-in MCP server for AI-assisted Web Scraping and data extraction. The MCP server features powerful, custom capabilities that leverage Scrapling to extract targeted content before passing it to the AI (Claude/Cursor/etc), thereby speeding up operations and reducing costs by minimizing token usage. ([demo video](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) @@ -77,12 +95,12 @@ Built for the modern Web, Scrapling features **its own rapid parsing engine** an ### Developer/Web Scraper Friendly Experience - 🎯 **Interactive Web Scraping Shell**: Optional built-in IPython shell with Scrapling integration, shortcuts, and new tools to speed up Web Scraping scripts development, like converting curl requests to Scrapling requests and viewing requests results in your browser. -- 🚀 **Use it directly from the Terminal**: Optionally, you can use Scrapling to scrape a URL without writing a single code! +- 🚀 **Use it directly from the Terminal**: Optionally, you can use Scrapling to scrape a URL without writing a single line of code! - 🛠️ **Rich Navigation API**: Advanced DOM traversal with parent, sibling, and child navigation methods. - 🧬 **Enhanced Text Processing**: Built-in regex, cleaning methods, and optimized string operations. - 📝 **Auto Selector Generation**: Generate robust CSS/XPath selectors for any element. - 🔌 **Familiar API**: Similar to Scrapy/BeautifulSoup with the same pseudo-elements used in Scrapy/Parsel. -- 📘 **Complete Type Coverage**: Full type hints for excellent IDE support and code completion. +- 📘 **Complete Type Coverage**: Full type hints for excellent IDE support and code completion. The entire codebase is automatically scanned with **PyRight** and **MyPy** with each change. - 🔋 **Ready Docker image**: With each release, a Docker image containing all browsers is automatically built and pushed. @@ -127,7 +145,7 @@ Scrapling requires Python 3.10 or higher: pip install scrapling ``` -Starting with v0.3.2, this installation only includes the parser engine and its dependencies, without any fetchers or commandline dependencies. +This installation only includes the parser engine and its dependencies, without any fetchers or commandline dependencies. ### Optional Dependencies From 1f9eb174145e1cf60bf45d96efd659dd783606c2 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Sun, 8 Feb 2026 23:33:30 +0200 Subject: [PATCH 77/80] ops: update benchmarks script --- benchmarks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks.py b/benchmarks.py index 438466e..fcb089c 100644 --- a/benchmarks.py +++ b/benchmarks.py @@ -75,7 +75,7 @@ def test_scrapling(): # No need to do `.extract()` like parsel to extract text # Also, this is faster than `[t.text for t in Selector(large_html, adaptive=False).css('.item')]` # for obvious reasons, of course. - return ScraplingSelector(large_html, adaptive=False).css(".item::text") + return ScraplingSelector(large_html, adaptive=False).css(".item::text").getall() @benchmark From 2a4d0089278721038f04d4379754adf10af8f848 Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 9 Feb 2026 00:28:24 +0200 Subject: [PATCH 78/80] docs: full update for main readme --- README.md | 188 ++++++++++++++++++++++++++++++++++---------------- docs/index.md | 2 +- 2 files changed, 130 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index f1ff2fe..0b31010 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

- العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский + العربيه | Español | Deutsch | 简体中文 | 日本語 | Русский
Tests @@ -49,16 +49,27 @@ Its parser learns from website changes and automatically relocates your elements Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers for Web Scrapers and regular users, there's something for everyone. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# Fetch websites' source under the radar! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # Scrape data that survives website design changes! ->> # Later, if the website structure changes, pass `adaptive=True` ->> products = page.css('.product', adaptive=True) # and Scrapling still finds them! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # Fetch website under the radar! +products = page.css('.product', auto_save=True) # Scrape data that survives website design changes! +products = page.css('.product', adaptive=True) # Later, if the website structure changes, pass `adaptive=True` to find them! ``` +Or scale up to full crawls +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() +``` + # Sponsors @@ -84,16 +95,27 @@ Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers fo ## Key Features +### Spiders — A Full Crawling Framework +- 🕷️ **Scrapy-like Spider API**: Define spiders with `start_urls`, async `parse` callbacks, and `Request`/`Response` objects. +- ⚡ **Concurrent Crawling**: Configurable concurrency limits, per-domain throttling, and download delays. +- 🔄 **Multi-Session Support**: Unified interface for HTTP requests, and stealthy headless browsers in a single spider — route requests to different sessions by ID. +- 💾 **Pause & Resume**: Checkpoint-based crawl persistence. Press Ctrl+C for a graceful shutdown; restart to resume from where you left off. +- 📡 **Streaming Mode**: Stream scraped items as they arrive via `async for item in spider.stream()` with real-time stats — ideal for UI, pipelines, and long-running crawls. +- 🛡️ **Blocked Request Detection**: Automatic detection and retry of blocked requests with customizable logic. +- 📦 **Built-in Export**: Export results through hooks and your own pipeline or the built-in JSON/JSONL with `result.items.to_json()` / `result.items.to_jsonl()` respectively. + ### Advanced Websites Fetching with Session Support -- **HTTP Requests**: Fast and stealthy HTTP requests with the `Fetcher` class. Can impersonate browsers' TLS fingerprint, headers, and use HTTP3. +- **HTTP Requests**: Fast and stealthy HTTP requests with the `Fetcher` class. Can impersonate browsers' TLS fingerprint, headers, and use HTTP/3. - **Dynamic Loading**: Fetch dynamic websites with full browser automation through the `DynamicFetcher` class supporting Playwright's Chromium and Google's Chrome. - **Anti-bot Bypass**: Advanced stealth capabilities with `StealthyFetcher` and fingerprint spoofing. Can easily bypass all types of Cloudflare's Turnstile/Interstitial with automation. - **Session Management**: Persistent session support with `FetcherSession`, `StealthySession`, and `DynamicSession` classes for cookie and state management across requests. +- **Proxy Rotation**: Built-in `ProxyRotator` with round-robin or custom strategies across all session types, plus per-request proxy overrides. +- **Domain Blocking**: Block requests to specific domains (and their subdomains) in browser-based fetchers. - **Async Support**: Complete async support across all fetchers and dedicated async session classes. ### Adaptive Scraping & AI Integration - 🔄 **Smart Element Tracking**: Relocate elements after website changes using intelligent similarity algorithms. -- 🎯 **Smart Flexible Selection**: CSS selectors, XPath selectors, filter-based search, text search, regex search, and more. +- 🎯 **Smart Flexible Selection**: CSS selectors, XPath selectors, filter-based search, text search, regex search, and more. - 🔍 **Find Similar Elements**: Automatically locate elements similar to found elements. - 🤖 **MCP Server to be used with AI**: Built-in MCP server for AI-assisted Web Scraping and data extraction. The MCP server features powerful, custom capabilities that leverage Scrapling to extract targeted content before passing it to the AI (Claude/Cursor/etc), thereby speeding up operations and reducing costs by minimizing token usage. ([demo video](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) @@ -105,51 +127,107 @@ Blazing fast crawls with real-time stats and streaming. Built by Web Scrapers fo ### Developer/Web Scraper Friendly Experience - 🎯 **Interactive Web Scraping Shell**: Optional built-in IPython shell with Scrapling integration, shortcuts, and new tools to speed up Web Scraping scripts development, like converting curl requests to Scrapling requests and viewing requests results in your browser. -- 🚀 **Use it directly from the Terminal**: Optionally, you can use Scrapling to scrape a URL without writing a single code! +- 🚀 **Use it directly from the Terminal**: Optionally, you can use Scrapling to scrape a URL without writing a single line of code! - 🛠️ **Rich Navigation API**: Advanced DOM traversal with parent, sibling, and child navigation methods. - 🧬 **Enhanced Text Processing**: Built-in regex, cleaning methods, and optimized string operations. - 📝 **Auto Selector Generation**: Generate robust CSS/XPath selectors for any element. - 🔌 **Familiar API**: Similar to Scrapy/BeautifulSoup with the same pseudo-elements used in Scrapy/Parsel. -- 📘 **Complete Type Coverage**: Full type hints for excellent IDE support and code completion. +- 📘 **Complete Type Coverage**: Full type hints for excellent IDE support and code completion. The entire codebase is automatically scanned with **PyRight** and **MyPy** with each change. - 🔋 **Ready Docker image**: With each release, a Docker image containing all browsers is automatically built and pushed. ## Getting Started -### Basic Usage -```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +Let's give you a quick glimpse of what Scrapling can do; the rest is on [the documentation website](https://scrapling.readthedocs.io). + +### Basic Usage +HTTP requests with session support +```python +from scrapling.fetchers import Fetcher, FetcherSession -# HTTP requests with session support with FetcherSession(impersonate='chrome') as session: # Use latest version of Chrome's TLS fingerprint page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # Or use one-off requests page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +Advanced stealth mode +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# Advanced stealth mode (Keep the browser open until you finish) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # Keep the browser open until you finish page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() # Or use one-off request style, it opens the browser for this request, then closes it after finishing page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# Full browser automation (Keep the browser open until you finish) -with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: +data = page.css('#padded_content a').getall() +``` +Full browser automation +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession + +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # Keep the browser open until you finish page = session.fetch('https://quotes.toscrape.com/', load_dom=False) - data = page.xpath('//span[@class="text"]/text()') # XPath selector if you prefer it + data = page.xpath('//span[@class="text"]/text()').getall() # XPath selector if you prefer it # Or use one-off request style, it opens the browser for this request, then closes it after finishing page = DynamicFetcher.fetch('https://quotes.toscrape.com/') -data = page.css('.quote .text::text') +data = page.css('.quote .text::text').getall() ``` -> [!NOTE] -> There's a wonderful guide to get you started quickly with Scrapling [here](https://substack.thewebscraping.club/p/scrapling-hands-on-guide) written by The Web Scraping Club. In case you find it easier to get you started than the [documentation website](https://scrapling.readthedocs.io/en/latest/). +### Spiders +Build full crawlers with concurrent requests, multiple session types, and pause/resume: +```python +from scrapling.spiders import Spider, Request, Response + +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 + + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } + + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) + +result = QuotesSpider().start() +print(f"Scraped {len(result.items)} quotes") +result.items.to_json("quotes.json") +``` +Use multiple session types in a single spider: +```python +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession + +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # Route protected pages through the stealth session + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) +``` +Pause and resume long crawls with checkpoints by running the spider like this: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +Press Ctrl+C to pause gracefully — progress is saved automatically. Later, when you start the spider again, pass the same `crawldir`, and it will resume from where it stopped. ### Advanced Parsing & Navigation ```python @@ -170,10 +248,9 @@ quotes = page.find_all(class_='quote') # and so on... quotes = page.find_by_text('quote', tag='div') # Advanced navigation -first_quote = page.css_first('.quote') -quote_text = first_quote.css('.text::text') -quote_text = page.css('.quote').css_first('.text::text') # Chained selectors -quote_text = page.css_first('.quote .text').text # Using `css_first` is faster than `css` if you want the first element +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # Chained selectors +first_quote = page.css('.quote') author = first_quote.next_sibling.css('.author::text') parent_container = first_quote.parent @@ -214,7 +291,7 @@ async with AsyncStealthySession(max_pages=2) as session: ## CLI & Interactive Shell -Scrapling v0.3 includes a powerful command-line interface: +Scrapling includes a powerful command-line interface: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) @@ -231,34 +308,34 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> There are many additional features, but we want to keep this page concise, such as the MCP server and the interactive Web Scraping Shell. Check out the full documentation [here](https://scrapling.readthedocs.io/en/latest/) +> There are many additional features, but we want to keep this page concise, including the MCP server and the interactive Web Scraping Shell. Check out the full documentation [here](https://scrapling.readthedocs.io/en/latest/) ## Performance Benchmarks -Scrapling isn't just powerful—it's also blazing fast, and the updates since version 0.3 have delivered exceptional performance improvements across all operations. The following benchmarks compare Scrapling's parser with other popular libraries. +Scrapling isn't just powerful—it's also blazing fast. The following benchmarks compare Scrapling's parser with the latest versions of other popular libraries. ### Text Extraction Speed Test (5000 nested elements) | # | Library | Time (ms) | vs Scrapling | |---|:-----------------:|:---------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### Element Similarity & Text Search Performance Scrapling's adaptive element finding capabilities significantly outperform alternatives: -| Library | Time (ms) | vs Scrapling | +| Library | Time (ms) | vs Scrapling | |-------------|:---------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > All benchmarks represent averages of 100+ runs. See [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) for methodology. @@ -271,7 +348,7 @@ Scrapling requires Python 3.10 or higher: pip install scrapling ``` -Starting with v0.3.2, this installation only includes the parser engine and its dependencies, without any fetchers or commandline dependencies. +This installation only includes the parser engine and its dependencies, without any fetchers or commandline dependencies. ### Optional Dependencies @@ -328,12 +405,5 @@ This work is licensed under the BSD-3-Clause License. This project includes code adapted from: - Parsel (BSD License)—Used for [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) submodule -## Thanks and References - -- [Daijro](https://github.com/daijro)'s brilliant work on [BrowserForge](https://github.com/daijro/browserforge) and [Camoufox](https://github.com/daijro/camoufox) -- [Vinyzu](https://github.com/Vinyzu)'s brilliant work on [Botright](https://github.com/Vinyzu/Botright) and [PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright) -- [brotector](https://github.com/kaliiiiiiiiii/brotector) for browser detection bypass techniques -- [fakebrowser](https://github.com/kkoooqq/fakebrowser) and [BotBrowser](https://github.com/botswin/BotBrowser) for fingerprinting research - --- -

Designed & crafted with ❤️ by Karim Shoair.

+
Designed & crafted with ❤️ by Karim Shoair.

\ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 48fffcb..cbb9d35 100644 --- a/docs/index.md +++ b/docs/index.md @@ -67,7 +67,7 @@ MySpider().start() - 🕷️ **Scrapy-like Spider API**: Define spiders with `start_urls`, async `parse` callbacks, and `Request`/`Response` objects. - ⚡ **Concurrent Crawling**: Configurable concurrency limits, per-domain throttling, and download delays. - 🔄 **Multi-Session Support**: Unified interface for HTTP requests, and stealthy headless browsers in a single spider — route requests to different sessions by ID. -- 💾 **Pause & Resume**: Checkpoint-based crawl persistence. Press Ctrl+C for graceful shutdown; restart to resume from where you left off. +- 💾 **Pause & Resume**: Checkpoint-based crawl persistence. Press Ctrl+C for a graceful shutdown; restart to resume from where you left off. - 📡 **Streaming Mode**: Stream scraped items as they arrive via `async for item in spider.stream()` with real-time stats — ideal for UI, pipelines, and long-running crawls. - 🛡️ **Blocked Request Detection**: Automatic detection and retry of blocked requests with customizable logic. - 📦 **Built-in Export**: Export results through hooks and your own pipeline or the built-in JSON/JSONL with `result.items.to_json()` / `result.items.to_jsonl()` respectively. From 3dc4bdcb4a991eee2cfca4310ad074135f26cb8d Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 9 Feb 2026 00:36:52 +0200 Subject: [PATCH 79/80] docs: small adjustments to the readme file --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b31010..cd5a578 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ MySpider().start() ## Getting Started -Let's give you a quick glimpse of what Scrapling can do; the rest is on [the documentation website](https://scrapling.readthedocs.io). +Let's give you a quick glimpse of what Scrapling can do without deep diving. ### Basic Usage HTTP requests with session support @@ -221,7 +221,7 @@ class MultiSessionSpider(Spider): if "protected" in link: yield Request(link, sid="stealth") else: - yield Request(link, sid="fast", callback=self.parse) + yield Request(link, sid="fast", callback=self.parse) # explicit callback ``` Pause and resume long crawls with checkpoints by running the spider like this: ```python @@ -250,7 +250,7 @@ quotes = page.find_by_text('quote', tag='div') # Advanced navigation quote_text = page.css('.quote')[0].css('.text::text').get() quote_text = page.css('.quote').css('.text::text').getall() # Chained selectors -first_quote = page.css('.quote') +first_quote = page.css('.quote')[0] author = first_quote.next_sibling.css('.author::text') parent_container = first_quote.parent From e6880939742d71a28eefdb91962fcc800120cbec Mon Sep 17 00:00:00 2001 From: Karim shoair Date: Mon, 9 Feb 2026 00:46:58 +0200 Subject: [PATCH 80/80] docs: update the translated readme files with the new content --- docs/README_AR.md | 328 ++++++++++++++++++++++++++----------------- docs/README_CN.md | 328 ++++++++++++++++++++++++++----------------- docs/README_DE.md | 316 +++++++++++++++++++++++++----------------- docs/README_ES.md | 314 +++++++++++++++++++++++++---------------- docs/README_JP.md | 342 +++++++++++++++++++++++++++------------------ docs/README_RU.md | 346 +++++++++++++++++++++++++++------------------- 6 files changed, 1191 insertions(+), 783 deletions(-) diff --git a/docs/README_AR.md b/docs/README_AR.md index 0463398..a7bd461 100644 --- a/docs/README_AR.md +++ b/docs/README_AR.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - طرق الاختيار - - · - - اختيار الجالب - - · - - واجهة سطر الأوامر - - · - - وضع MCP - - · - - الانتقال من Beautifulsoup - + طرق الاختيار + · + اختيار Fetcher + · + واجهة سطر الأوامر + · + وضع MCP + · + الانتقال من Beautifulsoup

-**توقف عن محاربة أنظمة مكافحة الروبوتات. توقف عن إعادة كتابة المحددات بعد كل تحديث للموقع.** +Scrapling هو إطار عمل تكيفي لـ Web Scraping يتعامل مع كل شيء من طلب واحد إلى زحف كامل النطاق. -Scrapling ليست مجرد مكتبة أخرى لاستخراج بيانات الويب. إنها أول مكتبة استخراج **تكيفية** تتعلم من تغييرات المواقع وتتطور معها. بينما تتعطل المكتبات الأخرى عندما تحدث المواقع بنيتها، يعيد Scrapling تحديد موقع عناصرك تلقائياً ويحافظ على عمل أدوات الاستخراج الخاصة بك. +محلله يتعلم من تغييرات المواقع ويعيد تحديد موقع عناصرك تلقائياً عند تحديث الصفحات. جوالبه تتجاوز أنظمة مكافحة الروبوتات مثل Cloudflare Turnstile مباشرةً. وإطار عمل Spider الخاص به يتيح لك التوسع إلى عمليات زحف متزامنة ومتعددة الجلسات مع إيقاف/استئناف وتدوير تلقائي لـ Proxy - كل ذلك في بضعة أسطر من Python. مكتبة واحدة، بدون تنازلات. -مبني للويب الحديث، يتميز Scrapling **بمحرك تحليل سريع خاص به** وجوالب للتعامل مع جميع تحديات استخراج بيانات الويب التي تواجهها أو ستواجهها. مبني بواسطة مستخرجي الويب لمستخرجي الويب والمستخدمين العاديين، هناك شيء للجميع. +زحف سريع للغاية مع إحصائيات فورية و Streaming. مبني بواسطة مستخرجي الويب لمستخرجي الويب والمستخدمين العاديين، هناك شيء للجميع. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# احصل على كود المصدر للمواقع بشكل خفي! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # استخرج البيانات التي تنجو من تغييرات تصميم الموقع! ->> # لاحقاً، إذا تغيرت بنية الموقع، مرر `adaptive=True` ->> products = page.css('.product', adaptive=True) # و Scrapling لا يزال يجدها! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # احصل على الموقع بشكل خفي! +products = page.css('.product', auto_save=True) # استخرج بيانات تنجو من تغييرات تصميم الموقع! +products = page.css('.product', adaptive=True) # لاحقاً، إذا تغيرت بنية الموقع، مرر `adaptive=True` للعثور عليها! +``` +أو توسع إلى عمليات زحف كاملة +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# الرعاة + +# الرعاة @@ -91,138 +93,211 @@ Scrapling ليست مجرد مكتبة أخرى لاستخراج بيانات ا ## الميزات الرئيسية +### Spiders — إطار عمل زحف كامل +- 🕷️ **واجهة Spider شبيهة بـ Scrapy**: عرّف Spiders مع `start_urls`، و async `parse` callbacks، وكائنات `Request`/`Response`. +- ⚡ **زحف متزامن**: حدود تزامن قابلة للتكوين، وتحكم بالسرعة حسب النطاق، وتأخيرات التنزيل. +- 🔄 **دعم الجلسات المتعددة**: واجهة موحدة لطلبات HTTP، ومتصفحات خفية بدون واجهة في Spider واحد — وجّه الطلبات إلى جلسات مختلفة بالمعرّف. +- 💾 **إيقاف واستئناف**: استمرارية الزحف القائمة على Checkpoint. اضغط Ctrl+C للإيقاف بسلاسة؛ أعد التشغيل للاستئناف من حيث توقفت. +- 📡 **وضع Streaming**: بث العناصر المستخرجة فور وصولها عبر `async for item in spider.stream()` مع إحصائيات فورية — مثالي لواجهات المستخدم وخطوط الأنابيب وعمليات الزحف الطويلة. +- 🛡️ **كشف الطلبات المحظورة**: كشف تلقائي وإعادة محاولة للطلبات المحظورة مع منطق قابل للتخصيص. +- 📦 **تصدير مدمج**: صدّر النتائج عبر الخطافات وخط الأنابيب الخاص بك أو JSON/JSONL المدمج مع `result.items.to_json()` / `result.items.to_jsonl()` على التوالي. + ### جلب متقدم للمواقع مع دعم الجلسات -- **طلبات HTTP**: طلبات HTTP سريعة وخفية مع فئة `Fetcher`. يمكنها تقليد بصمة TLS للمتصفح والرؤوس واستخدام HTTP3. +- **طلبات HTTP**: طلبات HTTP سريعة وخفية مع فئة `Fetcher`. يمكنها تقليد بصمة TLS للمتصفح والرؤوس واستخدام HTTP/3. - **التحميل الديناميكي**: جلب المواقع الديناميكية مع أتمتة كاملة للمتصفح من خلال فئة `DynamicFetcher` التي تدعم Chromium من Playwright و Google Chrome. -- **تجاوز مكافحة الروبوتات**: قدرات تخفي متقدمة مع `StealthyFetcher` وانتحال البصمات. يمكنه تجاوز جميع أنواع Turnstile/Interstitial من Cloudflare بسهولة بالأتمتة. +- **تجاوز مكافحة الروبوتات**: قدرات تخفي متقدمة مع `StealthyFetcher` وانتحال fingerprint. يمكنه تجاوز جميع أنواع Turnstile/Interstitial من Cloudflare بسهولة بالأتمتة. - **إدارة الجلسات**: دعم الجلسات المستمرة مع فئات `FetcherSession` و`StealthySession` و`DynamicSession` لإدارة ملفات تعريف الارتباط والحالة عبر الطلبات. +- **تدوير Proxy**: `ProxyRotator` مدمج مع استراتيجيات round-robin أو مخصصة عبر جميع أنواع الجلسات، بالإضافة إلى تجاوزات Proxy لكل طلب. +- **حظر النطاقات**: حظر الطلبات إلى نطاقات محددة (ونطاقاتها الفرعية) في الجوالب المعتمدة على المتصفح. - **دعم Async**: دعم async كامل عبر جميع الجوالب وفئات الجلسات async المخصصة. ### الاستخراج التكيفي والتكامل مع الذكاء الاصطناعي - 🔄 **تتبع العناصر الذكي**: إعادة تحديد موقع العناصر بعد تغييرات الموقع باستخدام خوارزميات التشابه الذكية. - 🎯 **الاختيار المرن الذكي**: محددات CSS، محددات XPath، البحث القائم على الفلاتر، البحث النصي، البحث بالتعبيرات العادية والمزيد. - 🔍 **البحث عن عناصر مشابهة**: تحديد العناصر المشابهة للعناصر الموجودة تلقائياً. -- 🤖 **خادم MCP للاستخدام مع الذكاء الاصطناعي**: خادم MCP مدمج لاستخراج بيانات الويب بمساعدة الذكاء الاصطناعي واستخراج البيانات. يتميز خادم MCP بقدرات قوية مخصصة تستفيد من Scrapling لاستخراج المحتوى المستهدف قبل تمريره إلى الذكاء الاصطناعي (Claude/Cursor/إلخ)، وبالتالي تسريع العمليات وتقليل التكاليف عن طريق تقليل استخدام الرموز. ([فيديو توضيحي](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) +- 🤖 **خادم MCP للاستخدام مع الذكاء الاصطناعي**: خادم MCP مدمج لـ Web Scraping بمساعدة الذكاء الاصطناعي واستخراج البيانات. يتميز خادم MCP بقدرات قوية مخصصة تستفيد من Scrapling لاستخراج المحتوى المستهدف قبل تمريره إلى الذكاء الاصطناعي (Claude/Cursor/إلخ)، وبالتالي تسريع العمليات وتقليل التكاليف عن طريق تقليل استخدام الرموز. ([فيديو توضيحي](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) -### بنية عالية الأداء ومختبرة في المعارك -- 🚀 **سريع كالبرق**: أداء محسّن يتفوق على معظم مكتبات استخراج Python. +### بنية عالية الأداء ومختبرة ميدانياً +- 🚀 **سريع كالبرق**: أداء محسّن يتفوق على معظم مكتبات Web Scraping في Python. - 🔋 **فعال في استخدام الذاكرة**: هياكل بيانات محسّنة وتحميل كسول لأقل استخدام للذاكرة. - ⚡ **تسلسل JSON سريع**: أسرع 10 مرات من المكتبة القياسية. -- 🏗️ **مُختبر في المعارك**: لا يمتلك Scrapling فقط تغطية اختبار بنسبة 92٪ وتغطية كاملة لتلميحات الأنواع، ولكن تم استخدامه يومياً من قبل مئات مستخرجي الويب خلال العام الماضي. +- 🏗️ **مُختبر ميدانياً**: لا يمتلك Scrapling فقط تغطية اختبار بنسبة 92٪ وتغطية كاملة لتلميحات الأنواع، بل تم استخدامه يومياً من قبل مئات مستخرجي الويب خلال العام الماضي. ### تجربة صديقة للمطورين/مستخرجي الويب -- 🎯 **غلاف استخراج ويب تفاعلي**: غلاف IPython مدمج اختياري مع تكامل Scrapling، واختصارات، وأدوات جديدة لتسريع تطوير سكريبتات استخراج الويب، مثل تحويل طلبات curl إلى طلبات Scrapling وعرض نتائج الطلبات في متصفحك. +- 🎯 **Shell تفاعلي لـ Web Scraping**: Shell IPython مدمج اختياري مع تكامل Scrapling، واختصارات، وأدوات جديدة لتسريع تطوير سكريبتات Web Scraping، مثل تحويل طلبات curl إلى طلبات Scrapling وعرض نتائج الطلبات في متصفحك. - 🚀 **استخدمه مباشرة من الطرفية**: اختيارياً، يمكنك استخدام Scrapling لاستخراج عنوان URL دون كتابة سطر واحد من الكود! -- 🛠️ **واجهة برمجة تطبيقات التنقل الغنية**: اجتياز DOM متقدم مع طرق التنقل بين الوالدين والأشقاء والأطفال. -- 🧬 **معالجة نصوص محسّنة**: تعبيرات عادية مدمجة وطرق تنظيف وعمليات سلسلة محسّنة. -- 📝 **إنشاء محدد تلقائي**: إنشاء محددات CSS/XPath قوية لأي عنصر. -- 🔌 **واجهة برمجة تطبيقات مألوفة**: مشابه لـ Scrapy/BeautifulSoup مع نفس العناصر الزائفة المستخدمة في Scrapy/Parsel. -- 📘 **تغطية كاملة للأنواع**: تلميحات نوع كاملة لدعم IDE ممتاز وإكمال الكود. +- 🛠️ **واجهة تنقل غنية**: اجتياز DOM متقدم مع طرق التنقل بين العناصر الوالدية والشقيقة والفرعية. +- 🧬 **معالجة نصوص محسّنة**: تعبيرات عادية مدمجة وطرق تنظيف وعمليات نصية محسّنة. +- 📝 **إنشاء محددات تلقائي**: إنشاء محددات CSS/XPath قوية لأي عنصر. +- 🔌 **واجهة مألوفة**: مشابه لـ Scrapy/BeautifulSoup مع نفس العناصر الزائفة المستخدمة في Scrapy/Parsel. +- 📘 **تغطية كاملة للأنواع**: تلميحات نوع كاملة لدعم IDE ممتاز وإكمال الكود. يتم فحص قاعدة الكود بالكامل تلقائياً بواسطة **PyRight** و**MyPy** مع كل تغيير. - 🔋 **صورة Docker جاهزة**: مع كل إصدار، يتم بناء ودفع صورة Docker تحتوي على جميع المتصفحات تلقائياً. ## البدء -### الاستخدام الأساسي -```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +لنلقِ نظرة سريعة على ما يمكن لـ Scrapling فعله دون التعمق. + +### الاستخدام الأساسي +طلبات HTTP مع دعم الجلسات +```python +from scrapling.fetchers import Fetcher, FetcherSession -# طلبات HTTP مع دعم الجلسات with FetcherSession(impersonate='chrome') as session: # استخدم أحدث إصدار من بصمة TLS لـ Chrome page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # أو استخدم طلبات لمرة واحدة page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +وضع التخفي المتقدم +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# وضع التخفي المتقدم (احتفظ بالمتصفح مفتوحاً حتى تنتهي) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # أبقِ المتصفح مفتوحاً حتى تنتهي page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() # أو استخدم نمط الطلب لمرة واحدة، يفتح المتصفح لهذا الطلب، ثم يغلقه بعد الانتهاء page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# أتمتة المتصفح الكاملة (احتفظ بالمتصفح مفتوحاً حتى تنتهي) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +أتمتة المتصفح الكاملة +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# أو استخدم نمط الطلب لمرة واحدة -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # أبقِ المتصفح مفتوحاً حتى تنتهي + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # محدد XPath إذا كنت تفضله + +# أو استخدم نمط الطلب لمرة واحدة، يفتح المتصفح لهذا الطلب، ثم يغلقه بعد الانتهاء +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### اختيار العناصر +### Spiders +ابنِ زواحف كاملة مع طلبات متزامنة وأنواع جلسات متعددة وإيقاف/استئناف: ```python -# محددات CSS -page.css('a::text') # استخراج النص -page.css('a::attr(href)') # استخراج السمات -page.css('a', recursive=False) # العناصر المباشرة فقط -page.css('a', auto_save=True) # حفظ مواضع العناصر تلقائياً +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# بحث مرن -page.find_by_text('Python', first_match=True) # البحث بالنص -page.find_by_regex(r'\d{4}') # البحث بنمط التعبير العادي -page.find('div', {'class': 'container'}) # البحث بالسمات + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# التنقل -element.parent # الحصول على العنصر الوالد -element.next_sibling # الحصول على الشقيق التالي -element.children # الحصول على الأطفال + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# عناصر مشابهة -similar = page.get_similar(element) # البحث عن عناصر مشابهة - -# الاستخراج التكيفي -saved_elements = page.css('.product', auto_save=True) -# لاحقاً، عندما يتغير الموقع: -page.css('.product', adaptive=True) # البحث عن العناصر باستخدام المواضع المحفوظة +result = QuotesSpider().start() +print(f"Scraped {len(result.items)} quotes") +result.items.to_json("quotes.json") ``` - -### استخدام الجلسة +استخدم أنواع جلسات متعددة في Spider واحد: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# جلسة متزامنة -with FetcherSession() as session: - # يتم الاحتفاظ بملفات تعريف الارتباط تلقائياً - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # تبديل بصمة المتصفح إذا لزم الأمر +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # وجّه الصفحات المحمية عبر جلسة التخفي + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # callback صريح +``` +أوقف واستأنف عمليات الزحف الطويلة مع Checkpoints بتشغيل Spider هكذا: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +اضغط Ctrl+C للإيقاف بسلاسة — يتم حفظ التقدم تلقائياً. لاحقاً، عند تشغيل Spider مرة أخرى، مرر نفس `crawldir`، وسيستأنف من حيث توقف. + +### التحليل المتقدم والتنقل +```python +from scrapling.fetchers import Fetcher + +# اختيار عناصر غني وتنقل +page = Fetcher.get('https://quotes.toscrape.com/') + +# احصل على الاقتباسات بطرق اختيار متعددة +quotes = page.css('.quote') # محدد CSS +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # بأسلوب BeautifulSoup +# نفس الشيء مثل +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # وهكذا... +# البحث عن عنصر بمحتوى النص +quotes = page.find_by_text('quote', tag='div') + +# التنقل المتقدم +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # محددات متسلسلة +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# علاقات العناصر والتشابه +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +يمكنك استخدام المحلل مباشرة إذا كنت لا تريد جلب المواقع كما يلي: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +وهو يعمل بنفس الطريقة تماماً! + +### أمثلة إدارة الجلسات بشكل Async +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession` واعٍ بالسياق ويعمل في كلا النمطين المتزامن/async + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') # استخدام جلسة async async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - + print(session.get_pool_stats()) # اختياري - حالة مجموعة علامات تبويب المتصفح (مشغول/حر/خطأ) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) ``` -## واجهة سطر الأوامر والغلاف التفاعلي +## واجهة سطر الأوامر والـ Shell التفاعلي -يتضمن Scrapling v0.3 واجهة سطر أوامر قوية: +يتضمن Scrapling واجهة سطر أوامر قوية: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) -تشغيل غلاف استخراج الويب التفاعلي +تشغيل Shell الـ Web Scraping التفاعلي ```bash scrapling shell ``` -استخراج الصفحات إلى ملف مباشرة دون برمجة (يستخرج المحتوى داخل وسم `body` افتراضياً). إذا انتهى ملف الإخراج بـ `.txt`، فسيتم استخراج محتوى النص للهدف. إذا انتهى بـ `.md`، فسيكون تمثيل Markdown لمحتوى HTML؛ إذا انتهى بـ `.html`، فسيكون محتوى HTML نفسه. +استخرج الصفحات إلى ملف مباشرة دون برمجة (يستخرج المحتوى داخل وسم `body` افتراضياً). إذا انتهى ملف الإخراج بـ `.txt`، فسيتم استخراج محتوى النص للهدف. إذا انتهى بـ `.md`، فسيكون تمثيل Markdown لمحتوى HTML؛ إذا انتهى بـ `.html`، فسيكون محتوى HTML نفسه. ```bash scrapling extract get 'https://example.com' content.md scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # جميع العناصر المطابقة لمحدد CSS '#fromSkipToProducts' @@ -231,24 +306,24 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> هناك العديد من الميزات الإضافية، لكننا نريد إبقاء هذه الصفحة موجزة، مثل خادم MCP وغلاف استخراج الويب التفاعلي. تحقق من الوثائق الكاملة [هنا](https://scrapling.readthedocs.io/en/latest/) +> هناك العديد من الميزات الإضافية، لكننا نريد إبقاء هذه الصفحة موجزة، بما في ذلك خادم MCP والـ Shell التفاعلي لـ Web Scraping. تحقق من الوثائق الكاملة [هنا](https://scrapling.readthedocs.io/en/latest/) ## معايير الأداء -Scrapling ليس قوياً فقط - إنه أيضاً سريع بشكل مذهل، والتحديثات منذ الإصدار 0.3 قدمت تحسينات أداء استثنائية عبر جميع العمليات. تقارن المعايير التالية محلل Scrapling مع المكتبات الشائعة الأخرى. +Scrapling ليس قوياً فحسب — بل هو أيضاً سريع بشكل مذهل. تقارن المعايير التالية محلل Scrapling مع أحدث إصدارات المكتبات الشائعة الأخرى. ### اختبار سرعة استخراج النص (5000 عنصر متداخل) -| # | المكتبة | الوقت (ms) | vs Scrapling | +| # | المكتبة | الوقت (ms) | vs Scrapling | |---|:-----------------:|:----------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### أداء تشابه العناصر والبحث النصي @@ -257,39 +332,39 @@ Scrapling ليس قوياً فقط - إنه أيضاً سريع بشكل مذه | المكتبة | الوقت (ms) | vs Scrapling | |-------------|:----------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > تمثل جميع المعايير متوسطات أكثر من 100 تشغيل. انظر [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) للمنهجية. ## التثبيت -يتطلب Scrapling Python 3.10 أو أعلى: +يتطلب Scrapling إصدار Python 3.10 أو أعلى: ```bash pip install scrapling ``` -بدءاً من v0.3.2، يتضمن هذا التثبيت فقط محرك المحلل وتبعياته، بدون أي جوالب أو تبعيات سطر أوامر. +يتضمن هذا التثبيت فقط محرك المحلل وتبعياته، بدون أي جوالب أو تبعيات سطر الأوامر. ### التبعيات الاختيارية 1. إذا كنت ستستخدم أياً من الميزات الإضافية أدناه، أو الجوالب، أو فئاتها، فستحتاج إلى تثبيت تبعيات الجوالب وتبعيات المتصفح الخاصة بها على النحو التالي: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - يقوم هذا بتنزيل جميع المتصفحات، إلى جانب تبعيات النظام وتبعيات معالجة البصمات الخاصة بها. + يقوم هذا بتنزيل جميع المتصفحات، إلى جانب تبعيات النظام وتبعيات معالجة fingerprint الخاصة بها. 2. ميزات إضافية: - تثبيت ميزة خادم MCP: ```bash pip install "scrapling[ai]" ``` - - تثبيت ميزات الغلاف (غلاف استخراج الويب وأمر `extract`): + - تثبيت ميزات Shell (Shell الـ Web Scraping وأمر `extract`): ```bash pip install "scrapling[shell]" ``` @@ -326,14 +401,7 @@ docker pull ghcr.io/d4vinci/scrapling:latest ## الشكر والتقدير يتضمن هذا المشروع كوداً معدلاً من: -- Parsel (ترخيص BSD) - يستخدم للوحدة الفرعية [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) - -## الشكر والمراجع - -- العمل الرائع لـ [Daijro](https://github.com/daijro) على [BrowserForge](https://github.com/daijro/browserforge) و[Camoufox](https://github.com/daijro/camoufox) -- العمل الرائع لـ [Vinyzu](https://github.com/Vinyzu) على [Botright](https://github.com/Vinyzu/Botright) و[PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright) -- [brotector](https://github.com/kaliiiiiiiiii/brotector) لتقنيات تجاوز اكتشاف المتصفح -- [fakebrowser](https://github.com/kkoooqq/fakebrowser) و[BotBrowser](https://github.com/botswin/BotBrowser) لأبحاث البصمات +- Parsel (ترخيص BSD) — يُستخدم للوحدة الفرعية [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) --- -
مصمم ومصنوع بـ ❤️ بواسطة كريم شعير.

\ No newline at end of file +
مصمم ومصنوع بـ ❤️ بواسطة كريم شعير.

diff --git a/docs/README_CN.md b/docs/README_CN.md index 93fb5e1..b2f0d77 100644 --- a/docs/README_CN.md +++ b/docs/README_CN.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - 选择方法 - - · - - 选择获取器 - - · - - 命令行界面 - - · - - MCP模式 - - · - - 从Beautifulsoup迁移 - + 选择方法 + · + 选择Fetcher + · + CLI + · + MCP模式 + · + 从Beautifulsoup迁移

-**停止与反机器人系统斗争。停止在每次网站更新后重写选择器。** +Scrapling是一个自适应Web Scraping框架,能处理从单个请求到大规模爬取的一切需求。 -Scrapling不仅仅是另一个网页抓取库。它是第一个**自适应**抓取库,能够从网站变化中学习并与之共同进化。当其他库在网站更新结构时失效,Scrapling会自动重新定位您的元素并保持抓取器运行。 +它的解析器能够从网站变化中学习,并在页面更新时自动重新定位您的元素。它的Fetcher能够开箱即用地绕过Cloudflare Turnstile等反机器人系统。它的Spider框架让您可以扩展到并发、多Session爬取,支持暂停/恢复和自动Proxy轮换——只需几行Python代码。一个库,零妥协。 -为现代网络而构建,Scrapling具有**自己的快速解析引擎**和获取器来处理您面临或将要面临的所有网页抓取挑战。由网页抓取者为网页抓取者和普通用户构建,适合每个人。 +极速爬取,实时统计和Streaming。由Web Scraper为Web Scraper和普通用户而构建,每个人都能找到适合自己的功能。 ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# 隐秘地获取网站源代码! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # 抓取在网站设计变更后仍能存活的数据! ->> # 之后,如果网站结构改变,传递 `adaptive=True` ->> products = page.css('.product', adaptive=True) # Scrapling仍然能找到它们! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # 隐秘地获取网站! +products = page.css('.product', auto_save=True) # 抓取在网站设计变更后仍能存活的数据! +products = page.css('.product', adaptive=True) # 之后,如果网站结构改变,传递 `adaptive=True` 来找到它们! +``` +或扩展为完整爬取 +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# 赞助商 + +# 赞助商 @@ -91,122 +93,195 @@ Scrapling不仅仅是另一个网页抓取库。它是第一个**自适应**抓 ## 主要特性 -### 支持会话的高级网站获取 -- **HTTP请求**:使用`Fetcher`类进行快速和隐秘的HTTP请求。可以模拟浏览器的TLS指纹、标头并使用HTTP3。 +### Spider — 完整的爬取框架 +- 🕷️ **类Scrapy的Spider API**:使用`start_urls`、async `parse` callback和`Request`/`Response`对象定义Spider。 +- ⚡ **并发爬取**:可配置的并发限制、按域名节流和下载延迟。 +- 🔄 **多Session支持**:统一接口,支持HTTP请求和隐秘无头浏览器在同一个Spider中使用——通过ID将请求路由到不同的Session。 +- 💾 **暂停与恢复**:基于Checkpoint的爬取持久化。按Ctrl+C优雅关闭;重启后从上次停止的地方继续。 +- 📡 **Streaming模式**:通过`async for item in spider.stream()`以实时统计Streaming抓取的数据——非常适合UI、管道和长时间运行的爬取。 +- 🛡️ **被阻止请求检测**:自动检测并重试被阻止的请求,支持自定义逻辑。 +- 📦 **内置导出**:通过钩子和您自己的管道导出结果,或使用内置的JSON/JSONL,分别通过`result.items.to_json()`/`result.items.to_jsonl()`。 + +### 支持Session的高级网站获取 +- **HTTP请求**:使用`Fetcher`类进行快速和隐秘的HTTP请求。可以模拟浏览器的TLS fingerprint、标头并使用HTTP/3。 - **动态加载**:通过`DynamicFetcher`类使用完整的浏览器自动化获取动态网站,支持Playwright的Chromium和Google Chrome。 -- **反机器人绕过**:使用`StealthyFetcher`的高级隐秘功能和指纹伪装。可以轻松自动绕过所有类型的Cloudflare的Turnstile/Interstitial。 -- **会话管理**:使用`FetcherSession`、`StealthySession`和`DynamicSession`类持久化会话支持,用于跨请求的cookie和状态管理。 -- **异步支持**:所有获取器和专用异步会话类的完整异步支持。 +- **反机器人绕过**:使用`StealthyFetcher`的高级隐秘功能和fingerprint伪装。可以轻松自动绕过所有类型的Cloudflare Turnstile/Interstitial。 +- **Session管理**:使用`FetcherSession`、`StealthySession`和`DynamicSession`类实现持久化Session支持,用于跨请求的cookie和状态管理。 +- **Proxy轮换**:内置`ProxyRotator`,支持轮询或自定义策略,适用于所有Session类型,并支持按请求覆盖Proxy。 +- **域名屏蔽**:在基于浏览器的Fetcher中屏蔽对特定域名(及其子域名)的请求。 +- **Async支持**:所有Fetcher和专用async Session类的完整async支持。 ### 自适应抓取和AI集成 - 🔄 **智能元素跟踪**:使用智能相似性算法在网站更改后重新定位元素。 - 🎯 **智能灵活选择**:CSS选择器、XPath选择器、基于过滤器的搜索、文本搜索、正则表达式搜索等。 -- 🔍 **查找相似元素**:自动定位与找到的元素相似的元素。 -- 🤖 **与AI一起使用的MCP服务器**:内置MCP服务器用于AI辅助网页抓取和数据提取。MCP服务器具有强大的自定义功能,利用Scrapling在将内容传递给AI(Claude/Cursor等)之前提取目标内容,从而加快操作并通过最小化令牌使用来降低成本。([演示视频](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) +- 🔍 **查找相似元素**:自动定位与已找到元素相似的元素。 +- 🤖 **与AI一起使用的MCP服务器**:内置MCP服务器用于AI辅助Web Scraping和数据提取。MCP服务器具有强大的自定义功能,利用Scrapling在将内容传递给AI(Claude/Cursor等)之前提取目标内容,从而加快操作并通过最小化token使用来降低成本。([演示视频](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) ### 高性能和经过实战测试的架构 - 🚀 **闪电般快速**:优化性能超越大多数Python抓取库。 - 🔋 **内存高效**:优化的数据结构和延迟加载,最小内存占用。 - ⚡ **快速JSON序列化**:比标准库快10倍。 -- 🏗️ **经过实战测试**:Scrapling不仅拥有92%的测试覆盖率和完整的类型提示覆盖率,而且在过去一年中每天被数百名网页抓取者使用。 +- 🏗️ **经过实战测试**:Scrapling不仅拥有92%的测试覆盖率和完整的类型提示覆盖率,而且在过去一年中每天被数百名Web Scraper使用。 -### 对开发者/网页抓取者友好的体验 -- 🎯 **交互式网页抓取Shell**:可选的内置IPython shell,具有Scrapling集成、快捷方式和新工具,可加快网页抓取脚本开发,例如将curl请求转换为Scrapling请求并在浏览器中查看请求结果。 +### 对开发者/Web Scraper友好的体验 +- 🎯 **交互式Web Scraping Shell**:可选的内置IPython Shell,具有Scrapling集成、快捷方式和新工具,可加快Web Scraping脚本开发,例如将curl请求转换为Scrapling请求并在浏览器中查看请求结果。 - 🚀 **直接从终端使用**:可选地,您可以使用Scrapling抓取URL而无需编写任何代码! - 🛠️ **丰富的导航API**:使用父级、兄弟级和子级导航方法进行高级DOM遍历。 - 🧬 **增强的文本处理**:内置正则表达式、清理方法和优化的字符串操作。 - 📝 **自动选择器生成**:为任何元素生成强大的CSS/XPath选择器。 - 🔌 **熟悉的API**:类似于Scrapy/BeautifulSoup,使用与Scrapy/Parsel相同的伪元素。 -- 📘 **完整的类型覆盖**:完整的类型提示,出色的IDE支持和代码补全。 +- 📘 **完整的类型覆盖**:完整的类型提示,出色的IDE支持和代码补全。整个代码库在每次更改时都会自动使用**PyRight**和**MyPy**扫描。 - 🔋 **现成的Docker镜像**:每次发布时,包含所有浏览器的Docker镜像会自动构建和推送。 ## 入门 -### 基本用法 -```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +让我们快速展示Scrapling的功能,无需深入了解。 -# 支持会话的HTTP请求 -with FetcherSession(impersonate='chrome') as session: # 使用Chrome的最新版本TLS指纹 +### 基本用法 +支持Session的HTTP请求 +```python +from scrapling.fetchers import Fetcher, FetcherSession + +with FetcherSession(impersonate='chrome') as session: # 使用Chrome的最新版本TLS fingerprint page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # 或使用一次性请求 page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +高级隐秘模式 +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# 高级隐秘模式(保持浏览器打开直到完成) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # 保持浏览器打开直到完成 page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() # 或使用一次性请求样式,为此请求打开浏览器,完成后关闭 page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# 完整的浏览器自动化(保持浏览器打开直到完成) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +完整的浏览器自动化 +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# 或使用一次性请求样式 -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # 保持浏览器打开直到完成 + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # 如果您偏好XPath选择器 + +# 或使用一次性请求样式,为此请求打开浏览器,完成后关闭 +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### 元素选择 +### Spider +构建具有并发请求、多种Session类型和暂停/恢复功能的完整爬虫: ```python -# CSS选择器 -page.css('a::text') # 提取文本 -page.css('a::attr(href)') # 提取属性 -page.css('a', recursive=False) # 仅直接元素 -page.css('a', auto_save=True) # 自动保存元素位置 +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# 灵活搜索 -page.find_by_text('Python', first_match=True) # 按文本查找 -page.find_by_regex(r'\d{4}') # 按正则表达式模式查找 -page.find('div', {'class': 'container'}) # 按属性查找 + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# 导航 -element.parent # 获取父元素 -element.next_sibling # 获取下一个兄弟元素 -element.children # 获取子元素 + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# 相似元素 -similar = page.get_similar(element) # 查找相似元素 - -# 自适应抓取 -saved_elements = page.css('.product', auto_save=True) -# 之后,当网站更改时: -page.css('.product', adaptive=True) # 使用保存的位置查找元素 +result = QuotesSpider().start() +print(f"抓取了 {len(result.items)} 条引用") +result.items.to_json("quotes.json") ``` - -### 会话使用 +在单个Spider中使用多种Session类型: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# 同步会话 -with FetcherSession() as session: - # Cookie自动保持 - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # 如需要,切换浏览器指纹 +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # 将受保护的页面路由到隐秘Session + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # 显式callback +``` +通过如下方式运行Spider来暂停和恢复长时间爬取,使用Checkpoint: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +按Ctrl+C优雅暂停——进度会自动保存。之后,当您再次启动Spider时,传递相同的`crawldir`,它将从上次停止的地方继续。 + +### 高级解析与导航 +```python +from scrapling.fetchers import Fetcher + +# 丰富的元素选择和导航 +page = Fetcher.get('https://quotes.toscrape.com/') + +# 使用多种选择方法获取引用 +quotes = page.css('.quote') # CSS选择器 +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoup风格 +# 等同于 +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # 等等... +# 按文本内容查找元素 +quotes = page.find_by_text('quote', tag='div') + +# 高级导航 +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # 链式选择器 +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# 元素关系和相似性 +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +如果您不想获取网站,可以直接使用解析器,如下所示: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +用法完全相同! + +### Async Session管理示例 +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession`是上下文感知的,可以在sync/async模式下工作 + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') -# 异步会话使用 +# Async Session用法 async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - + print(session.get_pool_stats()) # 可选 - 浏览器标签池的状态(忙/空闲/错误) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) @@ -214,11 +289,11 @@ async with AsyncStealthySession(max_pages=2) as session: ## CLI和交互式Shell -Scrapling v0.3包含强大的命令行界面: +Scrapling包含强大的命令行界面: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) -启动交互式网页抓取shell +启动交互式Web Scraping Shell ```bash scrapling shell ``` @@ -231,24 +306,24 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> 还有许多其他功能,但我们希望保持此页面简洁,例如MCP服务器和交互式网页抓取Shell。查看完整文档[这里](https://scrapling.readthedocs.io/en/latest/) +> 还有许多其他功能,但我们希望保持此页面简洁,包括MCP服务器和交互式Web Scraping Shell。查看完整文档[这里](https://scrapling.readthedocs.io/en/latest/) ## 性能基准 -Scrapling不仅功能强大——它还速度极快,自0.3版本以来的更新在所有操作中都提供了卓越的性能改进。以下基准测试将Scrapling的解析器与其他流行库进行了比较。 +Scrapling不仅功能强大——它还速度极快。以下基准测试将Scrapling的解析器与其他流行库的最新版本进行了比较。 ### 文本提取速度测试(5000个嵌套元素) -| # | 库 | 时间(ms) | vs Scrapling | -|---|:-----------------:|:-------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| # | 库 | 时间(ms) | vs Scrapling | +|---|:-----------------:|:---------:|:------------:| +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### 元素相似性和文本搜索性能 @@ -256,9 +331,9 @@ Scrapling不仅功能强大——它还速度极快,自0.3版本以来的更 Scrapling的自适应元素查找功能明显优于替代方案: | 库 | 时间(ms) | vs Scrapling | -|-------------|:------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +|-------------|:---------:|:------------:| +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > 所有基准测试代表100+次运行的平均值。请参阅[benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py)了解方法。 @@ -271,25 +346,25 @@ Scrapling需要Python 3.10或更高版本: pip install scrapling ``` -从v0.3.2开始,此安装仅包括解析器引擎及其依赖项,没有任何获取器或命令行依赖项。 +此安装仅包括解析器引擎及其依赖项,没有任何Fetcher或命令行依赖项。 ### 可选依赖项 -1. 如果您要使用以下任何额外功能、获取器或它们的类,您将需要安装获取器的依赖项和它们的浏览器依赖项,如下所示: +1. 如果您要使用以下任何额外功能、Fetcher或它们的类,您将需要安装Fetcher的依赖项和它们的浏览器依赖项,如下所示: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - 这会下载所有浏览器,以及它们的系统依赖项和指纹操作依赖项。 + 这会下载所有浏览器,以及它们的系统依赖项和fingerprint操作依赖项。 2. 额外功能: - 安装MCP服务器功能: ```bash pip install "scrapling[ai]" ``` - - 安装shell功能(网页抓取shell和`extract`命令): + - 安装Shell功能(Web Scraping Shell和`extract`命令): ```bash pip install "scrapling[shell]" ``` @@ -328,12 +403,5 @@ docker pull ghcr.io/d4vinci/scrapling:latest 此项目包含改编自以下内容的代码: - Parsel(BSD许可证)——用于[translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py)子模块 -## 感谢和参考 - -- [Daijro](https://github.com/daijro)在[BrowserForge](https://github.com/daijro/browserforge)和[Camoufox](https://github.com/daijro/camoufox)上的出色工作 -- [Vinyzu](https://github.com/Vinyzu)在[Botright](https://github.com/Vinyzu/Botright)和[PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright)上的出色工作 -- [brotector](https://github.com/kaliiiiiiiiii/brotector)提供的浏览器检测绕过技术 -- [fakebrowser](https://github.com/kkoooqq/fakebrowser)和[BotBrowser](https://github.com/botswin/BotBrowser)提供的指纹识别研究 - --- -
由Karim Shoair用❤️设计和制作。

\ No newline at end of file +
由Karim Shoair用❤️设计和制作。

diff --git a/docs/README_DE.md b/docs/README_DE.md index cec06af..51424b3 100644 --- a/docs/README_DE.md +++ b/docs/README_DE.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - Auswahlmethoden - - · - - Fetcher wählen - - · - - CLI - - · - - MCP-Modus - - · - - Migration von Beautifulsoup - + Auswahlmethoden + · + Einen Fetcher wählen + · + CLI + · + MCP-Modus + · + Migration von Beautifulsoup

-**Hören Sie auf, gegen Anti-Bot-Systeme zu kämpfen. Hören Sie auf, Selektoren nach jedem Website-Update neu zu schreiben.** +Scrapling ist ein adaptives Web-Scraping-Framework, das alles abdeckt -- von einer einzelnen Anfrage bis hin zu einem umfassenden Crawl. -Scrapling ist nicht nur eine weitere Web-Scraping-Bibliothek. Es ist die erste **adaptive** Scraping-Bibliothek, die von Website-Änderungen lernt und sich mit ihnen weiterentwickelt. Während andere Bibliotheken brechen, wenn Websites ihre Struktur aktualisieren, lokalisiert Scrapling Ihre Elemente automatisch neu und hält Ihre Scraper am Laufen. +Sein Parser lernt aus Website-Änderungen und lokalisiert Ihre Elemente automatisch neu, wenn sich Seiten aktualisieren. Seine Fetcher umgehen Anti-Bot-Systeme wie Cloudflare Turnstile direkt ab Werk. Und sein Spider-Framework ermöglicht es Ihnen, auf parallele Multi-Session-Crawls mit Pause & Resume und automatischer Proxy-Rotation hochzuskalieren -- alles in wenigen Zeilen Python. Eine Bibliothek, keine Kompromisse. -Für das moderne Web entwickelt, bietet Scrapling **seine eigene schnelle Parsing-Engine** und Fetcher, um alle Web-Scraping-Herausforderungen zu bewältigen, denen Sie begegnen oder begegnen werden. Von Web Scrapern für Web Scraper und normale Benutzer entwickelt, ist für jeden etwas dabei. +Blitzschnelle Crawls mit Echtzeit-Statistiken und Streaming. Von Web Scrapern für Web Scraper und normale Benutzer entwickelt, ist für jeden etwas dabei. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# Holen Sie sich Website-Quellcode unter dem Radar! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # Scrapen Sie Daten, die Website-Designänderungen überleben! ->> # Später, wenn sich die Website-Struktur ändert, übergeben Sie `adaptive=True` ->> products = page.css('.product', adaptive=True) # und Scrapling findet sie trotzdem! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # Website unbemerkt abrufen! +products = page.css('.product', auto_save=True) # Daten scrapen, die Website-Designänderungen überleben! +products = page.css('.product', adaptive=True) # Später, wenn sich die Website-Struktur ändert, `adaptive=True` übergeben, um sie zu finden! +``` +Oder auf vollständige Crawls hochskalieren +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# Sponsoren + +# Sponsoren @@ -91,12 +93,23 @@ Für das moderne Web entwickelt, bietet Scrapling **seine eigene schnelle Parsin ## Hauptmerkmale -### Erweiterte Website-Abruf mit Sitzungsunterstützung -- **HTTP-Anfragen**: Schnelle und heimliche HTTP-Anfragen mit der `Fetcher`-Klasse. Kann Browser-TLS-Fingerabdrücke, Header imitieren und HTTP3 verwenden. -- **Dynamisches Laden**: Abrufen dynamischer Websites mit vollständiger Browser-Automatisierung über die `DynamicFetcher`-Klasse, die Playwrights Chromium und Google Chrome unterstützt. -- **Anti-Bot-Umgehung**: Erweiterte Stealth-Fähigkeiten mit `StealthyFetcher` und Fingerabdruck-Spoofing. Kann alle Arten von Cloudflares Turnstile/Interstitial einfach mit Automatisierung umgehen. -- **Sitzungsverwaltung**: Persistente Sitzungsunterstützung mit den Klassen `FetcherSession`, `StealthySession` und `DynamicSession` für Cookie- und Zustandsverwaltung über Anfragen hinweg. -- **Async-Unterstützung**: Vollständige Async-Unterstützung über alle Fetcher und dedizierte Async-Sitzungsklassen hinweg. +### Spiders -- Ein vollständiges Crawling-Framework +- 🕷️ **Scrapy-ähnliche Spider-API**: Definieren Sie Spiders mit `start_urls`, async `parse` Callbacks und `Request`/`Response`-Objekten. +- ⚡ **Paralleles Crawling**: Konfigurierbare Parallelitätslimits, domainbezogenes Throttling und Download-Verzögerungen. +- 🔄 **Multi-Session-Unterstützung**: Einheitliche Schnittstelle für HTTP-Anfragen und heimliche Headless-Browser in einem einzigen Spider -- leiten Sie Anfragen per ID an verschiedene Sessions weiter. +- 💾 **Pause & Resume**: Checkpoint-basierte Crawl-Persistenz. Drücken Sie Strg+C für ein kontrolliertes Herunterfahren; starten Sie neu, um dort fortzufahren, wo Sie aufgehört haben. +- 📡 **Streaming-Modus**: Gescrapte Elemente in Echtzeit streamen über `async for item in spider.stream()` mit Echtzeit-Statistiken -- ideal für UI, Pipelines und lang laufende Crawls. +- 🛡️ **Erkennung blockierter Anfragen**: Automatische Erkennung und Wiederholung blockierter Anfragen mit anpassbarer Logik. +- 📦 **Integrierter Export**: Ergebnisse über Hooks und Ihre eigene Pipeline oder den integrierten JSON/JSONL-Export mit `result.items.to_json()` / `result.items.to_jsonl()` exportieren. + +### Erweitertes Website-Abrufen mit Session-Unterstützung +- **HTTP-Anfragen**: Schnelle und heimliche HTTP-Anfragen mit der `Fetcher`-Klasse. Kann Browser-TLS-Fingerprints und Header imitieren und HTTP/3 verwenden. +- **Dynamisches Laden**: Dynamische Websites mit vollständiger Browser-Automatisierung über die `DynamicFetcher`-Klasse abrufen, die Playwrights Chromium und Google Chrome unterstützt. +- **Anti-Bot-Umgehung**: Erweiterte Stealth-Fähigkeiten mit `StealthyFetcher` und Fingerprint-Spoofing. Kann alle Arten von Cloudflares Turnstile/Interstitial einfach mit Automatisierung umgehen. +- **Session-Verwaltung**: Persistente Session-Unterstützung mit den Klassen `FetcherSession`, `StealthySession` und `DynamicSession` für Cookie- und Zustandsverwaltung über Anfragen hinweg. +- **Proxy-Rotation**: Integrierter `ProxyRotator` mit Round-Robin- oder benutzerdefinierten Strategien über alle Session-Typen hinweg, plus Proxy-Überschreibungen pro Anfrage. +- **Domain-Blockierung**: Anfragen an bestimmte Domains (und deren Subdomains) in browserbasierten Fetchern blockieren. +- **Async-Unterstützung**: Vollständige async-Unterstützung über alle Fetcher und dedizierte async Session-Klassen hinweg. ### Adaptives Scraping & KI-Integration - 🔄 **Intelligente Element-Verfolgung**: Elemente nach Website-Änderungen mit intelligenten Ähnlichkeitsalgorithmen neu lokalisieren. @@ -110,103 +123,165 @@ Für das moderne Web entwickelt, bietet Scrapling **seine eigene schnelle Parsin - ⚡ **Schnelle JSON-Serialisierung**: 10x schneller als die Standardbibliothek. - 🏗️ **Praxiserprobt**: Scrapling hat nicht nur eine Testabdeckung von 92% und eine vollständige Type-Hints-Abdeckung, sondern wird seit dem letzten Jahr täglich von Hunderten von Web Scrapern verwendet. -### Entwickler/Web-Scraper-freundliche Erfahrung +### Entwickler-/Web-Scraper-freundliche Erfahrung - 🎯 **Interaktive Web-Scraping-Shell**: Optionale integrierte IPython-Shell mit Scrapling-Integration, Shortcuts und neuen Tools zur Beschleunigung der Web-Scraping-Skriptentwicklung, wie das Konvertieren von Curl-Anfragen in Scrapling-Anfragen und das Anzeigen von Anfrageergebnissen in Ihrem Browser. - 🚀 **Direkt vom Terminal aus verwenden**: Optional können Sie Scrapling verwenden, um eine URL zu scrapen, ohne eine einzige Codezeile zu schreiben! - 🛠️ **Umfangreiche Navigations-API**: Erweiterte DOM-Traversierung mit Eltern-, Geschwister- und Kind-Navigationsmethoden. - 🧬 **Verbesserte Textverarbeitung**: Integrierte Regex, Bereinigungsmethoden und optimierte String-Operationen. - 📝 **Automatische Selektorgenerierung**: Robuste CSS/XPath-Selektoren für jedes Element generieren. - 🔌 **Vertraute API**: Ähnlich wie Scrapy/BeautifulSoup mit denselben Pseudo-Elementen, die in Scrapy/Parsel verwendet werden. -- 📘 **Vollständige Typabdeckung**: Vollständige Type Hints für hervorragende IDE-Unterstützung und Code-Vervollständigung. +- 📘 **Vollständige Typabdeckung**: Vollständige Type Hints für hervorragende IDE-Unterstützung und Code-Vervollständigung. Die gesamte Codebasis wird bei jeder Änderung automatisch mit **PyRight** und **MyPy** gescannt. - 🔋 **Fertiges Docker-Image**: Mit jeder Veröffentlichung wird automatisch ein Docker-Image erstellt und gepusht, das alle Browser enthält. ## Erste Schritte +Hier ein kurzer Überblick über das, was Scrapling kann, ohne zu sehr ins Detail zu gehen. + ### Grundlegende Verwendung +HTTP-Anfragen mit Session-Unterstützung ```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +from scrapling.fetchers import Fetcher, FetcherSession -# HTTP-Anfragen mit Sitzungsunterstützung -with FetcherSession(impersonate='chrome') as session: # Verwenden Sie die neueste Version von Chromes TLS-Fingerabdruck +with FetcherSession(impersonate='chrome') as session: # Neueste Version von Chromes TLS-Fingerprint verwenden page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() -# Oder verwenden Sie einmalige Anfragen +# Oder einmalige Anfragen verwenden page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +Erweiterter Stealth-Modus +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# Erweiterter Stealth-Modus (Browser offen halten, bis Sie fertig sind) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # Browser offen halten, bis Sie fertig sind page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() -# Oder verwenden Sie den einmaligen Anfragenstil, öffnet den Browser für diese Anfrage und schließt ihn dann nach Abschluss +# Oder einmaligen Anfragenstil verwenden: öffnet den Browser für diese Anfrage und schließt ihn nach Abschluss page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# Vollständige Browser-Automatisierung (Browser offen halten, bis Sie fertig sind) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +Vollständige Browser-Automatisierung +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# Oder verwenden Sie den einmaligen Anfragenstil -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # Browser offen halten, bis Sie fertig sind + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # XPath-Selektor, falls bevorzugt + +# Oder einmaligen Anfragenstil verwenden: öffnet den Browser für diese Anfrage und schließt ihn nach Abschluss +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### Elementauswahl +### Spiders +Vollständige Crawler mit parallelen Anfragen, mehreren Session-Typen und Pause & Resume erstellen: ```python -# CSS-Selektoren -page.css('a::text') # Text extrahieren -page.css('a::attr(href)') # Attribute extrahieren -page.css('a', recursive=False) # Nur direkte Elemente -page.css('a', auto_save=True) # Elementpositionen automatisch speichern +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# Flexible Suche -page.find_by_text('Python', first_match=True) # Nach Text suchen -page.find_by_regex(r'\d{4}') # Nach Regex-Muster suchen -page.find('div', {'class': 'container'}) # Nach Attributen suchen + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# Navigation -element.parent # Elternelement abrufen -element.next_sibling # Nächstes Geschwister abrufen -element.children # Kindelemente abrufen + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# Ähnliche Elemente -similar = page.get_similar(element) # Ähnliche Elemente finden - -# Adaptives Scraping -saved_elements = page.css('.product', auto_save=True) -# Später, wenn sich die Website ändert: -page.css('.product', adaptive=True) # Elemente mithilfe gespeicherter Positionen finden +result = QuotesSpider().start() +print(f"{len(result.items)} Zitate gescrapt") +result.items.to_json("quotes.json") ``` - -### Sitzungsverwendung +Mehrere Session-Typen in einem einzigen Spider verwenden: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# Synchrone Sitzung -with FetcherSession() as session: - # Cookies werden automatisch beibehalten - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # Bei Bedarf Browser-Fingerabdruck wechseln +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # Geschützte Seiten über die Stealth-Session leiten + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # Expliziter Callback +``` +Lange Crawls mit Checkpoints pausieren und fortsetzen, indem Sie den Spider so starten: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +Drücken Sie Strg+C, um kontrolliert zu pausieren -- der Fortschritt wird automatisch gespeichert. Wenn Sie den Spider später erneut starten, übergeben Sie dasselbe `crawldir`, und er setzt dort fort, wo er aufgehört hat. + +### Erweitertes Parsing & Navigation +```python +from scrapling.fetchers import Fetcher + +# Umfangreiche Elementauswahl und Navigation +page = Fetcher.get('https://quotes.toscrape.com/') + +# Zitate mit verschiedenen Auswahlmethoden abrufen +quotes = page.css('.quote') # CSS-Selektor +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoup-Stil +# Gleich wie +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # und so weiter... +# Element nach Textinhalt finden +quotes = page.find_by_text('quote', tag='div') + +# Erweiterte Navigation +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # Verkettete Selektoren +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# Elementbeziehungen und Ähnlichkeit +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +Sie können den Parser direkt verwenden, wenn Sie keine Websites abrufen möchten, wie unten gezeigt: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +Und es funktioniert genau auf die gleiche Weise! + +### Beispiele für async Session-Verwaltung +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession` ist kontextbewusst und kann sowohl in sync- als auch in async-Mustern arbeiten + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') -# Async-Sitzungsverwendung +# Async-Session-Verwendung async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - + print(session.get_pool_stats()) # Optional - Der Status des Browser-Tab-Pools (beschäftigt/frei/Fehler) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) @@ -214,7 +289,7 @@ async with AsyncStealthySession(max_pages=2) as session: ## CLI & Interaktive Shell -Scrapling v0.3 enthält eine leistungsstarke Befehlszeilenschnittstelle: +Scrapling enthält eine leistungsstarke Befehlszeilenschnittstelle: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) @@ -222,7 +297,7 @@ Interaktive Web-Scraping-Shell starten ```bash scrapling shell ``` -Seiten direkt ohne Programmierung in eine Datei extrahieren (Extrahiert standardmäßig den Inhalt im `body`-Tag). Wenn die Ausgabedatei mit `.txt` endet, wird der Textinhalt des Ziels extrahiert. Wenn sie mit `.md` endet, ist es eine Markdown-Darstellung des HTML-Inhalts; wenn sie mit `.html` endet, ist es der HTML-Inhalt selbst. +Seiten direkt ohne Programmierung in eine Datei extrahieren (extrahiert standardmäßig den Inhalt im `body`-Tag). Wenn die Ausgabedatei mit `.txt` endet, wird der Textinhalt des Ziels extrahiert. Wenn sie mit `.md` endet, ist es eine Markdown-Darstellung des HTML-Inhalts; wenn sie mit `.html` endet, ist es der HTML-Inhalt selbst. ```bash scrapling extract get 'https://example.com' content.md scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # Alle Elemente, die dem CSS-Selektor '#fromSkipToProducts' entsprechen @@ -231,24 +306,24 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> Es gibt viele zusätzliche Funktionen, aber wir möchten diese Seite prägnant halten, wie den MCP-Server und die interaktive Web-Scraping-Shell. Schauen Sie sich die vollständige Dokumentation [hier](https://scrapling.readthedocs.io/en/latest/) an +> Es gibt viele zusätzliche Funktionen, aber wir möchten diese Seite prägnant halten, einschließlich des MCP-Servers und der interaktiven Web-Scraping-Shell. Schauen Sie sich die vollständige Dokumentation [hier](https://scrapling.readthedocs.io/en/latest/) an ## Leistungsbenchmarks -Scrapling ist nicht nur leistungsstark – es ist auch blitzschnell, und die Updates seit Version 0.3 haben außergewöhnliche Leistungsverbesserungen bei allen Operationen gebracht. Die folgenden Benchmarks vergleichen den Parser von Scrapling mit anderen beliebten Bibliotheken. +Scrapling ist nicht nur leistungsstark -- es ist auch blitzschnell. Die folgenden Benchmarks vergleichen Scraplings Parser mit den neuesten Versionen anderer beliebter Bibliotheken. ### Textextraktions-Geschwindigkeitstest (5000 verschachtelte Elemente) -| # | Bibliothek | Zeit (ms) | vs Scrapling | +| # | Bibliothek | Zeit (ms) | vs Scrapling | |---|:-----------------:|:---------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### Element-Ähnlichkeit & Textsuche-Leistung @@ -257,8 +332,8 @@ Scraplings adaptive Element-Finding-Fähigkeiten übertreffen Alternativen deutl | Bibliothek | Zeit (ms) | vs Scrapling | |-------------|:---------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > Alle Benchmarks stellen Durchschnittswerte von über 100 Durchläufen dar. Siehe [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) für die Methodik. @@ -271,18 +346,18 @@ Scrapling erfordert Python 3.10 oder höher: pip install scrapling ``` -Ab v0.3.2 enthält diese Installation nur die Parser-Engine und ihre Abhängigkeiten, ohne Fetcher oder Kommandozeilenabhängigkeiten. +Diese Installation enthält nur die Parser-Engine und ihre Abhängigkeiten, ohne Fetcher oder Kommandozeilenabhängigkeiten. ### Optionale Abhängigkeiten 1. Wenn Sie eine der folgenden zusätzlichen Funktionen, die Fetcher oder ihre Klassen verwenden möchten, müssen Sie die Abhängigkeiten der Fetcher und ihre Browser-Abhängigkeiten wie folgt installieren: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - Dies lädt alle Browser zusammen mit ihren Systemabhängigkeiten und Fingerabdruck-Manipulationsabhängigkeiten herunter. + Dies lädt alle Browser zusammen mit ihren Systemabhängigkeiten und Fingerprint-Manipulationsabhängigkeiten herunter. 2. Zusätzliche Funktionen: - MCP-Server-Funktion installieren: @@ -326,14 +401,7 @@ Diese Arbeit ist unter der BSD-3-Clause-Lizenz lizenziert. ## Danksagungen Dieses Projekt enthält angepassten Code von: -- Parsel (BSD-Lizenz) – Verwendet für [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py)-Submodul - -## Dank und Referenzen - -- [Daijros](https://github.com/daijro) brillante Arbeit an [BrowserForge](https://github.com/daijro/browserforge) und [Camoufox](https://github.com/daijro/camoufox) -- [Vinyzus](https://github.com/Vinyzu) brillante Arbeit an [Botright](https://github.com/Vinyzu/Botright) und [PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright) -- [brotector](https://github.com/kaliiiiiiiiii/brotector) für Browser-Erkennungs-Umgehungstechniken -- [fakebrowser](https://github.com/kkoooqq/fakebrowser) und [BotBrowser](https://github.com/botswin/BotBrowser) für Fingerprinting-Forschung +- Parsel (BSD-Lizenz) -- Verwendet für das [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py)-Submodul --- -
Entworfen und hergestellt mit ❤️ von Karim Shoair.

\ No newline at end of file +
Entworfen und hergestellt mit ❤️ von Karim Shoair.

diff --git a/docs/README_ES.md b/docs/README_ES.md index 9c27995..96aab01 100644 --- a/docs/README_ES.md +++ b/docs/README_ES.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - Métodos de selección - - · - - Elegir un fetcher - - · - - CLI - - · - - Modo MCP - - · - - Migrar desde Beautifulsoup - + Metodos de seleccion + · + Elegir un fetcher + · + CLI + · + Modo MCP + · + Migrar desde Beautifulsoup

-**Deja de luchar contra sistemas anti-bot. Deja de reescribir selectores después de cada actualización del sitio web.** +Scrapling es un framework de Web Scraping adaptativo que se encarga de todo, desde una sola solicitud hasta un rastreo a gran escala. -Scrapling no es solo otra biblioteca de Web Scraping. Es la primera biblioteca de scraping **adaptativa** que aprende de los cambios de los sitios web y evoluciona con ellos. Mientras que otras bibliotecas se rompen cuando los sitios web actualizan su estructura, Scrapling relocaliza automáticamente tus elementos y mantiene tus scrapers funcionando. +Su parser aprende de los cambios de los sitios web y relocaliza automáticamente tus elementos cuando las páginas se actualizan. Sus fetchers evaden sistemas anti-bot como Cloudflare Turnstile de forma nativa. Y su framework Spider te permite escalar a rastreos concurrentes con múltiples sesiones, con Pause & Resume y rotación automática de Proxy, todo en unas pocas líneas de Python. Una biblioteca, cero compromisos. -Construido para la Web moderna, Scrapling presenta **su propio motor de análisis rápido** y fetchers para manejar todos los desafíos de Web Scraping que enfrentas o enfrentarás. Construido por Web Scrapers para Web Scrapers y usuarios regulares, hay algo para todos. +Rastreos ultrarrápidos con estadísticas en tiempo real y Streaming. Construido por Web Scrapers para Web Scrapers y usuarios regulares, hay algo para todos. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# ¡Obtén el código fuente de sitios web bajo el radar! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # ¡Extrae datos que sobreviven a cambios de diseño del sitio web! ->> # Más tarde, si la estructura del sitio web cambia, pasa `adaptive=True` ->> products = page.css('.product', adaptive=True) # ¡y Scrapling aún los encuentra! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # ¡Obtén el sitio web bajo el radar! +products = page.css('.product', auto_save=True) # ¡Extrae datos que sobreviven a cambios de diseño del sitio web! +products = page.css('.product', adaptive=True) # Más tarde, si la estructura del sitio web cambia, ¡pasa `adaptive=True` para encontrarlos! +``` +O escala a rastreos completos +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# Patrocinadores + +# Patrocinadores @@ -91,24 +93,35 @@ Construido para la Web moderna, Scrapling presenta **su propio motor de análisi ## Características Principales -### Obtención Avanzada de Sitios Web con Soporte de Sesión -- **Solicitudes HTTP**: Solicitudes HTTP rápidas y sigilosas con la clase `Fetcher`. Puede imitar la huella TLS de los navegadores, encabezados y usar HTTP3. +### Spiders — Un Framework Completo de Rastreo +- 🕷️ **API de Spider al estilo Scrapy**: Define spiders con `start_urls`, callbacks async `parse`, y objetos `Request`/`Response`. +- ⚡ **Rastreo Concurrente**: Límites de concurrencia configurables, limitación por dominio y retrasos de descarga. +- 🔄 **Soporte Multi-Session**: Interfaz unificada para solicitudes HTTP y navegadores headless sigilosos en un solo Spider — enruta solicitudes a diferentes sesiones por ID. +- 💾 **Pause & Resume**: Persistencia de rastreo basada en Checkpoint. Presiona Ctrl+C para un cierre ordenado; reinicia para continuar desde donde lo dejaste. +- 📡 **Modo Streaming**: Transmite elementos extraídos a medida que llegan con `async for item in spider.stream()` con estadísticas en tiempo real — ideal para UI, pipelines y rastreos de larga duración. +- 🛡️ **Detección de Solicitudes Bloqueadas**: Detección automática y reintento de solicitudes bloqueadas con lógica personalizable. +- 📦 **Exportación Integrada**: Exporta resultados a través de hooks y tu propio pipeline o el JSON/JSONL integrado con `result.items.to_json()` / `result.items.to_jsonl()` respectivamente. + +### Obtención Avanzada de Sitios Web con Soporte de Session +- **Solicitudes HTTP**: Solicitudes HTTP rápidas y sigilosas con la clase `Fetcher`. Puede imitar el fingerprint TLS de los navegadores, encabezados y usar HTTP/3. - **Carga Dinámica**: Obtén sitios web dinámicos con automatización completa del navegador a través de la clase `DynamicFetcher` compatible con Chromium de Playwright y Google Chrome. -- **Evasión Anti-bot**: Capacidades de sigilo avanzadas con `StealthyFetcher` y falsificación de huellas digitales. Puede evadir fácilmente todos los tipos de Turnstile/Interstitial de Cloudflare con automatización. -- **Gestión de Sesión**: Soporte de sesión persistente con las clases `FetcherSession`, `StealthySession` y `DynamicSession` para la gestión de cookies y estado entre solicitudes. +- **Evasión Anti-bot**: Capacidades de sigilo avanzadas con `StealthyFetcher` y falsificación de fingerprint. Puede evadir fácilmente todos los tipos de Turnstile/Interstitial de Cloudflare con automatización. +- **Gestión de Session**: Soporte de sesión persistente con las clases `FetcherSession`, `StealthySession` y `DynamicSession` para la gestión de cookies y estado entre solicitudes. +- **Rotación de Proxy**: `ProxyRotator` integrado con estrategias round-robin o personalizadas en todos los tipos de sesión, además de sobrescrituras de Proxy por solicitud. +- **Bloqueo de Dominios**: Bloquea solicitudes a dominios específicos (y sus subdominios) en fetchers basados en navegador. - **Soporte Async**: Soporte async completo en todos los fetchers y clases de sesión async dedicadas. ### Scraping Adaptativo e Integración con IA - 🔄 **Seguimiento Inteligente de Elementos**: Relocaliza elementos después de cambios en el sitio web usando algoritmos inteligentes de similitud. - 🎯 **Selección Flexible Inteligente**: Selectores CSS, selectores XPath, búsqueda basada en filtros, búsqueda de texto, búsqueda regex y más. - 🔍 **Encontrar Elementos Similares**: Localiza automáticamente elementos similares a los elementos encontrados. -- 🤖 **Servidor MCP para usar con IA**: Servidor MCP integrado para Web Scraping asistido por IA y extracción de datos. El servidor MCP presenta capacidades poderosas y personalizadas que aprovechan Scrapling para extraer contenido específico antes de pasarlo a la IA (Claude/Cursor/etc), acelerando así las operaciones y reduciendo costos al minimizar el uso de tokens. ([video demo](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) +- 🤖 **Servidor MCP para usar con IA**: Servidor MCP integrado para Web Scraping asistido por IA y extracción de datos. El servidor MCP presenta capacidades potentes y personalizadas que aprovechan Scrapling para extraer contenido específico antes de pasarlo a la IA (Claude/Cursor/etc), acelerando así las operaciones y reduciendo costos al minimizar el uso de tokens. ([video demo](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) ### Arquitectura de Alto Rendimiento y Probada en Batalla -- 🚀 **Ultrarrápido**: Rendimiento optimizado que supera a la mayoría de las bibliotecas de scraping de Python. +- 🚀 **Ultrarrápido**: Rendimiento optimizado que supera a la mayoría de las bibliotecas de Web Scraping de Python. - 🔋 **Eficiente en Memoria**: Estructuras de datos optimizadas y carga diferida para una huella de memoria mínima. - ⚡ **Serialización JSON Rápida**: 10 veces más rápido que la biblioteca estándar. -- 🏗️ **Probado en batalla**: Scrapling no solo tiene una cobertura de prueba del 92% y cobertura completa de type hints, sino que ha sido utilizado diariamente por cientos de Web Scrapers durante el último año. +- 🏗️ **Probado en batalla**: Scrapling no solo tiene una cobertura de pruebas del 92% y cobertura completa de type hints, sino que ha sido utilizado diariamente por cientos de Web Scrapers durante el último año. ### Experiencia Amigable para Desarrolladores/Web Scrapers - 🎯 **Shell Interactivo de Web Scraping**: Shell IPython integrado opcional con integración de Scrapling, atajos y nuevas herramientas para acelerar el desarrollo de scripts de Web Scraping, como convertir solicitudes curl a solicitudes Scrapling y ver resultados de solicitudes en tu navegador. @@ -117,96 +130,158 @@ Construido para la Web moderna, Scrapling presenta **su propio motor de análisi - 🧬 **Procesamiento de Texto Mejorado**: Métodos integrados de regex, limpieza y operaciones de cadena optimizadas. - 📝 **Generación Automática de Selectores**: Genera selectores CSS/XPath robustos para cualquier elemento. - 🔌 **API Familiar**: Similar a Scrapy/BeautifulSoup con los mismos pseudo-elementos usados en Scrapy/Parsel. -- 📘 **Cobertura Completa de Tipos**: Type hints completos para excelente soporte de IDE y autocompletado de código. +- 📘 **Cobertura Completa de Tipos**: Type hints completos para excelente soporte de IDE y autocompletado de código. Todo el código fuente se escanea automáticamente con **PyRight** y **MyPy** en cada cambio. - 🔋 **Imagen Docker Lista**: Con cada lanzamiento, se construye y publica automáticamente una imagen Docker que contiene todos los navegadores. -## Empezando +## Primeros Pasos + +Aquí tienes un vistazo rápido de lo que Scrapling puede hacer sin entrar en profundidad. ### Uso Básico +Solicitudes HTTP con soporte de sesión ```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +from scrapling.fetchers import Fetcher, FetcherSession -# Solicitudes HTTP con soporte de sesión -with FetcherSession(impersonate='chrome') as session: # Usa la última versión de la huella TLS de Chrome +with FetcherSession(impersonate='chrome') as session: # Usa la última versión del fingerprint TLS de Chrome page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # O usa solicitudes de una sola vez page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +Modo sigiloso avanzado +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# Modo sigiloso avanzado (Mantén el navegador abierto hasta que termines) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # Mantén el navegador abierto hasta que termines page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() # O usa el estilo de solicitud de una sola vez, abre el navegador para esta solicitud, luego lo cierra después de terminar page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# Automatización completa del navegador (Mantén el navegador abierto hasta que termines) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +Automatización completa del navegador +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# O usa el estilo de solicitud de una sola vez -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # Mantén el navegador abierto hasta que termines + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # Selector XPath si lo prefieres + +# O usa el estilo de solicitud de una sola vez, abre el navegador para esta solicitud, luego lo cierra después de terminar +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### Selección de Elementos +### Spiders +Construye rastreadores completos con solicitudes concurrentes, múltiples tipos de sesión y Pause & Resume: ```python -# CSS selectors -page.css('a::text') # Extracta texto -page.css('a::attr(href)') # Extracta atributos -page.css('a', recursive=False) # Solo elementos directos -page.css('a', auto_save=True) # Guarda posiciones de los elementos automáticamente +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# Búsqueda flexible -page.find_by_text('Python', first_match=True) # Encuentra por texto -page.find_by_regex(r'\d{4}') # Encuentra por patrón regex -page.find('div', {'class': 'container'}) # Encuentra por atributos + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# Navegación -element.parent # Obtener elemento padre -element.next_sibling # Obtener siguiente hermano -element.children # Obtener hijos + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# Elementos similares -similar = page.get_similar(element) # Encuentra elementos similares - -# Scraping adaptativo -saved_elements = page.css('.product', auto_save=True) -# Más tarde, cuando el sitio web cambia: -page.css('.product', adaptive=True) # Encuentra elementos usando posiciones guardadas +result = QuotesSpider().start() +print(f"Se extrajeron {len(result.items)} citas") +result.items.to_json("quotes.json") ``` - -### Uso de Sesión +Usa múltiples tipos de sesión en un solo Spider: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# Sesión sincrónica -with FetcherSession() as session: - # Las cookies se mantienen automáticamente - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # Cambiar fingerprint del navegador si es necesario +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # Enruta las páginas protegidas a través de la sesión sigilosa + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # callback explícito +``` +Pausa y reanuda rastreos largos con checkpoints ejecutando el Spider así: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +Presiona Ctrl+C para pausar de forma ordenada — el progreso se guarda automáticamente. Después, cuando inicies el Spider de nuevo, pasa el mismo `crawldir`, y continuará desde donde se detuvo. + +### Análisis Avanzado y Navegación +```python +from scrapling.fetchers import Fetcher + +# Selección rica de elementos y navegación +page = Fetcher.get('https://quotes.toscrape.com/') + +# Obtén citas con múltiples métodos de selección +quotes = page.css('.quote') # Selector CSS +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # Estilo BeautifulSoup +# Igual que +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # y así sucesivamente... +# Encuentra elementos por contenido de texto +quotes = page.find_by_text('quote', tag='div') + +# Navegación avanzada +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # Selectores encadenados +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# Relaciones y similitud de elementos +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +Puedes usar el parser directamente si no necesitas obtener sitios web, como se muestra a continuación: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +¡Y funciona exactamente de la misma manera! + +### Ejemplos de Gestión de Session Async +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession` es consciente del contexto y puede funcionar tanto en patrones sync/async + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') # Uso de sesión async async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - + print(session.get_pool_stats()) # Opcional - El estado del pool de pestañas del navegador (ocupado/libre/error) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) @@ -214,11 +289,11 @@ async with AsyncStealthySession(max_pages=2) as session: ## CLI y Shell Interactivo -Scrapling v0.3 incluye una poderosa interfaz de línea de comandos: +Scrapling incluye una poderosa interfaz de línea de comandos: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) -Lanzar shell interactivo de Web Scraping +Lanzar el Shell interactivo de Web Scraping ```bash scrapling shell ``` @@ -231,24 +306,24 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> Hay muchas características adicionales, pero queremos mantener esta página concisa, como el servidor MCP y el Shell Interactivo de Web Scraping. Consulta la documentación completa [aquí](https://scrapling.readthedocs.io/en/latest/) +> Hay muchas características adicionales, pero queremos mantener esta página concisa, incluyendo el servidor MCP y el Shell Interactivo de Web Scraping. Consulta la documentación completa [aquí](https://scrapling.readthedocs.io/en/latest/) ## Benchmarks de Rendimiento -Scrapling no solo es poderoso, también es increíblemente rápido, y las actualizaciones desde la versión 0.3 han brindado mejoras de rendimiento excepcionales en todas las operaciones. Los siguientes benchmarks comparan el analizador de Scrapling con otras bibliotecas populares. +Scrapling no solo es potente, también es ultrarrápido. Los siguientes benchmarks comparan el parser de Scrapling con las últimas versiones de otras bibliotecas populares. ### Prueba de Velocidad de Extracción de Texto (5000 elementos anidados) -| # | Biblioteca | Tiempo (ms) | vs Scrapling | +| # | Biblioteca | Tiempo (ms) | vs Scrapling | |---|:-----------------:|:-----------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### Rendimiento de Similitud de Elementos y Búsqueda de Texto @@ -257,8 +332,8 @@ Las capacidades de búsqueda adaptativa de elementos de Scrapling superan signif | Biblioteca | Tiempo (ms) | vs Scrapling | |-------------|:-----------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > Todos los benchmarks representan promedios de más de 100 ejecuciones. Ver [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) para la metodología. @@ -271,29 +346,29 @@ Scrapling requiere Python 3.10 o superior: pip install scrapling ``` -A partir de v0.3.2, esta instalación solo incluye el motor de análisis y sus dependencias, sin ningún fetcher o dependencias de línea de comandos. +Esta instalación solo incluye el motor de análisis y sus dependencias, sin ningún fetcher ni dependencias de línea de comandos. ### Dependencias Opcionales 1. Si vas a usar alguna de las características adicionales a continuación, los fetchers, o sus clases, necesitarás instalar las dependencias de los fetchers y sus dependencias del navegador de la siguiente manera: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - Esto descarga todos los navegadores, junto con sus dependencias del sistema y dependencias de manipulación de huellas digitales. + Esto descarga todos los navegadores, junto con sus dependencias del sistema y dependencias de manipulación de fingerprint. 2. Características adicionales: - Instalar la característica del servidor MCP: ```bash pip install "scrapling[ai]" ``` - - Instalar características del shell (shell de Web Scraping y el comando `extract`): + - Instalar características del Shell (Shell de Web Scraping y el comando `extract`): ```bash pip install "scrapling[shell]" ``` - - Instalar todo: + - Instalar todo: ```bash pip install "scrapling[all]" ``` @@ -328,12 +403,5 @@ Este trabajo está licenciado bajo la Licencia BSD-3-Clause. Este proyecto incluye código adaptado de: - Parsel (Licencia BSD)—Usado para el submódulo [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) -## Agradecimientos y Referencias - -- El brillante trabajo de [Daijro](https://github.com/daijro) en [BrowserForge](https://github.com/daijro/browserforge) y [Camoufox](https://github.com/daijro/camoufox) -- El brillante trabajo de [Vinyzu](https://github.com/Vinyzu) en [Botright](https://github.com/Vinyzu/Botright) y [PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright) -- [brotector](https://github.com/kaliiiiiiiiii/brotector) por técnicas de evasión de detección de navegador -- [fakebrowser](https://github.com/kkoooqq/fakebrowser) y [BotBrowser](https://github.com/botswin/BotBrowser) por investigación de huellas digitales - --- -
Diseñado y elaborado con ❤️ por Karim Shoair.

\ No newline at end of file +
Diseñado y elaborado con ❤️ por Karim Shoair.

diff --git a/docs/README_JP.md b/docs/README_JP.md index f86a7b1..041805b 100644 --- a/docs/README_JP.md +++ b/docs/README_JP.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - 選択メソッド - - · - - フェッチャーの選択 - - · - - CLI - - · - - MCPモード - - · - - Beautifulsoupからの移行 - + 選択メソッド + · + Fetcherの選び方 + · + CLI + · + MCPモード + · + Beautifulsoupからの移行

-**アンチボットシステムとの戦いをやめましょう。ウェブサイトが更新されるたびにセレクタを書き直すのをやめましょう。** +Scraplingは、単一のリクエストから本格的なクロールまですべてを処理する適応型Web Scrapingフレームワークです。 -Scraplingは単なるウェブスクレイピングライブラリではありません。ウェブサイトの変更から学習し、それとともに進化する最初の**適応型**スクレイピングライブラリです。他のライブラリがウェブサイトの構造が更新されると壊れる一方で、Scraplingは自動的に要素を再配置し、スクレイパーを稼働し続けます。 +そのパーサーはウェブサイトの変更から学習し、ページが更新されたときに要素を自動的に再配置します。Fetcherはすぐに使えるCloudflare Turnstileなどのアンチボットシステムを回避します。そしてSpiderフレームワークにより、Pause & Resumeや自動Proxy回転機能を備えた並行マルチSessionクロールへとスケールアップできます — すべてわずか数行のPythonで。1つのライブラリ、妥協なし。 -モダンウェブ向けに構築されたScraplingは、**独自の高速パースエンジン**とフェッチャーを備えており、あなたが直面する、または直面するであろうすべてのウェブスクレイピングの課題に対応します。ウェブスクレイパーによってウェブスクレイパーと一般ユーザーのために構築され、誰にでも何かがあります。 +リアルタイム統計とStreamingによる超高速クロール。Web Scraperによって、Web Scraperと一般ユーザーのために構築され、誰にでも何かがあります。 ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# レーダーの下でウェブサイトのソースを取得! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # ウェブサイトのデザイン変更に耐えるデータをスクレイプ! ->> # 後でウェブサイトの構造が変わったら、`adaptive=True`を渡す ->> products = page.css('.product', adaptive=True) # そしてScraplingはまだそれらを見つけます! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # レーダーの下でウェブサイトを取得! +products = page.css('.product', auto_save=True) # ウェブサイトのデザイン変更に耐えるデータをスクレイプ! +products = page.css('.product', adaptive=True) # 後でウェブサイトの構造が変わったら、`adaptive=True`を渡して見つける! +``` +または本格的なクロールへスケールアップ +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# スポンサー + +# スポンサー @@ -91,138 +93,211 @@ Scraplingは単なるウェブスクレイピングライブラリではあり ## 主な機能 -### セッションサポート付き高度なウェブサイト取得 -- **HTTPリクエスト**:`Fetcher`クラスで高速でステルスなHTTPリクエスト。ブラウザのTLSフィンガープリント、ヘッダーを模倣し、HTTP3を使用できます。 -- **動的読み込み**:Playwright's ChromiumとGoogle Chromeをサポートする`DynamicFetcher`クラスを通じた完全なブラウザ自動化で動的ウェブサイトを取得。 -- **アンチボット回避**:`StealthyFetcher`とフィンガープリント偽装による高度なステルス機能。自動化でCloudflareのTurnstile/Interstitialのすべてのタイプを簡単に回避できます。 -- **セッション管理**:リクエスト間でCookieと状態を管理するための`FetcherSession`、`StealthySession`、`DynamicSession`クラスによる永続的なセッションサポート。 -- **非同期サポート**:すべてのフェッチャーと専用非同期セッションクラス全体での完全な非同期サポート。 +### Spider — 本格的なクロールフレームワーク +- 🕷️ **Scrapy風のSpider API**:`start_urls`、async `parse` callback、`Request`/`Response`オブジェクトでSpiderを定義。 +- ⚡ **並行クロール**:設定可能な並行数制限、ドメインごとのスロットリング、ダウンロード遅延。 +- 🔄 **マルチSessionサポート**:HTTPリクエストとステルスヘッドレスブラウザの統一インターフェース — IDによって異なるSessionにリクエストをルーティング。 +- 💾 **Pause & Resume**:Checkpointベースのクロール永続化。Ctrl+Cで正常にシャットダウン;再起動すると中断したところから再開。 +- 📡 **Streamingモード**:`async for item in spider.stream()`でリアルタイム統計とともにスクレイプされたアイテムをStreamingで受信 — UI、パイプライン、長時間実行クロールに最適。 +- 🛡️ **ブロックされたリクエストの検出**:カスタマイズ可能なロジックによるブロックされたリクエストの自動検出とリトライ。 +- 📦 **組み込みエクスポート**:フックや独自のパイプライン、または組み込みのJSON/JSONLで結果をエクスポート。それぞれ`result.items.to_json()` / `result.items.to_jsonl()`を使用。 + +### Sessionサポート付き高度なウェブサイト取得 +- **HTTPリクエスト**:`Fetcher`クラスで高速かつステルスなHTTPリクエスト。ブラウザのTLS fingerprint、ヘッダーを模倣し、HTTP/3を使用可能。 +- **動的読み込み**:PlaywrightのChromiumとGoogle Chromeをサポートする`DynamicFetcher`クラスによる完全なブラウザ自動化で動的ウェブサイトを取得。 +- **アンチボット回避**:`StealthyFetcher`とfingerprint偽装による高度なステルス機能。自動化でCloudflareのTurnstile/Interstitialのすべてのタイプを簡単に回避。 +- **Session管理**:リクエスト間でCookieと状態を管理するための`FetcherSession`、`StealthySession`、`DynamicSession`クラスによる永続的なSessionサポート。 +- **Proxy回転**:すべてのSessionタイプに対応したラウンドロビンまたはカスタム戦略の組み込み`ProxyRotator`、さらにリクエストごとのProxyオーバーライド。 +- **ドメインブロック**:ブラウザベースのFetcherで特定のドメイン(およびそのサブドメイン)へのリクエストをブロック。 +- **asyncサポート**:すべてのFetcherおよび専用asyncSessionクラス全体での完全なasyncサポート。 ### 適応型スクレイピングとAI統合 - 🔄 **スマート要素追跡**:インテリジェントな類似性アルゴリズムを使用してウェブサイトの変更後に要素を再配置。 - 🎯 **スマート柔軟選択**:CSSセレクタ、XPathセレクタ、フィルタベース検索、テキスト検索、正規表現検索など。 -- 🔍 **類似要素を見つける**:見つかった要素に類似した要素を自動的に特定。 -- 🤖 **AIと使用するMCPサーバー**:AI支援ウェブスクレイピングとデータ抽出のための組み込みMCPサーバー。MCPサーバーは、AI(Claude/Cursorなど)に渡す前にScraplingを活用してターゲットコンテンツを抽出する強力でカスタムな機能を備えており、操作を高速化し、トークン使用量を最小限に抑えることでコストを削減します。([デモビデオ](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) +- 🔍 **類似要素の検出**:見つかった要素に類似した要素を自動的に特定。 +- 🤖 **AIと使用するMCPサーバー**:AI支援Web Scrapingとデータ抽出のための組み込みMCPサーバー。MCPサーバーは、AI(Claude/Cursorなど)に渡す前にScraplingを活用してターゲットコンテンツを抽出する強力でカスタムな機能を備えており、操作を高速化し、トークン使用量を最小限に抑えることでコストを削減します。([デモ動画](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) ### 高性能で実戦テスト済みのアーキテクチャ -- 🚀 **高速**:ほとんどのPythonスクレイピングライブラリを上回る最適化されたパフォーマンス。 +- 🚀 **超高速**:ほとんどのPythonスクレイピングライブラリを上回る最適化されたパフォーマンス。 - 🔋 **メモリ効率**:最小のメモリフットプリントのための最適化されたデータ構造と遅延読み込み。 - ⚡ **高速JSONシリアル化**:標準ライブラリの10倍の速度。 -- 🏗️ **実戦テスト済み**:Scraplingは92%のテストカバレッジと完全な型ヒントカバレッジを備えているだけでなく、過去1年間に数百人のウェブスクレイパーによって毎日使用されてきました。 +- 🏗️ **実戦テスト済み**:Scraplingは92%のテストカバレッジと完全な型ヒントカバレッジを備えているだけでなく、過去1年間に数百人のWeb Scraperによって毎日使用されてきました。 -### 開発者/ウェブスクレイパーにやさしい体験 -- 🎯 **インタラクティブウェブスクレイピングシェル**:Scraping統合、ショートカット、curlリクエストをScraplingリクエストに変換したり、ブラウザでリクエスト結果を表示したりするなどの新しいツールを備えたオプションの組み込みIPythonシェルで、ウェブスクレイピングスクリプトの開発を加速します。 +### 開発者/Web Scraperにやさしい体験 +- 🎯 **インタラクティブWeb Scraping Shell**:Scrapling統合、ショートカット、curlリクエストをScraplingリクエストに変換したり、ブラウザでリクエスト結果を表示したりするなどの新しいツールを備えたオプションの組み込みIPython Shellで、Web Scrapingスクリプトの開発を加速。 - 🚀 **ターミナルから直接使用**:オプションで、コードを一行も書かずにScraplingを使用してURLをスクレイプできます! - 🛠️ **豊富なナビゲーションAPI**:親、兄弟、子のナビゲーションメソッドによる高度なDOMトラバーサル。 - 🧬 **強化されたテキスト処理**:組み込みの正規表現、クリーニングメソッド、最適化された文字列操作。 - 📝 **自動セレクタ生成**:任意の要素に対して堅牢なCSS/XPathセレクタを生成。 -- 🔌 **馴染みのあるAPI**:Scrapy/Parselで使用されている同じ疑似要素を持つScrapy/BeautifulSoupに似ています。 -- 📘 **完全な型カバレッジ**:優れたIDEサポートとコード補完のための完全な型ヒント。 +- 🔌 **馴染みのあるAPI**:Scrapy/Parselで使用されている同じ疑似要素を持つScrapy/BeautifulSoupに似た設計。 +- 📘 **完全な型カバレッジ**:優れたIDEサポートとコード補完のための完全な型ヒント。コードベース全体が変更のたびに**PyRight**と**MyPy**で自動的にスキャンされます。 - 🔋 **すぐに使えるDockerイメージ**:各リリースで、すべてのブラウザを含むDockerイメージが自動的にビルドおよびプッシュされます。 ## はじめに -### 基本的な使い方 -```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +深く掘り下げずに、Scraplingにできることの簡単な概要をお見せしましょう。 -# セッションサポート付きHTTPリクエスト -with FetcherSession(impersonate='chrome') as session: # ChromeのTLSフィンガープリントの最新バージョンを使用 +### 基本的な使い方 +Sessionサポート付きHTTPリクエスト +```python +from scrapling.fetchers import Fetcher, FetcherSession + +with FetcherSession(impersonate='chrome') as session: # ChromeのTLS fingerprintの最新バージョンを使用 page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # または一回限りのリクエストを使用 page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +高度なステルスモード +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# 高度なステルスモード(完了するまでブラウザを開いたままにする) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # 完了するまでブラウザを開いたままにする page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() -# または一回限りのリクエストスタイルを使用、このリクエストのためにブラウザを開き、完了後に閉じる +# または一回限りのリクエストスタイル、このリクエストのためにブラウザを開き、完了後に閉じる page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# 完全なブラウザ自動化(完了するまでブラウザを開いたままにする) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +完全なブラウザ自動化 +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# または一回限りのリクエストスタイルを使用 -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # 完了するまでブラウザを開いたままにする + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # お好みであればXPathセレクタを使用 + +# または一回限りのリクエストスタイル、このリクエストのためにブラウザを開き、完了後に閉じる +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### 要素の選択 +### Spider +並行リクエスト、複数のSessionタイプ、Pause & Resumeを備えた本格的なクローラーを構築: ```python -# CSSセレクタ -page.css('a::text') # テキストを抽出 -page.css('a::attr(href)') # 属性を抽出 -page.css('a', recursive=False) # 直接の要素のみ -page.css('a', auto_save=True) # 要素の位置を自動保存 +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# 柔軟な検索 -page.find_by_text('Python', first_match=True) # テキストで検索 -page.find_by_regex(r'\d{4}') # 正規表現パターンで検索 -page.find('div', {'class': 'container'}) # 属性で検索 + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# ナビゲーション -element.parent # 親要素を取得 -element.next_sibling # 次の兄弟を取得 -element.children # 子要素を取得 + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# 類似要素 -similar = page.get_similar(element) # 類似要素を見つける - -# 適応型スクレイピング -saved_elements = page.css('.product', auto_save=True) -# 後でウェブサイトが変更されたとき: -page.css('.product', adaptive=True) # 保存された位置を使用して要素を見つける +result = QuotesSpider().start() +print(f"{len(result.items)}件の引用をスクレイプしました") +result.items.to_json("quotes.json") ``` - -### セッションの使用 +単一のSpiderで複数のSessionタイプを使用: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# 同期セッション -with FetcherSession() as session: - # Cookieは自動的に維持されます - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # 必要に応じてブラウザのフィンガープリントを切り替え +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # 保護されたページはステルスSessionを通してルーティング + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # 明示的なcallback +``` +Checkpointを使用して長時間のクロールをPause & Resume: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +Ctrl+Cを押すと正常に一時停止し、進捗は自動的に保存されます。後でSpiderを再度起動する際に同じ`crawldir`を渡すと、中断したところから再開します。 + +### 高度なパースとナビゲーション +```python +from scrapling.fetchers import Fetcher + +# 豊富な要素選択とナビゲーション +page = Fetcher.get('https://quotes.toscrape.com/') + +# 複数の選択メソッドで引用を取得 +quotes = page.css('.quote') # CSSセレクタ +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # BeautifulSoupスタイル +# 以下と同じ +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # など... +# テキスト内容で要素を検索 +quotes = page.find_by_text('quote', tag='div') + +# 高度なナビゲーション +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # チェーンセレクタ +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# 要素の関連性と類似性 +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +ウェブサイトを取得せずにパーサーをすぐに使用することもできます: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +まったく同じ方法で動作します! + +### 非同期Session管理の例 +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession`はコンテキストアウェアで、同期/非同期両方のパターンで動作可能 + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') -# 非同期セッションの使用 +# 非同期Sessionの使用 async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - + print(session.get_pool_stats()) # オプション - ブラウザタブプールのステータス(ビジー/フリー/エラー) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) ``` -## CLIとインタラクティブシェル +## CLIとインタラクティブShell -Scrapling v0.3には強力なコマンドラインインターフェースが含まれています: +Scraplingには強力なコマンドラインインターフェースが含まれています: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) -インタラクティブウェブスクレイピングシェルを起動 +インタラクティブWeb Scraping Shellを起動 ```bash scrapling shell ``` -プログラミングせずに直接ページをファイルに抽出(デフォルトで`body`タグ内のコンテンツを抽出)。出力ファイルが`.txt`で終わる場合、ターゲットのテキストコンテンツが抽出されます。`.md`で終わる場合、HTMLコンテンツのMarkdown表現になります;`.html`で終わる場合、HTMLコンテンツそのものになります。 +プログラミングせずに直接ページをファイルに抽出(デフォルトで`body`タグ内のコンテンツを抽出)。出力ファイルが`.txt`で終わる場合、ターゲットのテキストコンテンツが抽出されます。`.md`で終わる場合、HTMLコンテンツのMarkdown表現になります。`.html`で終わる場合、HTMLコンテンツそのものになります。 ```bash scrapling extract get 'https://example.com' content.md scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # CSSセレクタ'#fromSkipToProducts'に一致するすべての要素 @@ -231,34 +306,34 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> MCPサーバーやインタラクティブウェブスクレイピングシェルなど、他にも多くの追加機能がありますが、このページは簡潔に保ちたいと思います。完全なドキュメントは[こちら](https://scrapling.readthedocs.io/en/latest/)をご覧ください +> MCPサーバーやインタラクティブWeb Scraping Shellなど、他にも多くの追加機能がありますが、このページは簡潔に保ちたいと思います。完全なドキュメントは[こちら](https://scrapling.readthedocs.io/en/latest/)をご覧ください ## パフォーマンスベンチマーク -Scraplingは強力であるだけでなく、驚くほど高速で、バージョン0.3以降のアップデートはすべての操作で優れたパフォーマンス向上を実現しています。以下のベンチマークは、Scraplingのパーサーを他の人気のあるライブラリと比較しています。 +Scraplingは強力であるだけでなく、超高速です。以下のベンチマークは、Scraplingのパーサーを他の人気ライブラリの最新バージョンと比較しています。 ### テキスト抽出速度テスト(5000個のネストされた要素) -| # | ライブラリ | 時間(ms) | vs Scrapling | -|---|:-----------------:|:-------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| # | ライブラリ | 時間(ms) | vs Scrapling | +|---|:-----------------:|:---------:|:------------:| +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### 要素類似性とテキスト検索のパフォーマンス Scraplingの適応型要素検索機能は代替手段を大幅に上回ります: -| ライブラリ | 時間(ms) | vs Scrapling | -|-------------|:------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| ライブラリ | 時間(ms) | vs Scrapling | +|-------------|:---------:|:------------:| +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > すべてのベンチマークは100回以上の実行の平均を表します。方法論については[benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py)を参照してください。 @@ -271,25 +346,25 @@ ScraplingにはPython 3.10以上が必要です: pip install scrapling ``` -v0.3.2以降、このインストールにはパーサーエンジンとその依存関係のみが含まれており、フェッチャーやコマンドライン依存関係は含まれていません。 +このインストールにはパーサーエンジンとその依存関係のみが含まれており、Fetcherやコマンドライン依存関係は含まれていません。 ### オプションの依存関係 -1. 以下の追加機能、フェッチャー、またはそれらのクラスのいずれかを使用する場合は、フェッチャーの依存関係とブラウザの依存関係を次のようにインストールする必要があります: +1. 以下の追加機能、Fetcher、またはそれらのクラスのいずれかを使用する場合は、Fetcherの依存関係とブラウザの依存関係を次のようにインストールする必要があります: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - これにより、すべてのブラウザ、およびそれらのシステム依存関係とフィンガープリント操作依存関係がダウンロードされます。 + これにより、すべてのブラウザ、およびそれらのシステム依存関係とfingerprint操作依存関係がダウンロードされます。 2. 追加機能: - MCPサーバー機能をインストール: ```bash pip install "scrapling[ai]" ``` - - シェル機能(ウェブスクレイピングシェルと`extract`コマンド)をインストール: + - Shell機能(Web Scraping Shellと`extract`コマンド)をインストール: ```bash pip install "scrapling[shell]" ``` @@ -328,12 +403,5 @@ docker pull ghcr.io/d4vinci/scrapling:latest このプロジェクトには次から適応されたコードが含まれています: - Parsel(BSDライセンス)— [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py)サブモジュールに使用 -## 感謝と参考文献 - -- [Daijro](https://github.com/daijro)の[BrowserForge](https://github.com/daijro/browserforge)と[Camoufox](https://github.com/daijro/camoufox)における素晴らしい仕事 -- [Vinyzu](https://github.com/Vinyzu)の[Botright](https://github.com/Vinyzu/Botright)と[PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright)における素晴らしい仕事 -- ブラウザ検出回避技術を提供する[brotector](https://github.com/kaliiiiiiiiii/brotector) -- フィンガープリント研究を提供する[fakebrowser](https://github.com/kkoooqq/fakebrowser)と[BotBrowser](https://github.com/botswin/BotBrowser) - --- -
Karim Shoairによって❤️でデザインおよび作成されました。

\ No newline at end of file +
Karim Shoairによって❤️でデザインおよび作成されました。

diff --git a/docs/README_RU.md b/docs/README_RU.md index 12f0492..04483bf 100644 --- a/docs/README_RU.md +++ b/docs/README_RU.md @@ -6,8 +6,9 @@
- Web Scraping have never been easier! + Effortless Web Scraping for the Modern Web +

Tests @@ -28,46 +29,47 @@

- - Методы выбора - - · - - Выбор фетчера - - · - - CLI - - · - - Режим MCP - - · - - Миграция с Beautifulsoup - + Методы выбора + · + Выбор Fetcher + · + CLI + · + Режим MCP + · + Миграция с Beautifulsoup

-**Прекратите бороться с анти-ботовыми системами. Прекратите переписывать селекторы после каждого обновления сайта.** +Scrapling — это адаптивный фреймворк для Web Scraping, который берёт на себя всё: от одного запроса до полномасштабного обхода сайтов. -Scrapling - это не просто очередная библиотека для веб-скрапинга. Это первая **адаптивная** библиотека для скрапинга, которая учится на изменениях сайтов и развивается вместе с ними. В то время как другие библиотеки ломаются, когда сайты обновляют свою структуру, Scrapling автоматически перемещает ваши элементы и поддерживает работу ваших скраперов. +Его парсер учится на изменениях сайтов и автоматически перемещает ваши элементы при обновлении страниц. Его Fetcher'ы обходят анти-бот системы вроде Cloudflare Turnstile прямо из коробки. А его Spider-фреймворк позволяет масштабироваться до параллельных, многосессионных обходов с Pause & Resume и автоматической ротацией Proxy — и всё это в нескольких строках Python. Одна библиотека, без компромиссов. -Созданный для современного веба, Scrapling имеет **собственный быстрый движок парсинга** и фетчеры для решения всех задач веб-скрапинга, с которыми вы сталкиваетесь или столкнетесь. Созданный веб-скраперами для веб-скраперов и обычных пользователей, здесь есть что-то для каждого. +Молниеносно быстрые обходы с отслеживанием статистики в реальном времени и Streaming. Создано веб-скраперами для веб-скраперов и обычных пользователей — здесь есть что-то для каждого. ```python ->> from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher ->> StealthyFetcher.adaptive = True -# Получайте исходный код сайтов незаметно! ->> page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) ->> print(page.status) -200 ->> products = page.css('.product', auto_save=True) # Скрапьте данные, которые переживут изменения дизайна сайта! ->> # Позже, если структура сайта изменится, передайте `adaptive=True` ->> products = page.css('.product', adaptive=True) # и Scrapling все равно их найдет! +from scrapling.fetchers import Fetcher, AsyncFetcher, StealthyFetcher, DynamicFetcher +StealthyFetcher.adaptive = True +page = StealthyFetcher.fetch('https://example.com', headless=True, network_idle=True) # Загрузите сайт незаметно! +products = page.css('.product', auto_save=True) # Скрапьте данные, которые переживут изменения дизайна сайта! +products = page.css('.product', adaptive=True) # Позже, если структура сайта изменится, передайте `adaptive=True`, чтобы найти их! +``` +Или масштабируйте до полного обхода +```python +from scrapling.spiders import Spider, Response + +class MySpider(Spider): + name = "demo" + start_urls = ["https://example.com/"] + + async def parse(self, response: Response): + for item in response.css('.product'): + yield {"title": item.css('h2::text').get()} + +MySpider().start() ``` -# Спонсоры + +# Спонсоры @@ -91,138 +93,211 @@ Scrapling - это не просто очередная библиотека д ## Ключевые особенности -### Продвинутая загрузка сайтов с поддержкой сессий -- **HTTP-запросы**: Быстрые и скрытные HTTP-запросы с классом `Fetcher`. Может имитировать TLS-отпечаток браузера, заголовки и использовать HTTP3. +### Spider'ы — полноценный фреймворк для обхода сайтов +- 🕷️ **Scrapy-подобный Spider API**: Определяйте Spider'ов с `start_urls`, async `parse` callback'ами и объектами `Request`/`Response`. +- ⚡ **Параллельный обход**: Настраиваемые лимиты параллелизма, ограничение скорости по домену и задержки загрузки. +- 🔄 **Поддержка нескольких сессий**: Единый интерфейс для HTTP-запросов и скрытных headless-браузеров в одном Spider — маршрутизируйте запросы к разным сессиям по ID. +- 💾 **Pause & Resume**: Persistence обхода на основе Checkpoint'ов. Нажмите Ctrl+C для мягкой остановки; перезапустите, чтобы продолжить с того места, где вы остановились. +- 📡 **Режим Streaming**: Стримьте извлечённые элементы по мере их поступления через `async for item in spider.stream()` со статистикой в реальном времени — идеально для UI, конвейеров и длительных обходов. +- 🛡️ **Обнаружение заблокированных запросов**: Автоматическое обнаружение и повторная отправка заблокированных запросов с настраиваемой логикой. +- 📦 **Встроенный экспорт**: Экспортируйте результаты через хуки и собственный конвейер или встроенный JSON/JSONL с `result.items.to_json()` / `result.items.to_jsonl()` соответственно. + +### Продвинутая загрузка сайтов с поддержкой Session +- **HTTP-запросы**: Быстрые и скрытные HTTP-запросы с классом `Fetcher`. Может имитировать TLS fingerprint браузера, заголовки и использовать HTTP/3. - **Динамическая загрузка**: Загрузка динамических сайтов с полной автоматизацией браузера через класс `DynamicFetcher`, поддерживающий Chromium от Playwright и Google Chrome. -- **Обход анти-ботов**: Расширенные возможности скрытности с `StealthyFetcher` и подмену отпечатков. Может легко обойти все типы Turnstile/Interstitial от Cloudflare с помощью автоматизации. +- **Обход анти-ботов**: Расширенные возможности скрытности с `StealthyFetcher` и подмену fingerprint'ов. Может легко обойти все типы Cloudflare Turnstile/Interstitial с помощью автоматизации. - **Управление сессиями**: Поддержка постоянных сессий с классами `FetcherSession`, `StealthySession` и `DynamicSession` для управления cookie и состоянием между запросами. -- **Поддержка асинхронности**: Полная асинхронная поддержка во всех фетчерах и выделенных асинхронных классах сессий. +- **Ротация Proxy**: Встроенный `ProxyRotator` с round-robin или пользовательскими стратегиями для всех типов сессий, а также переопределение Proxy для каждого запроса. +- **Блокировка доменов**: Блокируйте запросы к определённым доменам (и их поддоменам) в браузерных Fetcher'ах. +- **Поддержка async**: Полная async-поддержка во всех Fetcher'ах и выделенных async-классах сессий. ### Адаптивный скрапинг и интеграция с ИИ - 🔄 **Умное отслеживание элементов**: Перемещайте элементы после изменений сайта с помощью интеллектуальных алгоритмов подобия. - 🎯 **Умный гибкий выбор**: CSS-селекторы, XPath-селекторы, поиск на основе фильтров, текстовый поиск, поиск по регулярным выражениям и многое другое. -- 🔍 **Поиск похожих элементов**: Автоматически находите элементы, похожие на найденные элементы. -- 🤖 **MCP-сервер для использования с ИИ**: Встроенный MCP-сервер для веб-скрапинга с помощью ИИ и извлечения данных. MCP-сервер обладает мощными, пользовательскими возможностями, которые используют Scrapling для извлечения целевого контента перед передачей его ИИ (Claude/Cursor/и т.д.), тем самым ускоряя операции и снижая затраты за счет минимизации использования токенов. ([демо-видео](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) +- 🔍 **Поиск похожих элементов**: Автоматически находите элементы, похожие на найденные. +- 🤖 **MCP-сервер для использования с ИИ**: Встроенный MCP-сервер для Web Scraping с помощью ИИ и извлечения данных. MCP-сервер обладает мощными пользовательскими возможностями, которые используют Scrapling для извлечения целевого контента перед передачей его ИИ (Claude/Cursor/и т.д.), тем самым ускоряя операции и снижая затраты за счёт минимизации использования токенов. ([демо-видео](https://www.youtube.com/watch?v=qyFk3ZNwOxE)) ### Высокопроизводительная и проверенная в боях архитектура -- 🚀 **Молниеносно быстро**: Оптимизированная производительность превосходит большинство библиотек скрапинга Python. +- 🚀 **Молниеносная скорость**: Оптимизированная производительность, превосходящая большинство Python-библиотек для скрапинга. - 🔋 **Эффективное использование памяти**: Оптимизированные структуры данных и ленивая загрузка для минимального потребления памяти. -- ⚡ **Быстрая сериализация JSON**: В 10 раз быстрее, чем стандартная библиотека. +- ⚡ **Быстрая сериализация JSON**: В 10 раз быстрее стандартной библиотеки. - 🏗️ **Проверено в боях**: Scrapling имеет не только 92% покрытия тестами и полное покрытие type hints, но и ежедневно использовался сотнями веб-скраперов в течение последнего года. ### Удобный для разработчиков/веб-скраперов опыт -- 🎯 **Интерактивная оболочка веб-скрапинга**: Опциональная встроенная оболочка IPython с интеграцией Scrapling, ярлыками и новыми инструментами для ускорения разработки скриптов веб-скрапинга, такими как преобразование curl-запросов в Scrapling-запросы и просмотр результатов запросов в вашем браузере. +- 🎯 **Интерактивная Web Scraping Shell**: Опциональная встроенная IPython-оболочка с интеграцией Scrapling, ярлыками и новыми инструментами для ускорения разработки скриптов Web Scraping, такими как преобразование curl-запросов в запросы Scrapling и просмотр результатов запросов в браузере. - 🚀 **Используйте прямо из терминала**: При желании вы можете использовать Scrapling для скрапинга URL без написания ни одной строки кода! - 🛠️ **Богатый API навигации**: Расширенный обход DOM с методами навигации по родителям, братьям и детям. - 🧬 **Улучшенная обработка текста**: Встроенные регулярные выражения, методы очистки и оптимизированные операции со строками. -- 📝 **Автоматическая генерация селекторов**: Генерация надежных CSS/XPath селекторов для любого элемента. +- 📝 **Автоматическая генерация селекторов**: Генерация надёжных CSS/XPath-селекторов для любого элемента. - 🔌 **Знакомый API**: Похож на Scrapy/BeautifulSoup с теми же псевдоэлементами, используемыми в Scrapy/Parsel. -- 📘 **Полное покрытие типами**: Полные подсказки типов для отличной поддержки IDE и автодополнения кода. -- 🔋 **Готовый Docker-образ**: С каждым релизом автоматически создается и отправляется Docker-образ, содержащий все браузеры. +- 📘 **Полное покрытие типами**: Полные type hints для отличной поддержки IDE и автодополнения кода. Вся кодовая база автоматически проверяется **PyRight** и **MyPy** при каждом изменении. +- 🔋 **Готовый Docker-образ**: С каждым релизом автоматически создаётся и публикуется Docker-образ, содержащий все браузеры. ## Начало работы -### Базовое использование -```python -from scrapling.fetchers import Fetcher, StealthyFetcher, DynamicFetcher -from scrapling.fetchers import FetcherSession, StealthySession, DynamicSession +Давайте кратко покажем, на что способен Scrapling, без глубокого погружения. -# HTTP-запросы с поддержкой сессий -with FetcherSession(impersonate='chrome') as session: # Используйте последнюю версию TLS-отпечатка Chrome +### Базовое использование +HTTP-запросы с поддержкой Session +```python +from scrapling.fetchers import Fetcher, FetcherSession + +with FetcherSession(impersonate='chrome') as session: # Используйте последнюю версию TLS fingerprint Chrome page = session.get('https://quotes.toscrape.com/', stealthy_headers=True) - quotes = page.css('.quote .text::text') + quotes = page.css('.quote .text::text').getall() # Или используйте одноразовые запросы page = Fetcher.get('https://quotes.toscrape.com/') -quotes = page.css('.quote .text::text') +quotes = page.css('.quote .text::text').getall() +``` +Расширенный режим скрытности +```python +from scrapling.fetchers import StealthyFetcher, StealthySession -# Расширенный режим скрытности (Держите браузер открытым до завершения) -with StealthySession(headless=True, solve_cloudflare=True) as session: +with StealthySession(headless=True, solve_cloudflare=True) as session: # Держите браузер открытым, пока не закончите page = session.fetch('https://nopecha.com/demo/cloudflare', google_search=False) - data = page.css('#padded_content a') + data = page.css('#padded_content a').getall() -# Или используйте стиль одноразового запроса, открывает браузер для этого запроса, затем закрывает его после завершения +# Или используйте стиль одноразового запроса — открывает браузер для этого запроса, затем закрывает его после завершения page = StealthyFetcher.fetch('https://nopecha.com/demo/cloudflare') -data = page.css('#padded_content a') - -# Полная автоматизация браузера (Держите браузер открытым до завершения) -with DynamicSession(headless=True) as session: - page = session.fetch('https://quotes.toscrape.com/', network_idle=True) - quotes = page.css('.quote .text::text') +data = page.css('#padded_content a').getall() +``` +Полная автоматизация браузера +```python +from scrapling.fetchers import DynamicFetcher, DynamicSession -# Или используйте стиль одноразового запроса -page = DynamicFetcher.fetch('https://quotes.toscrape.com/', network_idle=True) -quotes = page.css('.quote .text::text') +with DynamicSession(headless=True, disable_resources=False, network_idle=True) as session: # Держите браузер открытым, пока не закончите + page = session.fetch('https://quotes.toscrape.com/', load_dom=False) + data = page.xpath('//span[@class="text"]/text()').getall() # XPath-селектор, если вы предпочитаете его + +# Или используйте стиль одноразового запроса — открывает браузер для этого запроса, затем закрывает его после завершения +page = DynamicFetcher.fetch('https://quotes.toscrape.com/') +data = page.css('.quote .text::text').getall() ``` -### Выбор элементов +### Spider'ы +Создавайте полноценные обходчики с параллельными запросами, несколькими типами сессий и Pause & Resume: ```python -# CSS-селекторы -page.css('a::text') # Извлечь текст -page.css('a::attr(href)') # Извлечь атрибуты -page.css('a', recursive=False) # Только прямые элементы -page.css('a', auto_save=True) # Автоматически сохранять позиции элементов +from scrapling.spiders import Spider, Request, Response -# XPath -page.xpath('//a/text()') +class QuotesSpider(Spider): + name = "quotes" + start_urls = ["https://quotes.toscrape.com/"] + concurrent_requests = 10 -# Гибкий поиск -page.find_by_text('Python', first_match=True) # Найти по тексту -page.find_by_regex(r'\d{4}') # Найти по паттерну regex -page.find('div', {'class': 'container'}) # Найти по атрибутам + async def parse(self, response: Response): + for quote in response.css('.quote'): + yield { + "text": quote.css('.text::text').get(), + "author": quote.css('.author::text').get(), + } -# Навигация -element.parent # Получить родительский элемент -element.next_sibling # Получить следующего брата -element.children # Получить дочерние элементы + next_page = response.css('.next a') + if next_page: + yield response.follow(next_page[0].attrib['href']) -# Похожие элементы -similar = page.get_similar(element) # Найти похожие элементы - -# Адаптивный скрапинг -saved_elements = page.css('.product', auto_save=True) -# Позже, когда сайт изменится: -page.css('.product', adaptive=True) # Найти элементы используя сохраненные позиции +result = QuotesSpider().start() +print(f"Извлечено {len(result.items)} цитат") +result.items.to_json("quotes.json") ``` - -### Использование сессий +Используйте несколько типов сессий в одном Spider: ```python -from scrapling.fetchers import FetcherSession, AsyncFetcherSession +from scrapling.spiders import Spider, Request, Response +from scrapling.fetchers import FetcherSession, AsyncStealthySession -# Синхронная сессия -with FetcherSession() as session: - # Cookie автоматически сохраняются - page1 = session.get('https://quotes.toscrape.com/login') - page2 = session.post('https://quotes.toscrape.com/login', data={'username': 'admin', 'password': 'admin'}) - - # При необходимости переключите отпечаток браузера +class MultiSessionSpider(Spider): + name = "multi" + start_urls = ["https://example.com/"] + + def configure_sessions(self, manager): + manager.add("fast", FetcherSession(impersonate="chrome")) + manager.add("stealth", AsyncStealthySession(headless=True), lazy=True) + + async def parse(self, response: Response): + for link in response.css('a::attr(href)').getall(): + # Направляйте защищённые страницы через stealth-сессию + if "protected" in link: + yield Request(link, sid="stealth") + else: + yield Request(link, sid="fast", callback=self.parse) # явный callback +``` +Приостанавливайте и возобновляйте длительные обходы с помощью Checkpoint'ов, запуская Spider следующим образом: +```python +QuotesSpider(crawldir="./crawl_data").start() +``` +Нажмите Ctrl+C для мягкой остановки — прогресс сохраняется автоматически. Позже, когда вы снова запустите Spider, передайте тот же `crawldir`, и он продолжит с того места, где остановился. + +### Продвинутый парсинг и навигация +```python +from scrapling.fetchers import Fetcher + +# Богатый выбор элементов и навигация +page = Fetcher.get('https://quotes.toscrape.com/') + +# Получение цитат различными методами выбора +quotes = page.css('.quote') # CSS-селектор +quotes = page.xpath('//div[@class="quote"]') # XPath +quotes = page.find_all('div', {'class': 'quote'}) # В стиле BeautifulSoup +# То же самое, что +quotes = page.find_all('div', class_='quote') +quotes = page.find_all(['div'], class_='quote') +quotes = page.find_all(class_='quote') # и так далее... +# Найти элемент по текстовому содержимому +quotes = page.find_by_text('quote', tag='div') + +# Продвинутая навигация +quote_text = page.css('.quote')[0].css('.text::text').get() +quote_text = page.css('.quote').css('.text::text').getall() # Цепочка селекторов +first_quote = page.css('.quote')[0] +author = first_quote.next_sibling.css('.author::text') +parent_container = first_quote.parent + +# Связи элементов и подобие +similar_elements = first_quote.find_similar() +below_elements = first_quote.below_elements() +``` +Вы можете использовать парсер напрямую, если не хотите загружать сайты, как показано ниже: +```python +from scrapling.parser import Selector + +page = Selector("...") +``` +И он работает точно так же! + +### Примеры async Session +```python +import asyncio +from scrapling.fetchers import FetcherSession, AsyncStealthySession, AsyncDynamicSession + +async with FetcherSession(http3=True) as session: # `FetcherSession` контекстно-осведомлён и может работать как в sync, так и в async-режимах + page1 = session.get('https://quotes.toscrape.com/') page2 = session.get('https://quotes.toscrape.com/', impersonate='firefox135') -# Использование асинхронной сессии +# Использование async-сессии async with AsyncStealthySession(max_pages=2) as session: tasks = [] urls = ['https://example.com/page1', 'https://example.com/page2'] - + for url in urls: task = session.fetch(url) tasks.append(task) - - print(session.get_pool_stats()) # Опционально - Статус пула вкладок браузера (занят/свободен/ошибка) + + print(session.get_pool_stats()) # Опционально — статус пула вкладок браузера (занят/свободен/ошибка) results = await asyncio.gather(*tasks) print(session.get_pool_stats()) ``` -## CLI и интерактивная оболочка +## CLI и интерактивная Shell -Scrapling v0.3 включает мощный интерфейс командной строки: +Scrapling включает мощный интерфейс командной строки: [![asciicast](https://asciinema.org/a/736339.svg)](https://asciinema.org/a/736339) -Запустить интерактивную оболочку веб-скрапинга +Запустить интерактивную Web Scraping Shell ```bash scrapling shell ``` -Извлечь страницы в файл напрямую без программирования (Извлекает содержимое внутри тега `body` по умолчанию). Если выходной файл заканчивается на `.txt`, то будет извлечено текстовое содержимое цели. Если заканчивается на `.md`, это будет Markdown-представление HTML-содержимого; если заканчивается на `.html`, это будет само HTML-содержимое. +Извлечь страницы в файл напрямую без программирования (по умолчанию извлекает содержимое внутри тега `body`). Если выходной файл заканчивается на `.txt`, будет извлечено текстовое содержимое цели. Если заканчивается на `.md`, это будет Markdown-представление HTML-содержимого; если заканчивается на `.html`, это будет само HTML-содержимое. ```bash scrapling extract get 'https://example.com' content.md scrapling extract get 'https://example.com' content.txt --css-selector '#fromSkipToProducts' --impersonate 'chrome' # Все элементы, соответствующие CSS-селектору '#fromSkipToProducts' @@ -231,24 +306,24 @@ scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' captchas. ``` > [!NOTE] -> Есть много дополнительных функций, но мы хотим сохранить эту страницу краткой, например, MCP-сервер и интерактивная оболочка веб-скрапинга. Ознакомьтесь с полной документацией [здесь](https://scrapling.readthedocs.io/en/latest/) +> Есть множество дополнительных возможностей, но мы хотим сохранить эту страницу краткой, включая MCP-сервер и интерактивную Web Scraping Shell. Ознакомьтесь с полной документацией [здесь](https://scrapling.readthedocs.io/en/latest/) ## Тесты производительности -Scrapling не только мощный - он также невероятно быстрый, и обновления с версии 0.3 обеспечили исключительные улучшения производительности во всех операциях. Следующие тесты производительности сравнивают парсер Scrapling с другими популярными библиотеками. +Scrapling не только мощный — он ещё и невероятно быстрый. Следующие тесты производительности сравнивают парсер Scrapling с последними версиями других популярных библиотек. ### Тест скорости извлечения текста (5000 вложенных элементов) -| # | Библиотека | Время (мс) | vs Scrapling | +| # | Библиотека | Время (мс) | vs Scrapling | |---|:-----------------:|:----------:|:------------:| -| 1 | Scrapling | 1.99 | 1.0x | -| 2 | Parsel/Scrapy | 2.01 | 1.01x | -| 3 | Raw Lxml | 2.5 | 1.256x | -| 4 | PyQuery | 22.93 | ~11.5x | -| 5 | Selectolax | 80.57 | ~40.5x | -| 6 | BS4 with Lxml | 1541.37 | ~774.6x | -| 7 | MechanicalSoup | 1547.35 | ~777.6x | -| 8 | BS4 with html5lib | 3410.58 | ~1713.9x | +| 1 | Scrapling | 2.02 | 1.0x | +| 2 | Parsel/Scrapy | 2.04 | 1.01 | +| 3 | Raw Lxml | 2.54 | 1.257 | +| 4 | PyQuery | 24.17 | ~12x | +| 5 | Selectolax | 82.63 | ~41x | +| 6 | MechanicalSoup | 1549.71 | ~767.1x | +| 7 | BS4 with Lxml | 1584.31 | ~784.3x | +| 8 | BS4 with html5lib | 3391.91 | ~1679.1x | ### Производительность подобия элементов и текстового поиска @@ -257,8 +332,8 @@ Scrapling не только мощный - он также невероятно | Библиотека | Время (мс) | vs Scrapling | |-------------|:----------:|:------------:| -| Scrapling | 2.46 | 1.0x | -| AutoScraper | 13.3 | 5.407x | +| Scrapling | 2.39 | 1.0x | +| AutoScraper | 12.45 | 5.209x | > Все тесты производительности представляют собой средние значения более 100 запусков. См. [benchmarks.py](https://github.com/D4Vinci/Scrapling/blob/main/benchmarks.py) для методологии. @@ -271,33 +346,33 @@ Scrapling требует Python 3.10 или выше: pip install scrapling ``` -Начиная с v0.3.2, эта установка включает только движок парсера и его зависимости, без каких-либо фетчеров или зависимостей командной строки. +Эта установка включает только движок парсера и его зависимости, без каких-либо Fetcher'ов или зависимостей командной строки. ### Опциональные зависимости -1. Если вы собираетесь использовать какие-либо из дополнительных функций ниже, фетчеры или их классы, вам необходимо установить зависимости фетчеров и их зависимости браузера следующим образом: +1. Если вы собираетесь использовать какие-либо из дополнительных возможностей ниже, Fetcher'ы или их классы, вам необходимо установить зависимости Fetcher'ов и браузеров следующим образом: ```bash pip install "scrapling[fetchers]" - + scrapling install ``` - Это загрузит все браузеры вместе с их системными зависимостями и зависимостями манипуляции отпечатками. + Это загрузит все браузеры вместе с их системными зависимостями и зависимостями для манипуляции fingerprint'ами. -2. Дополнительные функции: +2. Дополнительные возможности: - Установить функцию MCP-сервера: ```bash pip install "scrapling[ai]" ``` - - Установить функции оболочки (оболочка веб-скрапинга и команда `extract`): + - Установить функции Shell (Web Scraping Shell и команда `extract`): ```bash pip install "scrapling[shell]" ``` - - Установить все: + - Установить всё: ```bash pip install "scrapling[all]" ``` - Помните, что вам нужно установить зависимости браузера с помощью `scrapling install` после любого из этих дополнений (если вы еще этого не сделали) + Помните, что вам нужно установить зависимости браузеров с помощью `scrapling install` после любого из этих дополнений (если вы ещё этого не сделали) ### Docker Вы также можете установить Docker-образ со всеми дополнениями и браузерами с помощью следующей команды из DockerHub: @@ -308,11 +383,11 @@ docker pull pyd4vinci/scrapling ```bash docker pull ghcr.io/d4vinci/scrapling:latest ``` -Этот образ автоматически создается и отправляется с использованием GitHub Actions и основной ветки репозитория. +Этот образ автоматически создаётся и публикуется с помощью GitHub Actions и основной ветки репозитория. -## Вклад +## Участие в разработке -Мы приветствуем вклад! Пожалуйста, прочитайте наши [руководства по внесению вклада](https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md) перед началом работы. +Мы приветствуем участие! Пожалуйста, прочитайте наши [руководства по участию в разработке](https://github.com/D4Vinci/Scrapling/blob/main/CONTRIBUTING.md) перед началом работы. ## Отказ от ответственности @@ -328,12 +403,5 @@ docker pull ghcr.io/d4vinci/scrapling:latest Этот проект включает код, адаптированный из: - Parsel (лицензия BSD) — Используется для подмодуля [translator](https://github.com/D4Vinci/Scrapling/blob/main/scrapling/core/translator.py) -## Благодарности и ссылки - -- Блестящая работа [Daijro](https://github.com/daijro) над [BrowserForge](https://github.com/daijro/browserforge) и [Camoufox](https://github.com/daijro/camoufox) -- Блестящая работа [Vinyzu](https://github.com/Vinyzu) над [Botright](https://github.com/Vinyzu/Botright) и [PatchRight](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright) -- [brotector](https://github.com/kaliiiiiiiiii/brotector) за техники обхода обнаружения браузера -- [fakebrowser](https://github.com/kkoooqq/fakebrowser) и [BotBrowser](https://github.com/botswin/BotBrowser) за исследование отпечатков - --- -
Разработано и создано с ❤️ Карим Шоаир.

\ No newline at end of file +
Разработано и создано с ❤️ Карим Шоаир.