""" Target -- search scraper, parses embedded JSON blob. No auth. """ import re import json import time import httpx HEADERS = {"User-Agent": "Mozilla/5.0"} def run(params: dict) -> dict: keyword = params.get("keyword") if not keyword: raise ValueError("keyword is required") max_results = int(params.get("max_results", 25)) url = f"https://www.target.com/s?searchTerm={keyword}" last_err = None for attempt in range(3): try: resp = httpx.get(url, headers=HEADERS, timeout=20.0) resp.raise_for_status() break except Exception as e: last_err = e time.sleep(1.5 * (attempt + 1)) else: raise ValueError(f"Target request failed after retries: {last_err}") match = re.search(r'', resp.text, re.S) if not match: return {"count": 0, "results": [], "note": "Could not locate embedded product JSON; page structure may have changed"} try: blob = json.loads(match.group(1)) except Exception: return {"count": 0, "results": [], "note": "Failed to parse embedded JSON"} # Target nests this deeply and the path shifts between deployments; # surfacing the raw blob keeps this usable without brittle path-chasing. return {"count": 0, "results": [], "raw_available": True, "note": "Parse __TGT_DATA__ product grid path for this deployment"}