# SPA-Scraping — Kiwi Browser Workarounds für JS-Heavy Sites

Moderne SPAs (Single Page Applications) rendern Content client-seitig. Der Kiwi-Browser `/visit`-Endpunkt mit `wait: "networkidle"` reicht oft nicht, weil die App erst nach Hydration oder Lazy-Load Daten nachlädt.

## Rezepte pro Plattform

### Reddit

**Beste Lösung: Native JSON-API** (kein Browser nötig)
- An beliebige Reddit-URL `.json` anhängen: `https://reddit.com/r/.../comments/xxx.json?tl=de`
- Liefert [post, comments]-Array. Struktur:
  - `data[0]['data']['children'][0]['data']` = Post (title, selftext, author, ups, num_comments)
  - `data[1]['data']['children']` = Top-Level Comments
  - Jeder Comment hat `body`, `author`, `ups`, `replies` (rekursiv verschachtelt)
- `?tl=de` für deutsche Spracheinstellung (kann weggelassen werden)

**Python-Extraktion (als one-liner):**
```python
import json, urllib.request
url = "https://www.reddit.com/r/LocalLLaMA/comments/1sz2y76/ama_with_nous_research_ask_us_anything.json"
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
data = json.loads(urllib.request.urlopen(req).read())
post = data[0]['data']['children'][0]['data']
comments = data[1]['data']['children']
```

### Twitter / X

- X blockiert Headless-Browser hart (TLS-Fingerprint, Bot-Score).
- Alternativen:
  1. **Nitter-Instanzen** (wo verfügbar) — kein Login nötig, statisches HTML.
  2. **Offizielle API** (v2) via `xurl`-Skill.
  3. **RSS-Feeds** für öffentliche Accounts.

### YouTube

- Videos: `yt-dlp` (Skill `youtube-content`) für Transkripte/Metadaten — kein Browser nötig.
- Studio/Upload: Kiwi-Browser mit echten Klicks (`/click`, `/type`), aber Schritt-für-Schritt mit Pausen.

### Allgemeine SPA-Strategien (Fallback-Kette)

1. **Prüfe JSON-API** — Reddit, Instagram (?__a=1, instabil), etc.
2. **`/evaluate` mit `document.body.innerText`** — Nach `/navigate` + `wait: "load"`:
   ```bash
   curl -s -X POST http://127.0.0.1:30000/evaluate \
     -H "Content-Type: application/json" \
     -d '{"url":"https://example.com","script":"document.body.innerText"}'
   ```
3. **Scroll-Trigger + Evaluate** — Manche SPAs laden erst nach Scroll:
   ```bash
   curl -s -X POST http://127.0.0.1:30000/scroll \
     -d '{"url":"https://example.com","direction":"bottom"}'
   # dann evaluate
   ```
4. **Screenshot + OCR** — Wenn Text nicht extrahierbar ist:
   ```bash
   curl -s -X POST http://127.0.0.1:30000/screenshot \
     -d '{"url":"https://example.com","full_page":true}' | jq -r '.screenshot_base64' | base64 -d > page.png
   ```
   Dann OCR via `ocr-and-documents` Skill oder `marker-pdf`.
5. **Headless-Wait erhöhen** — `wait: "load"` statt `"networkidle"` für langsame Hydration.

## Anti-Pattern: Nicht tun

- Nicht versuchen, Reddit/X mit `/visit` + CSS-Selektor zu scrapen — die Struktur ändert sich ständig und ist SSR-unzuverlässig.
- Nicht mehrere `/visit`-Retries ohne Strategiewechsel — das ist verschwendete Zeit.

## Verwandte Skills

- `youtube-content` — YouTube Transkripte/Metadaten ohne Browser
- `xurl` — X/Twitter API via CLI
- `ocr-and-documents` — Screenshot-OCR-Pipeline
