Spaces:
Sleeping
Sleeping
Download ingestion/shared/playwright_helpers.py from shield137/shockmap-api: direct link, hf CLI and curl.
- Browser
- Download file 1.98 kB
-
https://huggingface.co/spaces/shield137/shockmap-api/resolve/main/ingestion/shared/playwright_helpers.py
- Command line
-
hf download hf://spaces/shield137/shockmap-api/ingestion/shared/playwright_helpers.py
-
curl -L -o playwright_helpers.py https://huggingface.co/spaces/shield137/shockmap-api/resolve/main/ingestion/shared/playwright_helpers.py
1.98 kB
| """ | |
| Async helpers for Playwright browser-based scraping. | |
| """ | |
| import asyncio | |
| import logging | |
| from typing import List, Dict, Optional | |
| from playwright.async_api import async_playwright | |
| # Setup Logging | |
| logger = logging.getLogger("ingestion.playwright") | |
| USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" | |
| async def fetch_page_html( | |
| url: str, | |
| wait_for_selector: Optional[str] = None, | |
| timeout_ms: int = 30000 | |
| ) -> str: | |
| """ | |
| Launches a headless browser, navigates to a URL, and returns the full HTML content. | |
| """ | |
| async with async_playwright() as p: | |
| browser = await p.chromium.launch(headless=True) | |
| context = await browser.new_context(user_agent=USER_AGENT) | |
| page = await context.new_page() | |
| try: | |
| logger.info(f"Navigating to {url}...") | |
| await page.goto(url, timeout=timeout_ms) | |
| if wait_for_selector: | |
| await page.wait_for_selector(wait_for_selector, timeout=timeout_ms) | |
| html = await page.content() | |
| return html | |
| except Exception as e: | |
| logger.error(f"Error fetching {url}: {e}") | |
| return "" | |
| finally: | |
| await browser.close() | |
| async def fetch_pages_concurrent( | |
| urls: List[str], | |
| max_concurrency: int = 3, | |
| rate_limit_per_sec: float = 0.5 | |
| ) -> Dict[str, str]: | |
| """ | |
| Fetches multiple pages concurrently with a semaphore and rate limiting. | |
| """ | |
| semaphore = asyncio.Semaphore(max_concurrency) | |
| results = {} | |
| async def _bound_fetch(url: str): | |
| async with semaphore: | |
| html = await fetch_page_html(url) | |
| results[url] = html | |
| # Rate limit wait | |
| await asyncio.sleep(1.0 / rate_limit_per_sec) | |
| tasks = [asyncio.create_task(_bound_fetch(url)) for url in urls] | |
| await asyncio.gather(*tasks) | |
| return results | |