31 lines
866 B
Python
31 lines
866 B
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import time
|
|
|
|
from scrapling import StealthyFetcher
|
|
|
|
from ..models.request import ScrapeRequest
|
|
from ..models.response import ScrapeResponse
|
|
from .base import BaseScraper
|
|
|
|
|
|
class StealthyScraper(BaseScraper):
|
|
"""Wraps Scrapling's StealthyFetcher — TLS fingerprint impersonation."""
|
|
|
|
async def scrape(self, req: ScrapeRequest) -> ScrapeResponse:
|
|
start = time.perf_counter()
|
|
fetcher = StealthyFetcher(auto_match=False)
|
|
|
|
kwargs: dict = {
|
|
"url": req.url,
|
|
"timeout": req.timeout / 1000,
|
|
}
|
|
if req.headers:
|
|
kwargs["extra_headers"] = req.headers
|
|
if req.proxy:
|
|
kwargs["proxy"] = req.proxy
|
|
|
|
page = await asyncio.to_thread(fetcher.fetch, **kwargs)
|
|
return self._build_response(req, page, "stealth", start)
|