XTOOLS / tools /target.py
1990two's picture
Upload 31 files
0ee2df7 verified
Raw History Blame Contribute Delete
1.48 kB
"""
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'<script type="application/json"[^>]*id="__TGT_DATA__"[^>]*>(.*?)</script>', 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"}