Async_Web_scraper / Backend /app /scraper_manager.py
orakzai-io
V2
d57e0f9
Raw History Blame Contribute Delete
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()