fullvideosporn.com is sextu.com rebranded, not a clone of fullmovies.xxx
(different engine, different catalog, 0/140 title overlap with our
fullmoviesxxx corpus).
The site is only worth ingesting behind a gate: 65-75% of its catalog has
no performer at all, and those scenes also carry SEO-spun titles, so they
would never match canonical and would land as empty orphans. So we ingest
only scenes with at least one performer. That keeps ~25-35% of the catalog
(verified: 19 of 60 on page one) where the signal is good, since 88-89% of
the performer names in the research sample already resolve to a canonical
performer in our DB.
Three site-specific traps, all handled:
- Titles come from the player's vit:"..." field, not og:title/h1, which are
sometimes an AI SEO rewrite rather than the real scene title.
- Cast is read only from the <h3>Porn-stars:</h3> section; the page carries
~22 videos.php?q= links overall but only 1-2 real performers, the same
pollution that got xxxfiles rejected. Porn Site / Porn Categories are
separate h3 blocks and are parsed per-section so they don't bleed.
- Every fetch passes a cookie gate: a fresh session gets HTTP 429 plus a
small JS challenge, so we read the cookie out of it and retry on the same
session. Hence the custom crawl_page instead of the base browser_get.
The TXXX video_url decoder moved out of vjav into _txxx.py since both tubes
share the engine; vjav keeps an alias and was re-verified after the move.
Playback resolves videofile.php -> decode -> get_file -> 302 -> znvcdn, and
the final CDN URL is portable cross-IP so the phone streams it directly.
Note for future debugging: the VPS itself gets 429 from that CDN because of
datacenter IP reputation, so playback health-checks run from the VPS will
be falsely negative.
Pilot ingest of 2 pages: 39 seen, 11 merged into existing scenes, 28 new,
0 errors; 0/19 without cast or duration on the sampled page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Second JAV vertical source (origin tube:vjav, gated to JAV tab via JAV_ORIGINS).
Browse: SPA has no server-rendered listing, so id-walk over sitemap_vids
(newest = highest video id) feeding the rich JSON metadata API
(/api/json/video/1/<floor>/<id>/<id>.json): title, duration, post_date,
channel->studio, models->performers, categories+tags.
Stream: videofile.php returns video_url in two obfuscation layers, Cyrillic
homoglyphs (M/C/A/E) over a custom base64 alphabet (comma->slash, tilde->pad,
dash->plus). Decoded get_file is absolute (old shared-txxx videos) or relative
(new vjav-infra, prepend host); adding f=video.m3u8 yields a portable, time-bound
ahcdn HLS (referer=none whitelisted, not IP-bound). Returned as m3u8 +
mobile_direct_ok so playback routes it through /proxy/hls: manifest passthrough,
segments direct from the phone (verified 206 cross-IP, 0 VPS video bandwidth).
Backend-only, no mobile change (JAV tab + jav param already shipped).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>