4k69.com (~65k scenes): same PlayTube CMS as hqfap - common logic moved to _playtube.py (sitemap catalog, JSON-LD, pills). Studio classified by matching category pills against the studios index page. Streams are get_file (fullmovies family) returned unresolved with mobile_direct, 2160p skipped. neporn.com: KVS engine, latest-updates listing, JSON-LD + video:duration meta, performers from models links with flashvars video_tags fallback for fresh uploads. Resolve via _kvs; final URL portable cross-IP. superporn.com rejected: Cloudflare 403 from VPS on all TLS impersonations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
26 lines
1 KiB
Python
26 lines
1 KiB
Python
"""hqfap.com — latest-vids browse scraper (PlayTube CMS, patrz _playtube.py).
|
|
|
|
Dołączony 2026-06-10 (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 (cdnde.com nowsze / 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
|