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>
28 lines
1.2 KiB
Python
28 lines
1.2 KiB
Python
"""hqfap.com, latest-vids browse scraper (PlayTube CMS, patrz _playtube.py).
|
|
|
|
Dołączony 2026-06-10 (user request), usunięty 2026-06-25 (cała biblioteka CDN padła
|
|
na stub), przywrócony 2026-07-07 (strona wróciła na CDN vstor.top z realnymi plikami,
|
|
user request). Re-uploader katalogu pornhd.pet (~120k scen, thumbnaile to base64-encoded
|
|
oryginalne URL-e w `/uploads/images/`).
|
|
|
|
Specyfika vs baza: studio siedzi w kategoriach z suffixem " Clips"
|
|
("Filthy Kings Clips" → studio "Filthy Kings"); reszta kategorii → tagi.
|
|
Playback: direct mp4 z JSON-LD contentUrl (vstor.top obecnie, cdnde.com/okcdn.ru
|
|
starsze), tokeny time-bound i portable cross-IP → natywny extractor `hqfapcom`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from app.connectors.direct_scrapers._playtube import BasePlayTubeScraper
|
|
|
|
|
|
class HQFapScraper(BasePlayTubeScraper):
|
|
sitetag = "hqfapcom"
|
|
base_url = "https://hqfap.com"
|
|
|
|
def _pick_studio(self, category_names: list[str]) -> str | None:
|
|
for name in category_names:
|
|
if name.lower().endswith(" clips"):
|
|
studio_name = name[: -len(" clips")].strip()
|
|
if studio_name:
|
|
return studio_name
|
|
return None
|