Reduce scraper timeouts and raise default concurrency to 6
Timeouts were set for the old proxy 407 round-trip world (14.5s latency per challenge). Now that credentials are embedded in the proxy URL, pages load in ~7s — the 90s goto timeout was forcing 5+ minutes of wasted wait on Cloudflare-blocked dates before rotating sessions. homepage warmup goto: 90s → 20s page 1 search goto: 90s → 30s (4× normal load time headroom) property-card waits: 30s → 15s (cards appear in <3s on clean pages) Default concurrency 3 → 6: each worker uses its own residential proxy IP so parallelism is safe. ~0.4 GB per Chromium; 6 workers fits in 4 GB LXC. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b47258d47b
commit
ea66025140
2 changed files with 9 additions and 9 deletions
|
|
@ -426,16 +426,16 @@ async def scrape_date(
|
||||||
|
|
||||||
|
|
||||||
def get_scraper_concurrency(db: Session) -> int:
|
def get_scraper_concurrency(db: Session) -> int:
|
||||||
"""Number of parallel scrape workers (config key, default 3). Each worker
|
"""Number of parallel scrape workers (config key, default 6). Each worker
|
||||||
runs its own browser on its own residential proxy IP, so raise this only
|
runs its own browser on its own residential proxy IP (~0.4 GB each), so
|
||||||
with proxy IPs and RAM to spare (~0.4 GB per worker)."""
|
keep this below RAM / 0.4 GB. Requires proxy — serial fallback if off."""
|
||||||
row = db.execute(
|
row = db.execute(
|
||||||
text("SELECT config_value FROM system_config WHERE config_key = 'booking_scraper_concurrency'")
|
text("SELECT config_value FROM system_config WHERE config_key = 'booking_scraper_concurrency'")
|
||||||
).fetchone()
|
).fetchone()
|
||||||
try:
|
try:
|
||||||
return max(1, int(row.config_value)) if row and row.config_value else 3
|
return max(1, int(row.config_value)) if row and row.config_value else 6
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return 3
|
return 6
|
||||||
|
|
||||||
|
|
||||||
def _effective_concurrency(db: Session, n_jobs: int) -> int:
|
def _effective_concurrency(db: Session, n_jobs: int) -> int:
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ class PlaywrightLocalBackend(ScraperBackend):
|
||||||
async def _warm_up(self, page: Page):
|
async def _warm_up(self, page: Page):
|
||||||
"""Visit the homepage first so search requests carry session cookies."""
|
"""Visit the homepage first so search requests carry session cookies."""
|
||||||
try:
|
try:
|
||||||
await page.goto(self.HOMEPAGE, wait_until='domcontentloaded', timeout=90000)
|
await page.goto(self.HOMEPAGE, wait_until='domcontentloaded', timeout=20000)
|
||||||
await asyncio.sleep(random.uniform(1.5, 3.0))
|
await asyncio.sleep(random.uniform(1.5, 3.0))
|
||||||
# Dismiss the cookie-consent dialog if present
|
# Dismiss the cookie-consent dialog if present
|
||||||
for sel in ['#onetrust-accept-btn-handler',
|
for sel in ['#onetrust-accept-btn-handler',
|
||||||
|
|
@ -375,12 +375,12 @@ class PlaywrightLocalBackend(ScraperBackend):
|
||||||
# Wait for property cards - booking.com uses data-testid. Retry once
|
# Wait for property cards - booking.com uses data-testid. Retry once
|
||||||
# with a scroll nudge before giving up: cards can lazy-load late.
|
# with a scroll nudge before giving up: cards can lazy-load late.
|
||||||
try:
|
try:
|
||||||
await page.wait_for_selector('[data-testid="property-card"]', timeout=30000)
|
await page.wait_for_selector('[data-testid="property-card"]', timeout=15000)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"No property cards on first wait, retrying: {e}")
|
logger.warning(f"No property cards on first wait, retrying: {e}")
|
||||||
try:
|
try:
|
||||||
await self._human_like_scroll(page)
|
await self._human_like_scroll(page)
|
||||||
await page.wait_for_selector('[data-testid="property-card"]', timeout=30000)
|
await page.wait_for_selector('[data-testid="property-card"]', timeout=15000)
|
||||||
except Exception as e2:
|
except Exception as e2:
|
||||||
logger.warning(f"No property cards found after retry: {e2}")
|
logger.warning(f"No property cards found after retry: {e2}")
|
||||||
return hotels, rates
|
return hotels, rates
|
||||||
|
|
@ -614,7 +614,7 @@ class PlaywrightLocalBackend(ScraperBackend):
|
||||||
# direct hit to searchresults with no Referer causes
|
# direct hit to searchresults with no Referer causes
|
||||||
# Cloudflare to hold the response body open indefinitely.
|
# Cloudflare to hold the response body open indefinitely.
|
||||||
await page.goto(url, wait_until='domcontentloaded',
|
await page.goto(url, wait_until='domcontentloaded',
|
||||||
timeout=90000, referer=self.HOMEPAGE)
|
timeout=30000, referer=self.HOMEPAGE)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Page load timeout, continuing: {e}")
|
logger.warning(f"Page load timeout, continuing: {e}")
|
||||||
page_loaded = False
|
page_loaded = False
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue