Proxy miniatur oddaje 404 dla banera usunietego obrazka pixhost i dla
odpowiedzi tekstowych (link do strony podgladu), zamiast 200 z atrapa.
Kategorie mixed-porn i porn-movie pomijane: serwis daje je kazdemu wpisowi.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Od 2026-10-15 ok. 04:31 UTC Cloudflare oddaje 403 na IPv4 VPS-a (IPv6 200).
Ekstraktor nie patrzyl na status, API dawalo 503 i perverzija nie grala
nikomu; listing zwracal [] jak koniec katalogu, a uzupelnianie dlugosci
palilo proby. HTML przez Bright Data tylko przy 403, player bez zmian.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hentaimama: nowy zapis id posta i 5 playerow w admin-ajax, adresy w JSON-ie;
bierzemy mp4 z gdvid (3 jakosci, bez tokenu), POST najpierw bez proxy.
Ogon "Watch Online Free in HD" w tytulach ucinany.
xanimeporn: przekierowanie download.php rozwiazywane na serwerze, apka
dostawala .php, otwierala WebView i pobierala plik zamiast grac.
Blad resolve (extractor pusty, HTTP strony) trafia do playback_events.
Filmy: tytul z okruszkow (motyw dooplay losuje "Watch"/"Now Playing:"),
linki nitroflare/rapidgator nie sa juz brane za wideo, sam landing idzie
do WebView, a przytrzymanie w apce nie zabija ostatniego linku filmu,
jesli serwer widzi, ze zyje. Skrypty naprawcze: tytuly dooplay,
tytuly i miniatury hentaimama, repair_dooplay_movies dla streampornvip.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- browse_runs (migracja 0056): jeden wiersz per scraper i przebieg browse-latest
- quality_watchdog: listing pusty albo bez nowych, skok lub zanik obsady, sceny bez
dlugosci i miniatur, spadek udanych odtworzen per origin; fingerprint per zrodlo i rodzaj
- ingest_watchdog: prog swiezosci z mediany odstepow zrodla (3x, max 14 d) zamiast stalej
- duration backfill: resolvery perverzija (JSON-LD) i mypornerleak (itemprop), paczka
po rowno z originow, 404/410 zamyka wiersz od razu
- parsery: galaxyporn data z JSON-LD, hentaimama dlugosc, javflix aktorki, fullmovies
i hdporngg data z uploadDate
Stary globalny regex /models/ gubil prawdziwa obsade (nazwa w spanie, pusty tekst
linku) i dopinal performerow z kart related (srednio 12 na scene). Kategorie
to teraz gatunki, nie studio; tagi bez przedrostka #.
- superporn: feed /videos/latest/N zamiast rotujacej strony glownej
- pornbusy: karty ze strony glownej przed spoznion sitemapa
- dooplay/streamporn: nowy motyw (card__th, h1 vid__t, data-servers JSON,
st--duration, time datetime, chipy gatunkow), odstep i ponowienia w _fetch
- porndoe: listing z sitemap_videos.xml; None gdy zadna strona sceny nie parsuje
- hentaimama: /episodes/feed/ poza regexem odcinkow
- watchdog: progi per zrodlo dla serwisow publikujacych rzadko
Strona nie escapuje apostrofu w title/alt, wiec "Brenna's Mouths" urywal
dopasowanie i kafelek wypadal (3 z 18 na stronie). Pierwszy czlon alt z
kilkoma osobami ("A, B - Tytul") szedl jako jeden wykonawca.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bramka nazwy w slugu zwracala True, gdy zaden czlon nazwy nie mial 3 znakow ("Wa A",
"Al B", "T P"), a wolajacy pomijali ja przy pustych tokenach. Performer-driven
dopinal wiec takiego wykonawce do kazdego wyniku wyszukiwarki tuba: 108 wykonawcow,
10,5 tys. blednych przypisan w 7,9 tys. scen. Teraz takie nazwy nic nie dopasowuja.
Na produkcji bledne przypisania usuniete (kopia w scene_performers_removed_20260924).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Strona filmu hqporner nie ma wlasnej okladki, a pierwszy _main.jpg na niej to kafelek
polecanego filmu. Scraper go bral, wiec ~90% zrodel dostalo cudze miniatury (62 tys.
zrodel, 5,4 tys. roznych miniatur). Okladka jest tylko w kafelku listingu
(cover_<id>): browse zbiera je z listingu, wyszukiwarka z wynikow wyszukiwania.
scripts/hqporner_fix_thumbs.py poprawia zapisane miniatury przechodzac listing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
siska.video od 2026-09-22 nie istnieje (NXDOMAIN), ten sam serwis dziala pod
siska.tv z tymi samymi videoID i sciezkami miniatur. Scraper bierze kafelki z obu
domen i z www, zapisuje jeden kanoniczny adres. Lista najnowszych jest pod
best_xvideos.php?page=N, bo /page/N/ na siska.tv zawsze oddaje strone 1.
Na produkcji adresy stron, miniatur i external_id przepisane na siska.tv
(16 007 zrodel, 16 265 powiazan scen); 103 duplikaty www.siska.video oznaczone
jako martwe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
xvideos (JSON-LD) i kilka innych tubow oddaje tytuly z encjami HTML5
(`we're`, `(AI)`), czasem podwojnie zakodowane. normalize
robil z nich slowa `apos`, `lpar`, wiec tytul nie trafial w wyszukiwarke
ani w kanon.
unescape_html w app/normalize/text.py dekoduje encje zakonczone srednikiem
po slowniku HTML5, do skutku (max 3 przebiegi). Wpiete w normalize_scene i
normalize_movie oraz w parsery xvideos_browse i pornxp. Skrypt
fix_html_entity_titles.py poprawia istniejace wiersze (title,
title_normalized, slug gdy byl wyliczony z tytulu).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- _search_base: hak _thumbnail_map (mapa url -> miniatura z calej strony) przed
szukaniem <img> w oknie tekstu; xhamster mial 54% zrodel bez miniatury
- mypornerleak search: karty maja teraz src zamiast data-src; browse (REST) bez
featured media -> og:image ze strony posta
- scripts/backfill_thumbs.py: uzupelnia miniatury ze strony sceny, od najnowszych
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tubepornclassic.com to SPA sieci TXXX (ten sam silnik co vjav): HTML ma pusty
<title> i zero linkow do scen, wszystko idzie z JSON API. Listing
/api/json/videos2/<cache>/str/latest-updates/60/..<page>.all...json oddaje
60 rekordow z pelnymi metadanymi (tytul, slug, dlugosc, post_date, obsada,
kategorie+tagi, miniatura), wiec nie ma fetchu per scena. ~168 tys. wideo,
wgrania codziennie. Koniec katalogu = 200 z code=videos_not_found.
Stream: videofile.php -> dekod video_url -> get_file -> f=video.m3u8 -> HLS
na ahcdn (klucz time-bound, nie IP-bound: adres wybity z VPS gra z lacza
domowego). Ten tor zyl dotad w tubes/vjav.py; wyniesiony do
_txxx.extract_hls, vjav i tubepornclassic wolaja to samo. HLS zamiast mp4,
bo mp4 z tego samego get_file ma w URL CDN speed=... (~1,2 MB/s), a segmenty
HLS leca ~3,6 MB/s. Wyzwanie 429 (ciasteczko w ciele) obsluzone w
ekstraktorze, scraperze i juz wczesniej w /proxy/hls.
Bramka: 38% tytulow to generator SEO ("Fabulous Sex Movie Vintage Try To
Watch For Ever Seen"). Z doczepionym nazwiskiem scena jest odnajdywalna
i zostaje; bez obsady (22%) nie wchodzi, bo nie ma po czym jej znalezc
ani z czym zdeduplikowac. Obsada u 46% scen, studiow brak.
Pilot: 2 strony, 120 scen, 111 nowych, 9 juz w bazie, wszystkie z dlugoscia.
Odtworzenie na emulatorze: playback_events success (ttff 3,3 s), AudioTrack
started. vjav po refaktorze: ten sam wynik ekstraktora co przed.
Z szesciu stron z listy piec juz jest lub bylo w bazie: fullmovies.xxx,
hdporn.gg, neporn.com sa zywe (ingest z dzisiaj, odtwarzanie 84-99%),
a hqfap.com i 4k69.com nadal oddaja Cloudflare JS-challenge na podstronach
(403 "Just a moment" takze z lacza domowego, wiec to nie blokada po IP).
Jedyna nowa to porndupe.
Porndupe wyglada jak KVS, ale to atrapa: kazdy get_stream/<id>-<q>.mp4?md5=
odpowiada doslownie "error" (sprawdzone z sesja, Refererem strony i embedu,
z permutacja md5 kodem licencyjnym). Prawdziwy tor widac w DevTools:
generate_mp4('<b64 JSON>', '<haslo>', '<okid>', '<id>')
-> {ciphertext, iv, salt, iterations: 999}
-> PBKDF2-SHA512 + AES-256-CBC -> klucz sesji OK.ru (staly; haslo i
ladunek zmieniaja sie co wczytanie, to zaciemnienie)
-> api.ok.ru/fb.do method=video.get -> url_low/medium/high/fullhd,
duration (ms), created_ms, thumbnail_url
Wariant PBKDF2 ustalony empirycznie: SHA-1/SHA-256 daja bad decrypt,
SHA-512 oddaje dokladnie klucz z trace'u.
okcdn: srcIp wbite w URL, NIE egzekwowane (URL z lacza domowego pobrany
z VPS -> 206, 514 MB, ftypisom) -> mobile_direct_ok. Cap 720p, bo OK.ru
dlawi polaczenie do ~2,1 Mbps (decyzja z 4k69/8kporner).
Browse po id (vjav pattern): kazdy listing to catch-all z tymi samymi 24
linkami, sitemapy pokrywaja 3500 z 12 887 id. /video/<id>/ -> 301 slug
(istnieje) albo 302 / (brak). Dlugosc z api.ok.ru przy ingescie (HTML nie
ma duration ani uploadDate). Daty CELOWO nie: created_ms to dwie fale
hurtowego wgrania (07.2024, 04.2025), nie premiery.
Katalog ZAMROZONY od kwietnia 2025, wiec to jednorazowy import, nie zrodlo
swiezosci. Wchodzi, bo 87% scen (52/60) nie mamy, a to tresc studyjna
(Nubile Films, NF Busty, Family Strokes) trafiajaca w kanon, w odroznieniu
od hentaicloud (17%). Pilot crawl_page(1): 22/22 z dlugoscia, 21/22 z
performerem, studia i tagi per-video.
Blad diagnostyczny po drodze: strona blankuje sie do about:blank po wykryciu
CDP (disable-devtool z jsdelivr); trace przezyl, DOM nie.
- person_named_in: jednowyrazowe nazwisko tylko co do znaku (albo zlepek sasiednich
czlonow tytulu), przedrostek co najwyzej o 2 znaki; "Thebdck" lapal kazde "the"
- sxyprn: autor z sciezki miniatury, _BLOCKED_AUTHORS (Shizuka, Ajx, Denzel),
karty z >20 hashtagami wchodza bez tagow
- scripts/sxyprn_purge_uploaders.py: dry-run/apply, sceny tych autorow + smieciowi performerzy
Watchdog zglaszal "tube:porndoecom (browse) bez nowych tresci (173h, prog 48h)" i
potraktowalem to jako szum razem z alertami dla tubow, ktore faktycznie przestaly
publikowac. Bledna ocena: porndoe to nasze czwarte co do wielkosci zrodlo (356 tys.
zrodel), a ostatnia nowa scena wpadla 2026-08-21.
Przyczyna: porndoe zaczal oddawac HTTP 403 na IP serwerowni. Scraper dostawal strone
bledu, znajdowal zero linkow i konczyl sie bez wyjatku, wiec z zewnatrz wygladalo to na
"tub sie wyczerpal", a nie na awarie. Ten sam ksztalt pomylki co przy porntrex, gdzie
cicha zmiana markupu ukryla 6479 scen.
Sprawdzone 2026-08-31: bez proxy 403 i 0 scen, przez Bright Data ISP proxy 200 i 31 scen
z pierwszej strony, z datami z 30 sierpnia, dlugosciami i obsada. Wzorzec i uzasadnienie
kosztowe jak przy superporn: ISP proxy jest ryczaltowe, wiec deep-crawl nie kosztuje
wiecej, a przez proxy leci sam HTML, nigdy strumien.
Bez skonfigurowanego proxy `crawl_page` zwraca pusta liste zamiast dobijac sie o 403.
Zgloszenie e28f2517: scena "Bridgette B, Gigi Rivera, Julia Ann, Phoenix Marie, ..."
miala przypisana Julie B., ktorej w tytule nie ma.
Mechanizm: scraper wola strone performera i sprawdza, czy scena naprawde go dotyczy,
porownujac czlony nazwiska z tytulem. Robil to jednak KAZDY Z OSOBNA i tylko od trzech
znakow. Dla "Julia B." czlon "b." odpadal na dlugosci, zostawalo samo "julia", i
przypisanie lapalo kazda scene z tym imieniem w tytule. Stad tez "Chloe S" przy
"Chloe Kreams", "Sharon D" przy "Sharon White", "May E" przy "Danielle Maye".
Nowa regula (`person_named_in` w `app/normalize/text.py`): czlony musza stac OBOK
SIEBIE i w tej samej kolejnosci. Od trzech znakow wystarczy zgodnosc przedrostka, zeby
przezyly warianty zapisu ("Savanna Bond" przy tytule "Savannah Bond", "Jyn Maze" przy
"Jynx Maze"). Inicjaly musza zgadzac sie dokladnie. Tytul tniemy wczesniej na segmenty
po przecinkach i myslnikach, bo bez tego smieciowy performer "Rope Bondage" dopasowywal
sie do doklejonego ogona tagow "- rope - bondage".
Swiadomy koszt: odwrocona kolejnosc ("Goldy Kim" wobec "Kim Gold") nie przejdzie, a
performer z inicjalem zamiast nazwiska nie dostanie ze sxyprn nic. Przy wyborze miedzy
pominieciem sceny a przypisaniem jej niewlasciwej osoby wolimy pominac, bo to bledne
przypisanie widac na ekranie performera i to ono jest zglaszane.
Smoke test po zmianie: Lana Rhoades, Julia Ann, Angela White i Abella Danger dalej po
30 scen ze strony performera, wiec scraper sie nie zamrozil (to sie juz raz zdarzilo
przy zbyt ostrym filtrze). "Julia B." oddaje teraz zero zamiast cudzych scen.
Dolozony `scripts/sxyprn_fix_overattribution.py`, ktory stosuje te sama regule wstecz.
Uruchomiony na produkcji: skasowane 85 379 z 239 686 przypisan (35,6%). Ruszamy tylko
sceny majace WYLACZNIE zrodlo sxyprn i tylko przypisania od scrapera; kanon
(tpdb/stashdb) nietkniety. Regula sprawdzona recznie na dwoch probkach po ~20 pozycji,
wszystkie kasowane byly faktycznie bledne.
Skutek uboczny: scen bez zadnego performera przybylo z 3 622 do 23 891. To sceny,
ktorych jedyne przypisanie bylo bledne, wiec brak jest uczciwszy niz cudze nazwisko.
javflix stal 89h bez nowosci, mimo ze scraper chodzil i widzial sceny. Powod:
listing szedl ze strony glownej, a ta pokazuje staly zestaw 16 postow, ktory mamy
w calosci. Audyt 2026-08-20: /new/ ma 7 nieznanych scen z 9, strona glowna 0 z 16.
Przy okazji paginacja: WordPress ja tu tylko udaje. /page/2/ i /page/3/ oddaja
identyczna tresc co strona glowna, a /new/page/2/ to samo co /new/, wiec
browse-latest mielil ten sam zestaw piec razy na run. Teraz strona 1 to /new/,
strona 2 to strona glowna, dalej pusto.
Zweryfikowane na zywo: run oddal seen=25, new=7.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zgloszenie 2026-08-13: strona Tiffani Time pelna scen o Tiffany Tatum,
Tiffani Madison i Victorii Tiffani.
Przyczyna: `_search_base.search` dokleja szukanego performera do KAZDEJ
sceny bezwarunkowo (`all_performers = [RawPerformer(name=query), ...]`),
wiec cala poprawnosc obsady wisi na filtrze tokenow. A filtr testowal
PODCIAG na luznych tokenach, wiec:
"tiffany" ⊂ "lp-s-tiffany-love-first-time-gonzo" (inna osoba)
"time" ⊂ "adult-time", "first-time", "multiple-times" (pospolite slowo)
Historia tej linijki to trzy poziomy: any() -> all() -> (teraz) fraza.
`all()` naprawil "Ava Koxxx na scenach Avy Devine", ale zostawil oba
powyzsze. Teraz slug musi zawierac CALA nazwe jako ciag, z granica slowa
po bokach, z dowolnym separatorem miedzy czlonami.
Dozwolone koncowe "s": slug gubi apostrof, wiec "TiffaniTime's" zapisuje
jako "tiffanitimes". Nie luzuje bramki, bo przed tym "s" stoi cala fraza.
hqporner mial WLASNA kopie tego filtru (i wlasny zestaw dziur) - podpiety
pod ta sama funkcje, zeby sie nie rozjezdzalo.
12 przypadkow testowych z realnych danych, w tym te ktore MUSZA przejsc
(tiffani-time-*, tiffanitimes-*, mia-li-* z czlonem <3 znaki).
Do tego skrypt czyszczacy juz istniejace pomylki. Kryterium zawezone po
obejrzeniu probki: samo "brak nazwy w tytule" kasowalo MESKICH performerow
(tuby nie wypisuja ich w tytule, a przypisanie szlo z listy obsady, nie
z searcha). Dolozony warunek "inny performer sceny ma dowod I dzieli
czlon" - probka 14/14 to realne pomylki.
Machinima i animacje SFM/Blender. Kanon nie istnieje tak samo jak przy
hentai i rule34video, wiec kazda pozycja jest orphanem i to poprawne.
Najzdrowsza jednostka tresci calego wertykalu 3D: mediana 289 s, ZERO
pozycji ponizej minuty, 18/25 powyzej progu potoku. Dla porownania
rule34video ma mediane 68 s i traci ~70% katalogu.
Playback najprostszy z serii: jawne <source> w trzech jakosciach, bez
tokenu, bez AJAX-a, bez CF. Zweryfikowane z VPS: 206, ftypisom, 140 MB,
dziala bez Referera, wiec mobile_direct_ok i zero pracy po stronie apki
(inaczej niz rule34video, gdzie token byl IP-bound).
Szosty niezalezny host wertykalu (videos.naughtymachinima.com), zadna
z szesciu stron nie re-hostuje pozostalych.
Odsiewamy pusty <source src=""> (placeholder playera) i preroll
/images/preroll/NMintro.mp4, ktory pasuje do naiwnego \.mp4.
Bramka dlugosci zestrojona z min_ingest_duration_sec, jak przy
rule34video. Pilot 3 strony: seen 48, new 48, skipped 0, errors 0.
Animacje SFM/Blender. Kanon nie istnieje tak samo jak przy hentai, wiec
kazda pozycja jest orphanem i to poprawne.
Playback: KVS z jawnymi flashvars (4 jakosci, bez license_code), ale
`v-acctoken` jest ZWIAZANY Z IP tego, kto pobral strone. Test krzyzowy:
URL wygenerowany przez proxy i pobrany z VPS = 403, ten sam URL z IP
generujacego = 206 ftypisom 70 MB. Po zdekodowaniu tokenu adresu nie
widac wprost (inaczej niz fpoxxx), wiec samo ogladanie nie wystarcza.
Dlatego bez mobile_direct_ok: telefon resolwuje sam, UPFRONT, istniejaca
sciezka isGetFileUrl()/resolveGetFilePage z SceneDetailScreen. Rozszerzam
getfileResolver o flashvars, bo dotad umial tylko <source> (hdporn.gg,
fullmovies.xxx). Zweryfikowane end-to-end z residential IP: strona ->
flashvars 720p -> 302 na boomio-cdn -> 206 ftypisom 39,8 MB.
Bramka dlugosci zestrojona z `min_ingest_duration_sec` (prod 180 s)
zamiast wlasnej liczby: pierwsza wersja miala 60 s i liczniki klamaly
(seen 57, new 31, skipped 26). Po zestrojeniu seen 20, new 20, skipped 0.
Krotka tresc wycina ~70% katalogu (mediana 68 s).
Tagi TYLKO z class=tag_item. `class=button` wyglada na wlasciwe, a jest
chmura "Top Tags": przy filmie o Lux siedzialy tam "cell (dbz)" i
"queen of pain (dota)". Autor animacji zapisany jako studio.
CZWARTY niezalezny host: pliki na hentaiplanet.info, podczas gdy hentaimama ma
gdvid.info, xanimeporn download.xanimeporn.com, a hentaigasm hgasm<N>.com. Cztery
strony, cztery osobne pule plikow - zadna nie re-hostuje pozostalych, mimo ze katalogi
odcinkow mocno sie pokrywaja.
Metadane z RSS-a, tak jak przy hentaigasm i z tego samego powodu: /genre/ w HTML strony
to 2084 linki, najwieksza chmura z sidebara w calym wertykale (hentaigasm mial 38,
hentaimama 118). Feed daje date, tytul i realne kategorie. Odsiewamy przy tym pozycje
czysto techniczne (Hentai Anime, New Hentai, English Subbed) oraz rocznik, bo to nie sa
tagi tresci. /page/2/ nie zwraca odcinkow, /feed/?paged=N stronicuje chronologicznie.
Playback: mp4 wprost w HTML (video.js), bez AJAX-a i bez Cloudflare. Pulapka: serwis
nazywa miniaturki od pliku wideo (…-RAW.mp4_snapshot_07.59.jpg), wiec naiwne szukanie
.mp4 lapie zarowno wideo, jak i obrazek. Wymagamy URL-a KONCZACEGO sie na .mp4 i
odrzucamy wp-content/uploads.
Druga pulapka, zlapana dopiero testem: og:image na tej stronie NIE ISTNIEJE, miniaturka
jest tylko w JSON-LD i z escapowanymi ukosnikami. Pierwsza wersja dawala 12/12 odcinkow
bez miniaturki.
Zweryfikowane z VPS: 206 na Range, ftypmp42, 78 MB, dziala BEZ Referera i bez tokenu.
Serwer oddaje content-type application/octet-stream, ale sciezka konczy sie .mp4, wiec
ExoPlayer wybierze Mp4Extractor po rozszerzeniu.
Pilot: seen 48, new 48, errors 0. Komplet dat i miniaturek.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
TRZECI niezalezny host w wertykale. Te same odcinki co hentaimama i xanimeporn, ale
znowu inne pliki: tutaj hgasm<N>.com/<Tytul Ze Spacjami>.mp4, tam gdvid.info/N/... i
download.xanimeporn.com/videos/1080p/[1080p]<id>.mp4. Zadna z trzech stron nie
re-hostuje pozostalych.
Metadane w CALOSCI z RSS-a i to nie skrot tylko koniecznosc:
- strona odcinka NIE MA daty publikacji w zadnym standardowym miejscu (ani JSON-LD,
ani article:published_time, ani <time>), a feed ma pubDate
- /genre/ w HTML to 38 linkow, czyli kolejna chmura z sidebara; feed daje 5 realnych
kategorii, gdzie pierwsza to nazwa serii
- /page/2/ nie zwraca odcinkow w ogole, a /feed/?paged=N stronicuje chronologicznie
Playback najprostszy z calej trojki: konfiguracja JWPlayera z gotowym file: wprost w
HTML, bez AJAX-a i bez Cloudflare. Sciezka zawiera SPACJE, wiec kodujemy sama sciezke,
zostawiajac schemat i host. Host ROTUJE miedzy odcinkami (hgasm1/hgasm3), wiec czytamy
go ze strony zamiast wpisywac na sztywno.
Zweryfikowane z VPS: 206 na Range, ftypisom, 198 MB, dziala BEZ Referera i bez tokenu,
wiec URL nie wygasa. mobile_direct_ok.
Pilot: seen 107, new 107, errors 0. Metadane: 100 procent z data, miniaturka i tagami.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
NIE jest re-hostem hentaimamy i to bylo pierwsze, co sprawdzilem. Wspolny odcinek
(Shoujo Ramune 7) lezy na obu stronach, ale to zupelnie inne pliki: hentaimama serwuje
gdvid.info/S/shoujo-ramune-7.mp4 w jednej jakosci bez etykiety, a tutaj jest
download.xanimeporn.com z jawnym wyborem 1080p (222 MB) i 720p (84 MB).
Listing idzie z RSS-a i to jedyna droga, ktora dziala. Sprawdzone trzy inne:
- /page/2/ i /page/3/ oddaja ten sam zestaw co strona 1 (28 z 32 wspolnych),
czyli paginacja zepsuta jak przy 8kporner
- /uncensored/ i /censored/ stronicuja poprawnie, ale NIE sa chronologiczne: pierwsze
pozycje z 2024, zakres 2015-2026. Browse-latest nigdy nie zobaczylby nowego odcinka,
czyli pulapka z freshporno. Pierwsza wersja konektora wlasnie tak dzialala i dopiero
test na danych to pokazal
- /hentai-list/ ma caly katalog (1048) na jednej stronie, ale nie jest chronologiczny
Drugi filtr tez wymuszony przez dane: slugi gatunkow (/futanari/, /big-tits/) sa takimi
samymi slugami najwyzszego poziomu jak odcinki i wchodzily jako pozycje bez daty i
miniaturki. _parse_detail wymaga teraz postid w klasie body, ktory maja tylko
pojedyncze wpisy. Ten sam identyfikator jest potrzebny extractorowi.
Playback: Fluid Player z PUSTYM <source src=''>, wideo wstrzykiwane w runtime, wiec w
HTML nie ma zadnego linku. Wyjsciem jest zakladka Downloads:
videos.xanimeporn.com/download.php?id=<postId>&quality=. Oddajemy download.php, NIE
docelowy plik, zeby token generowal sie przy odtwarzaniu i nie wietrzal (lekcja z
watchporn). Bez Cloudflare i bez proxy, w odroznieniu od hentaimamy.
Pilot: seen 50, new 50, errors 0. Metadane: 100 procent z data, miniaturka, kategoria
i seria jako tagi.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Jednostka tresci to ODCINEK (/episodes/<seria>-episode-N/), mapowany na scene tak samo
jak w wertykale JAV, bez zmian w schemacie. Seria ladue jako tag, wiec odcinki daja sie
grupowac.
KRYTERIUM JEST TU INNE I TO CELOWE. Dla animacji nie istnieje kanon - TPDB i StashDB
nie maja rysowanych postaci - wiec kazda scena stad jest technicznie orphanem i to
jest POPRAWNE. Nie stosujemy ani bramki na obsade (nie ma obsady), ani miary canonical
match, ktora sluzyla nam do oceny tubow z zywymi aktorami. Jakosc mierzymy kompletem
seria + odcinek + gatunki.
Motyw jest z rodziny Dooplay, ale DooplayConnector NIE pasuje: brak data-fl-source i
data-post, na ktorych stoi tamten parser. Player idzie w trzech krokach: id posta ze
strony odcinka, POST /wp-admin/admin-ajax.php z action=get_player_contents, potem
strona wlasnego playera, ktora oddaje bezposredni mp4. Sam POST jest za Cloudflare
(GET-y przechodza), wiec wymaga Bright Data, dokladnie jak POST /api/video-info w sexu.
Playback najlepszy z mozliwych: preferujemy gdvid.info, bo oddaje plik BEZ tokenu,
wiec URL nie wygasa. Zweryfikowane z VPS: 206 na Range, ftypisom (faststart), dziala
BEZ Referera, stad mobile_direct_ok.
Pulapka obeszla: /genre/ w calym HTML to 118 linkow (chmura w sidebarze, ten sam wzorzec
co przy sexu i yourdailypornmovies). Gatunki bierzemy tylko z div.sgeneros, co daje 5-10
realnych pozycji na odcinek.
Pilot: seen 90, new 90, errors 0. W bazie 90 odcinkow, 100 procent z data i tagami,
zakres 2025-12-29 do 2026-07-31.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1745 wystapien w 291 plikach (backend, scripts, mobile). Dominowal jeden ksztalt,
' — ' laczace zdania, wiec poszedl przecinek; myslnik otwierajacy mysl zdjety;
zakresy 0–5 i A–Z na dywiz.
Podzial komentarz/kod robil skaner stanow, nie regex, zeby nie ruszyc myslnika
stojacego w stringu albo w wyrazeniu regularnym. Potwierdzone maszynowo: po wycieciu
komentarzy z wersji HEAD i z dysku obie sa identyczne we wszystkich 291 plikach,
czyli poza komentarzami nie zmienilo sie nic. 233 pliki .py parsuja sie bez bledu,
tsc ma te same 11 bledow w tych samych 3 plikach co przed zmiana.
Dwie rzeczy wymagaly poprawki po automacie: wyrownane listy definicji, gdzie myslnik
byl separatorem kolumny (37 miejsc, kolumna przywrocona), i trzy przeniesienia mysli
do nowej linii, gdzie zostawal wiszacy przecinek na poczatku (poprawione recznie).
Bundla nie republikuje: Hermes i tak nie niesie komentarzy, wiec dla uzytkownika
to zero zmiany.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Po naprawie dostepu vjav ruszyl, ale zaczal sypac smieciem: pomiar na 295 scenach z
doby po fixie dal 78,6 proc. tytulow slug-concat i ZERO przypisanej obsady. Takie
sceny sa w apce nieodnajdywalne - nie maja ani tytulu, ani performera.
Bramka odrzuca cztery wzorce: prefiks id_JAV, hash x1x..., kod typu
QCT062-KPUDYLMLBL913295279 oraz ciagi bez samoglosek/spacji (walniecie w klawiature).
Zmierzone na probce 6000 tytulow: odrzuca 80 proc. swiezych i 27 proc. starych, przy
39 przepuszczonych na 200 obejrzanych - zrodlo nie jest wyzerowane.
WAZNE, znalezione przy pomiarze pierwszej wersji: str.isalpha() jest prawdziwe dla
kana i kanji, a japonski nie stawia spacji, wiec reguly "za malo samoglosek" i "brak
spacji" odrzucalyby PRAWDZIWE tytuly na serwisie JAV - 708 z 708 tytulow CJK z probki.
Stad jawny wyjatek _has_cjk. Kontrola jednostkowa: 8/8 przypadkow, w tym dwa CJK.
Drugi blad, wprowadzony przez sama bramke i zlapany dopiero pilotem: strona 1 jest w
100 proc. smieciowa, wiec po odsianiu zwracala [], a bazowe latest_scenes traktuje
pusta strone jako koniec katalogu i konczylo caly run. Zrodlo dawalo seen: 0 mimo 39
dobrych scen na stronach 2-5. Wlasna iteracja rozstrzyga wyczerpanie po dlugosci listy
id, nie po liczbie scen po filtrze. To ta sama pulapka co w _load_ids.
Pilot po obu poprawkach: seen 39 (wszystkie skipped - weszly przed bramka).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audyt po fixie streamporn.vip. vjav (77 tys. zrodel) nie dodal nic od 2026-07-22 i
NIE zglaszal bledu - crawl_page oddawal 0 scen, licznik pokazywal errors: 0.
Przyczyna: vjav odcial IP VPS-a. Sprawdzone 2026-08-03 - sitemap, strona glowna i
/latest-updates/ daja 429 przy trzech probach z rzedu, a przez Bright Data 200 od
pierwszej. Kod tego nie widzial, bo browser_get NIE rzuca na 4xx, wiec 343-bajtowa
tresc bledu byla parsowana jako XML: zero sitemap, zero id.
Drugi blad, ktory to ukryl: przy niepowodzeniu _load_ids ustawialo _sorted_ids = [],
a crawl_page tlumaczy [] na "koniec katalogu" (poprawny stan), nie na awarie. Teraz
przy bledzie zostaje None, ktore crawl_page zwraca jako transient-fail.
Fix: proxy Bright Data na sitemap i API metadanych (ten sam host, ten sam 429), jawne
sprawdzanie statusu, [] tylko dla realnie pustego katalogu.
Po fixie crawl_page oddaje 120 scen zamiast 0. Nowej podazy to jeszcze nie dalo
(wszystkie 120 to pozycje sprzed blokady, skipped na niezmienionym hashu) - sitemap
vjav nie przesunal sie od czasu odciecia. Do obserwacji. Uwaga na jakosc: w tej
partii 58 proc. tytulow to slug-concat typu 0008363_JAV_..., przy 2,9 proc. w calym
katalogu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Druga i ostateczna deaktywacja (pierwsza 2026-06-25, wtedy stub-pliki). Strona
wdrozyla Cloudflare z JS-challenge na /watch/. Sprawdzone TRZY drogi, wszystkie 403:
VPS (Hetzner), residential IP z pelnym kompletem naglowkow przegladarki, oraz
Bright Data ISP proxy. Czyli blokada NIE jest po IP - wymaga wykonania JS.
Przelaczenie na WebView (commit 140764b) tez nie wystarczylo: challenge pokazuje sie
userowi zamiast przechodzic samoczynnie (zgloszenia 92e9133e / 60576a84 / 244131ba).
Telemetria: ZERO prob odtworzenia od 27.07, czyli realnie martwe od tygodnia.
Utrzymanie wymagaloby headless-przegladarki na VPS - nieproporcjonalne do zysku,
decyzja uzytkownika: usunac. Wyrejestrowany scraper (browse) i extractor;
61238 playback_sources oznaczone dead_at. Uwaga: hqporner to INNE zrodlo o mylnie
podobnej nazwie - nietkniete, dziala.
Bug-report 986d3018 ('O co chodzi z tym Lady Vi? To wcale nie jest aktorka z tych
filmow'). Search-scrapery filtruja wyniki po tokenach nazwy >=3 znaki, wiec czlon
2-znakowy wypada: 'Lady Vi' -> {lady}, i degeneruje sie do 'slug zawiera
lady' = KAZDA scena z tym slowem. Dla nazw gdzie WSZYSTKIE czlony sa krotkie
('Jj Jj', 'Mi Su') zbior tokenow jest PUSTY, a
przepuszcza wtedy absolutnie wszystko.
Audyt: Lady Vi miala 116 przypisan z tube, z czego 115 pasowalo tylko przez 'lady'
a realnie o niej byla 1. Wyczyszczone (zostaly kanoniczne stashdb + 1 trafione).
Fix: gdy nazwa ma czlon <3 znaki, wymagamy dodatkowo CALEJ nazwy sklejonej bez
separatorow ('lady-vi-...' -> 'ladyvi'). Zweryfikowane: lady-vi-hot-scene przyjmie,
lady-sonia-milf i busty-lady-next-door odrzuci.
Pelne sceny, nie klipy: mediana ~33 min, zero ponizej 10 min, ~140-240 dziennie,
listing chronologiczny mimo naglowka Featured.
Extractor sklada URL sam, bez tokenu i bez wygasania: id w iframe jest zapisane
wspak, a koncowka to maska bitowa jakosci (1/2/4/8 = 360/480/720/1080). Id bywa
numeryczne albo szesnastkowe, a to drugie to ~25% katalogu. Blokada CDN jest na
naglowku (bez UA 403, bez Referera 404), NIE na fingerprincie TLS, wiec telefon
przechodzi -> mobile_direct_ok. Zweryfikowane 206 + faststart do 1080p.
Metadane cienkie: brak studia, mediana 3 tagi, tytuly przepisane pod SEO. Za to
data jako unix timestamp i dlugosc co do sekundy. Bramka na obsade, bo sceny bez
performera scalily sie 0/23 w dry-runie.
Phash miniatury liczony celowo i to on robi robote: dry-run resolvera bez niego
dawal 31% scalen, pilot z nim dal 65% (seen 62, new 22, updated 40, errors 0).
85 z 89 performerow ma ref tpdb/stashdb.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Metadane ma najlepsze z tej serii: kanal = realne studio na 97% scen, 96%
performerow z refem tpdb/stashdb, dokladna dlugosc w sekundach, swiezosc w
godzinach, 120 scen na stronie listingu.
Nie wlaczamy go jednak do ALL_BROWSE_SCRAPERS, bo jednostka tresci jest zla:
to klipy 5-10 minut, nie sceny. Mediana 571 s na stronie 30 i 459 s na 200,
zero filmow >=20 min w calym katalogu. Pilot na 240 scenach dal 1 canonical
match, bo dlugosc i tytul, czyli sygnaly resolvera, sa przepisane pod tube.
Przy ~340 uploadach dziennie to ~10k nierozwiazywalnych wierszy miesiecznie.
Kod zostaje kompletny i zweryfikowany: POST /api/video-info przez Bright Data
(CF blokuje sam POST z VPS), HLS playerData.src zamiast mp4 sources (te maja
ip= requestera w tokenie), master konczy sie .mp4 wiec lapie go istniejacy
hls_needs_passthrough. Gdyby serwis zaczal wrzucac pelne sceny, wystarczy
dopisac klase z powrotem do rejestru.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sitemapa i /watch/*.html są za Cloudflare, paginacja zwraca stronę 1, a load-more
chce logowania, więc katalog buduje się z homepage (~115 scen), a detale lecą przez
?link1=watch&id=. Bramka na obsadę przepuszcza 62/115; z tego 97% performerów ma
ref tpdb/stashdb, a 60% scen dopina się do tego, co już mamy.
Extractor czyta tablicę sources JWPlayera, nie JSON-LD contentUrl (ten jest zawsze
144p). Cap 720p, bo okcdn dławi połączenie do ~2,1 Mbps. Stream przenośny cross-IP
(206 bez Referera, faststart) → mobile_direct_ok.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pornmike.com puts everything in JSON-LD @graph -> ItemPage.mainEntity
(name, duration, uploadDate, actor[], genre[], keywords, description,
thumbnail), so the parser reads one JSON blob instead of scraping markup.
Cast is clean: the whole scene page carries exactly as many /pornstar/
links as there are actors, none of the sidebar pollution that got xxxfiles
rejected. 82% of sampled performers already carry a tpdb/stashdb ref and
19-20 of 20 channels are studios we already know.
Ingest is gated on a non-empty actor[]: 23% of the catalog has no cast and
those scenes could neither be attributed nor deduped. Tags and categories
come only from JSON-LD (keywords + genre), never from the HTML, which
carries 38 /category/ and 22 /tag/ nav and sidebar links per page.
Pagination is ?p=N only: the /N/ form 404s and ?page=N is silently ignored,
returning page 1.
Playback is the simplest in the portfolio: a plain <source> mp4 on twincdn
with no token, no query string and no expiry. Verified 206 on a Range
request from the VPS and from another machine in another country, both
without a Referer, so it is neither hotlink-guarded nor IP-bound and the
phone streams it directly.
Two honest caveats recorded in the module docstring: these are 5-12 minute
clips (median ~487s against 1800-2400s for the tubes we accepted), so for
the ~20% of the catalog from Tushy/Blacked Raw/Milfy/Anilos they will sit
as a short shadow next to full canonical scenes; and uploadDate is the
tube's import date, not the studio release, so pages past the second are
marked backfill.
Pilot ingest of 3 pages: 127 seen, 49 merged into existing scenes, 66 new,
0 errors; on page one the gate passed 42 of 62 links with zero scenes
missing cast, duration or studio.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>
pornbusy.com exposes every field as a discrete itemprop node (title,
duration, uploadDate, thumbnail, description) plus a dedicated
<div id="video-actors"> cast block with no sidebar pollution. Measured
orphan risk is low: 80% of a 100-scene sample have a performer that
already carries a tpdb/stashdb ref, and 21% of titles strongly match
scenes we already hold. No studio field exists on the site.
Homepage pagination is broken (pages 1/2/3 return an identical set), so
the listing is driven off sitemap_index.xml -> 10 post-sitemaps sorted by
lastmod, chunked in crawl_page the same way the PlayTube base does it.
Playback dispatches on embedURL and covers ~69% of the catalog: the
seekplayer family (already handled by the engine after the earlier host
regex widening) and zpi.cx (the embedURL is the file itself), plus loadvid
at ~41%, which needed new plumbing.
loadvid hands back the CONTENT of an m3u8 over POST /videos/resolve-token
(CSRF + videoToken from the embed page) and has no manifest URL at all:
GET on that endpoint is 405 and the guessable .m3u8 paths are 404. So
make_token grew an optional `producer` marker and /proxy/hls calls the
producer instead of GETting a URL. Segments in the returned manifest are
absolute and fully portable (verified: 206 on a Range request with no
headers, no referer, no token), so the phone still pulls them straight
from the CDN and only the manifest travels through the VPS.
upload18 (~12%) and the tail are deliberately left unresolved: their token
embeds the fetcher's /24, so resolving server-side would force the whole
video through the VPS.
Verified: 19 scenes/page, 19/19 with duration, 17/19 with cast, 19/19 with
tags (names read from the title attribute since an icon element precedes
the anchor text), playback 8/8 via loadvid, and /proxy/hls returning a
116KB manifest with 869 absolute segments. Pilot ingest of 3 pages: 59
seen, 35 merged into existing scenes, 24 new, 0 errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
galaxyporn.net carries paysite rips with a dedicated <div id="video-actors">
cast block (no sidebar pollution), studio + date in the title prefix, healthy
/page/N/ pagination. Measured orphan risk is low: 92% of a 75-performer
sample already have a tpdb/stashdb ref in our DB and 79% of titles match
scenes we already hold.
seekplayer_engine host regex widened to cover seekplays|4meplayer|ezplayer|
seeks|upn and the pro|cloud|one TLDs. This is the same engine (identical
AES key/IV and /api/v1/video endpoint), just newer domains; the whitelist is
additive so existing hosts keep matching (verified, including that
upns.evil.com is still rejected). Unlocks all four galaxyporn player hosts
and the same family on other sites.
Two things the extractor had to get right:
- Call seekplayer_engine directly rather than via extract_stream_from_hoster:
the wrapper verifies the resulting URL and the hotlink-guarded HLS 403s, so
it discarded correctly decoded streams.
- Referer must be the PLAYER origin, not galaxyporn.net. With the site referer
the manifest 403s; with the player origin it returns 200. Verified end to
end: manifest 200 -> variant 200 (570 segments) -> segment 206.
Duration is absent from the HTML, JSON-LD and player payload, and a NULL
duration would silently hide scenes behind the min_duration_sec filter (the
porntrex incident), so it is computed from the player's thumbnail.vtt last
cue. The player API throttles bursts, hence the retry/backoff: that took
missing durations from 9/21 down to 3/21. The value runs ~2% short of the
true length (one thumbnail interval), which beats having none.
Pilot: 21 scenes/page with studio 21/21 and clean cast (max 3), ingest of
2 pages = 42 seen, 34 new, 8 merged, 0 errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
youperv.com (DataLife Engine) carries paysite rips titled
"Studio - Performer - Title" (71% of a 132-title sample), ~60-70 new
scenes/day. Browse the homepage + /page/N/ (19 scenes/page, no overlap);
scene URL is /<category>/<id>-<slug>.html.
Cast is scoped to the fmeta block (up to the Related section): the whole
page carries 19-26 /xfsearch/pornstar/ links but only 1-2 are the actual
cast, so without scoping this would repeat the page-wide pollution that
got xxxfiles rejected. Studio comes from the title prefix, guarded so a
performer name is never mistaken for a studio. Duration, ISO release date,
per-scene tags and thumbnail all come from the same block.
Playback is a plain <source> mp4 (files.klubnichka-hd.com) with no token
or expiry, but the CDN hotlink-guards on Referer: bare Range gets 403,
Range + Referer + browser UA gets 206 cross-IP from the VPS. So the
extractor returns it with referer + mobile_direct_ok and the phone streams
straight from the CDN, no WebView and no proxy. Path is percent-encoded
because the filenames contain spaces.
Deep-crawl capped at 2000 pages: beyond that (<=09.2023) the catalog turns
into generic amateur uploads with no performers and dead CDN files.
Verified: 19 scenes/page with studio+cast+duration+date, max 2 performers
per scene (pollution guard holds), 0/19 missing duration, playback 206
video/mp4. Pilot ingest 3 pages: 57 seen, 39 attached to existing canonical
scenes, 18 new, 0 errors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
hqporner byl TYLKO w ALL_DIRECT_SCRAPERS (search po nazwisku performera), wiec
swieze sceny wchodzily wylacznie gdy worker trafil na pasujacego performera →
0 nowych scen w 7 dni (audit 2026-07-26, user: 'nie widze nowych scen z hqporner'),
mimo ze tube publikuje codziennie.
HQPornerBrowseScraper: listing / + ?p=N (~50 scen/strone), detail /hdporn/<id>-<slug>.
Metadane z detail page: tytul z <title> (Title Case; <h1> jest lowercase), dlugosc z
meta description ('Video duration is 46min 58sec'), performerki z /actress/ (display
name, nie slug), tagi z /category/, miniaturka fastporndelivery + phash (z Refererem,
bo CDN bez niego 403).
external_id identyczny jak w HQPornerScraper.search (hqpornercom:<url>) → obie sciezki
trafiaja w te sama scene zamiast robic duplikat. Tagi jakosciowe (1080p-porn, 4k-porn)
odfiltrowane, bo to atrybut pliku a nie tag tresci.
Zweryfikowane na zywo: 50 scen z page 1, dur 2818s/1138s/1805s, performerzy+tagi+phash.
1) eporner/phone-resolve: gdy strona parsuje sie OK, ale CDN jest nieosiagalny z
sieci usera (audit: siec zglaszajacego nulluje vid-*.eporner.com -> 0.0.0.0, a
www.eporner.com dziala), phone re-resolve zwracal TEN SAM URL, a lancuch fallback
nie ratowal: dla phone-resolved linkow fallbackProxyUrl === url (resolver ustawia
stream_url = direct_url), wiec krok proxy byl no-opem i szlo prosto do WebView =
strona hostera z reklamami ('zaladowala sie reklama zamiast wideo'). Teraz po
nieudanym phone-resolve bierzemy PRAWDZIWE proxy z backendu (VPS pobiera swoim
DNS-em). Tylko na sciezce bledu. Eporner globalnie zdrowy (89-100%, ~100 urzadzen
dziennie), wiec to fix dla userow z blokowanym CDN, nie regresja globalna.
2) porntrex zmienil markup kafelka: class="duration">MM:SS< ->
<div class="durations"><i class="fa fa-clock-o"></i> MM:SS</div>. Stary wzorzec
przestal matchowac -> duration_sec=NULL dla ~95% swiezych scen (6479/6815 w 7 dni),
a mobile domyslnie filtruje min_duration_sec=60, wiec te sceny byly NIEWIDOCZNE
('nie widze nowych scen z porntrex'). Wzorzec obsluguje oba warianty + H:MM:SS.
Zweryfikowane na zywym listingu: 84/85 kafelkow, 20:45 -> 1245s.
Fourth JAV vertical source (origin tube:supjav, gated to JAV tab via JAV_ORIGINS).
Browse: CF-blocks datacenter IPs, so listing goes through the Bright Data ISP proxy
with retry (the proxy rotates IPs and CF only lets some through). Homepage-latest only
(~66 newest); deeper /page/N/ stays CF-403 even via proxy. Metadata parsed from the
listing cards (title, thumbnail, JAV code, year/month) rather than per-post details,
which are flaky and slow through the proxy.
Stream: supjav hides the real hoster behind a per-server data-link (hex). base.js loads
lk1.supremejav.com/supjav.php?l=<data-link>, which reverses the hex string and fetches
?c=<reversed>, 302-ing to the hoster (TV->turbovid, FST->fc2stream, ST->streamtape,
VOE->voe). The extractor reproduces that: fetch detail via proxy, reverse each data-link,
resolve through lk1 (reachable direct from the server), return the hosters as type=hoster
so the phone resolves them (dood/filemoon native, the rest via the WebView fallback on the
residential IP). lk1 needs no proxy; only the detail fetch does.
Backend-only, no mobile change.
Co-Authored-By: Claude Opus 4.8 <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>
JAV is a distinct vertical (user decision): Asian codes/titles that do not dedup
against the western catalog, so they must not flood the main feed.
Backend (scenes.py): JAV_ORIGINS = {tube:javflix, tube:javguru, tube:vjav,
tube:supjav}; list_scenes gains a `jav` param. Default (jav=false) excludes any
scene with a live JAV-origin source; jav=true returns only those. The cached
default-count and _is_pure_default also exclude JAV so the main feed count matches.
JavflixScraper is now registered in ALL_BROWSE_SCRAPERS (scheduled ingest lands in
the JAV section, gated). Scraper hardened: requires a real server button
(class="myLink") so static pages (Terms/FAQ) are skipped, and unescapes HTML
entities in the title.
Mobile: a "JAV" top tab reuses ScenesScreen with { jav: true } (route param ->
listScenes jav=true). The 60s minimum-duration default is disabled in the JAV tab
because javflix does not expose duration (NULL >= 60 would hide the whole section).
Verified on prod: 16 javflix scenes appear only in the JAV feed and are excluded
from the 2.29M main feed; playback resolves to voe/doodstream/emturbovid.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First site of the JAV vertical (user request, separate section). javflix.cc is a
WordPress JAV aggregator, VPS-reachable and server-rendered. Scraper parses itemprop
metadata (title, thumbnail, uploadDate; no duration) and the JAV code (BKD-368 style)
as a tag. Playback: server buttons are <a class="myLink" href="<embed>"> (streamtape,
voe, doodstream, emturbovid) whose href sits in the raw HTML; the generic _embed_iframe
extractor already resolves those via its anchor-hoster pattern, so javflix registers
under sitetag "javflix" with a thin wrapper that drops the players.mp4 placeholder.
Added emturbovid to the anchor-hoster host list.
Verified end-to-end on prod: scrape a listing -> RawScene with metadata + code tag,
resolve -> emturbovid/voe/doodstream hoster sources (all Goon-playable).
NOT registered in ALL_BROWSE_SCRAPERS yet. JAV is a separate vertical (user decision)
that must be gated out of the main scenes feed before ingest so it does not flood the
western catalog. Next: feed gating (exclude JAV origins by default) + a mobile JAV tab
+ on-device playback test, then enable scheduled ingest. jav.guru / vjav / supjav
follow the same pattern.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hqfap was hard-removed 2026-06-25 when its entire CDN library started serving a
fixed /upload/videos/video_down.mp4 "server down" stub for every scene. The site
is back and now serves real video from a new CDN (d*.vstor.top/whlvid/...). Probe
of the live sitemap: 5/6 sampled scenes return a real mp4 (0 stubs), and the CDN
is portable cross-IP (HTTP 206 from a residential IP and from the VPS with the
hqfap referer).
Restores the PlayTube CMS browse scraper (HQFapScraper, sitetag hqfapcom) and the
JSON-LD contentUrl extractor, re-registered in both registries. The extractor now
sets mobile_direct_ok=True (vstor.top is not matched by _TIME_BOUND_CDN_RE, but is
verified portable) so mobile plays direct with zero proxy. The video_down.mp4 stub
guard is kept defensively. 4k69 stays removed (not re-checked).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two bug-report clusters about missing thumbnails:
1. watchporn scenes had no thumbnail on the list, only appearing after opening
SceneDetail (which auto-enriches og:image). Coverage was 1.3% (463/36,915).
The browse scraper never captured a thumbnail. KVS stores the poster at a fixed
derivable path (contents/videos_screenshots/<id//1000*1000>/<id>/preview.jpg,
verified 8/8 loading). Scraper now sets thumbnail_url (og:image, else derived);
backfilled 36,687 existing rows -> 100% coverage.
2. SceneDetail showed no thumb where the list showed one: the mobile detail picks
the first source with a thumbnail_url (origin ASC often puts sxyprncom first),
and sxyprn/trafficdeposit stored thumbs rot to 404. The list already swaps those
for a live resolver (/proxy/sxyprn-thumb/), but the detail builder did not. It
now applies the same live-resolver swap and nulls other rotting thumbs so the
detail lands on a working image.
Both backend-only, no OTA needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
watchporn.to was disabled 2026-05-12 (all iframes were DoodStream/CAPTCHA
-> black-screen WebView). The site has since been rebuilt as a KVS tube:
the DoodStream hosters are gone, scenes now expose flashvars get_file
direct mp4. Rewrote the dead ?s= search scraper as a /latest-updates/
browse scraper (og:title, JSON-LD duration/uploadDate, /models/ performers,
/tags/ tags, /categories/ studio) and added a KVS get_file extractor
(porntrex-style same-session 302 resolve; token not IP-bound, plays from
VPS). Moved to ALL_BROWSE_SCRAPERS, extractor swapped from _embed_iframe.
Verified: 35 fresh scenes/page (today), multi-performer, playback 1080p mp4 206.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Re-check 2026-06-25 across the full id range confirmed both PlayTube tubes
serve only the fixed `/upload/videos/video_down.mp4` "server down" stub, never
a real file: hqfap 0/80 real (79 stub, 1 none), 4k69 0/40 real (38 stub, 2
none). Both were disabled 2026-06-22; CDN never came back, so removing entirely
(mirrors the pornhub/redtube/0dayxx/pornditt/pornhat removals).
Removed the extractor registry entries (hqfapcom, 4k69com) + module files and
the browse scrapers + imports. Prod DB data deleted separately (28,398
solo-orphan scenes + 46,196 playback_sources). `_playtube.py` kept: superporn
and neporn still use its JSON-LD helpers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Browse over /best/<YYYY-MM>/<page> (SSR; xnxx has no clean /new/ and its homepage is
JS-rendered) for a latest-feed freshness signal next to the performer-driven search
scraper. JSON-LD VideoObject only — xnxx detail (unlike its xvideos twin) doesn't
expose /models/ or /tags/ in SSR, so performers/tags come via canonical merge + the
search scraper. Title is html.unescaped (JSON-LD ships ,/! entities).
xhamster and sxyprn intentionally left search-only: xhamster Cloudflare-blocks the
VPS on listing pages (1KB challenge), sxyprn has no clean SSR listing (IP-bound) —
a flaky browse scraper would be worse than the working search + 168h watchdog.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Browse over /browse/time/?page=<n> (SSR) for guaranteed latest-feed freshness next to
the existing performer-driven search scraper. JSON-LD VideoObject only (title /
duration / uploadDate / thumbnail) — deliberately NOT scraping performers/tags from
the detail page: JSON-LD has no actor field and the /pornstar//category links are
sidebar-polluted with no scene-scoped container, so a naive regex attached the same
2 pornstars to every scene. Performers/tags come via canonical merge + the search
scraper instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>