기존 — Python + Playwright
import asyncio, json, hashlib
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
ctx = await browser.new_context(viewport={"width": 1280, "height": 800})
page = await ctx.new_page()
try:
await page.goto(URL, wait_until="networkidle", timeout=30000)
except Exception:
await browser.close()
raise SystemExit("navigation failed")
# selector breaks on every redesign — constant upkeep
cells = await page.query_selector_all("div.product-card span.price")
prices = [(await c.inner_text()).strip() for c in cells]
if not prices: # blocked? selector changed? can't tell
await browser.close()
raise SystemExit("blocked or selector changed")
await page.screenshot(path="out.png", full_page=True)
with open("out.json", "w") as f:
json.dump({"prices": prices, "url": page.url}, f, ensure_ascii=False)
sha = hashlib.sha256(open("out.png", "rb").read()).hexdigest()
print("evidence", sha[:8])
await browser.close()
asyncio.run(main())
ScreenPlay — .play
try:
page.goto(url)
recover NetworkError:
retry(max=3, backoff_ms=500)
if page.wall_check():
stop_before("blocked") # honest fail-closed, stops here
# self-healing selectors survive redesigns
items = page.discover_list({name, price})
capture_evidence("prices") # screenshot + SHA-256 manifest
fs.write_json("out.json", items)