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>
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
|