Spaces:
Sleeping
Sleeping
Download Backend/app/scraper_manager.py from orakzai-io/Async_Web_scraper: direct link, hf CLI and curl.
- Browser
- Download file 3.31 kB
-
https://huggingface.co/spaces/orakzai-io/Async_Web_scraper/resolve/main/Backend/app/scraper_manager.py
- Command line
-
hf download hf://spaces/orakzai-io/Async_Web_scraper/Backend/app/scraper_manager.py
-
curl -L -o scraper_manager.py https://huggingface.co/spaces/orakzai-io/Async_Web_scraper/resolve/main/Backend/app/scraper_manager.py
3.31 kB
| from .browser_client import BrowserClient | |
| from .parser import Parser | |
| from .JSONStorage import JSONStorage | |
| from .llm_extractor import LLMExtractor | |
| from .datastore import DataStore | |
| from loguru import logger | |
| class ScraperManager: | |
| def __init__(self): | |
| self.browser_client = BrowserClient() | |
| self.parser = Parser() | |
| self.llm_extractor = LLMExtractor() | |
| self.json_storage = JSONStorage() | |
| self.datastore = DataStore() | |
| self.job_counter = 0 | |
| async def scrape(self, url): | |
| """ | |
| Coordinates the scraping pipeline for a single URL. | |
| Returns the structured data or an error. | |
| """ | |
| self.job_counter += 1 | |
| job_id = self.job_counter | |
| task_log = logger.bind(context="scraper_manager", url=url, job_id=job_id) | |
| # 1) Fetch | |
| try: | |
| html = await self.browser_client.fetch(url) | |
| if not html or len(html.strip()) == 0: | |
| raise ValueError(" Received empty HTML") | |
| task_log.info(f"[1/6] Fetched HTML {len(html)} characters") | |
| except Exception as e: | |
| task_log.exception(f"Worker {job_id} aborted: Failed to fetch HTML") | |
| raise e # Propagation of "Bot Blocked" or "Wrong URL" from browser_client | |
| # 2) Parse | |
| try: | |
| parsed_text = await self.parser.parse(html) | |
| task_log.info(f"[2/6] Extracted {len(parsed_text)} characters of text") | |
| except Exception as e: | |
| task_log.exception(f"Worker {job_id} failed to extract text") | |
| raise Exception(f"Failed to parse text: {e}") | |
| # 3) Save cleaned text | |
| try: | |
| parsed_record = self.datastore.save_parsed_data(parsed_text) | |
| task_log.info("[3/6] Saved cleaned text to DB") | |
| except Exception as e: | |
| task_log.exception("[3/6] Failed to save cleaned text to DB") | |
| raise Exception(f"Database error: {e}") | |
| # 4) LLM Extract | |
| try: | |
| data = await self.llm_extractor.make(parsed_text, url) | |
| task_log.info("[4/6] LLM Extraction completed") | |
| except Exception as e: | |
| task_log.exception("[4/6] Failed to extract structured JSON from LLM") | |
| raise Exception(f"LLM extraction error: {e}") | |
| # 5) Save data extracted data to JSONL | |
| try: | |
| await self.json_storage.save_jsonl(data) | |
| task_log.info("[5/6] Saved structured JSON to File: data.jsonl") | |
| except Exception as e: | |
| task_log.exception( | |
| "[5/6] Failed to save structured JSON to File: data.jsonl" | |
| ) | |
| raise Exception(f"File storage error: {e}") | |
| # 6) Save extracted data to DB | |
| try: | |
| self.datastore.save_llm_extraction(parsed_record.id, data, url) | |
| task_log.info("[6/6] Saved structured JSONL to DB") | |
| except Exception as e: | |
| task_log.exception("[6/6] Failed to save structured JSONL to DB") | |
| raise Exception(f"Database extraction save error: {e}") | |
| task_log.success(f"Worker {job_id} has completed all operations successfully") | |
| return data | |
| async def close(self): | |
| await self.browser_client.close() | |