From 418e0d2fcc510cf773328a0ae427a984fb60d51b Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Fri, 10 Jul 2026 08:42:08 +0000 Subject: [PATCH] Block images/CSS/fonts in Playwright to cut ~75% bandwidth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cf.bstatic.com (images + CSS CDN) was consuming 1.5 GB per scrape run. Added route interception to abort image, stylesheet, font, and media resources, plus pure tracking domains. The DOM extraction only reads HTML attributes — no visual resources are needed. Co-Authored-By: Claude Sonnet 4.6 --- .../scraper_backends/playwright_hotel_page.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/backend/services/scraper_backends/playwright_hotel_page.py b/backend/services/scraper_backends/playwright_hotel_page.py index b7ecb4d..6cd649c 100644 --- a/backend/services/scraper_backends/playwright_hotel_page.py +++ b/backend/services/scraper_backends/playwright_hotel_page.py @@ -55,6 +55,39 @@ _VIEWPORTS = [ {'width': 1600, 'height': 900}, ] +# Resource types to abort — we only need the DOM and JS execution. +# Images, stylesheets, and fonts are served from cf.bstatic.com and account +# for ~75% of bandwidth; aborting them saves ~1.5 GB per scrape run. +_BLOCK_RESOURCE_TYPES = {'image', 'stylesheet', 'font', 'media'} + +# Pure tracking/analytics domains with no effect on DOM or JS prices rendering. +_BLOCK_DOMAINS = { + 'cdn.cookielaw.org', + 'geolocation.onetrust.com', + 'graph.facebook.com', + 'platform-lookaside.fbsbx.com', + 'lh3.googleusercontent.com', + 'maps.googleapis.com', + 'web-perf.booking.com', + 'sink.gw.booking.com', + 'otel-gw.booking.com', +} + + +async def _route_handler(route, request): + if request.resource_type in _BLOCK_RESOURCE_TYPES: + await route.abort() + return + try: + host = request.url.split('/')[2].split(':')[0] + except IndexError: + host = '' + if host in _BLOCK_DOMAINS: + await route.abort() + return + await route.continue_() + + # Injected into every new context to mask headless/webdriver signals. _STEALTH_SCRIPT = """ Object.defineProperty(navigator, 'webdriver', {get: () => undefined}); @@ -250,6 +283,7 @@ class PlaywrightHotelPageBackend(ScraperBackend): **self._proxy_kwargs(session_id), ) await self._context.add_init_script(_STEALTH_SCRIPT) + await self._context.route('**/*', _route_handler) self._requests_on_context = 0 logger.debug( f"Opened new browser context ua=…{ua[-30:]} viewport={viewport['width']}x{viewport['height']}"