fix(vjav): 429 parsowany jako XML, zrodlo stalo 12 dni bez zadnego bledu
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>
This commit is contained in:
parent
3f8f38202a
commit
532c7e2bb4
1 changed files with 36 additions and 4 deletions
|
|
@ -31,6 +31,7 @@ from app.connectors.base import (
|
|||
RawStudio,
|
||||
RawTag,
|
||||
)
|
||||
from app.config import get_settings
|
||||
from app.connectors.direct_scrapers._browse_base import BaseBrowseScraper
|
||||
from app.extractors import browser_get
|
||||
from app.normalize.text import slugify
|
||||
|
|
@ -74,21 +75,45 @@ class VjavScraper(BaseBrowseScraper):
|
|||
super().__init__(*args, **kwargs)
|
||||
# Cache id-ów wideo (posortowane malejąco = newest first), per instancja/run.
|
||||
self._sorted_ids: list[int] | None = None
|
||||
# vjav odciął IP VPS-a: 2026-08-03 KAŻDA ścieżka (sitemap, strona główna,
|
||||
# /latest-updates/) oddawała 429 przy trzech próbach z rzędu, a przez proxy
|
||||
# 200 od pierwszej. Źródło stało 12 dni. Bright Data jest tu więc warunkiem
|
||||
# działania, nie optymalizacją — bez klucza scraper się wyłącza.
|
||||
self._proxy = get_settings().brightdata_proxy_url
|
||||
if not self._proxy:
|
||||
log.warning("vjav: BRAK BRIGHTDATA_PROXY_URL — vjav blokuje IP VPS-a (429)")
|
||||
|
||||
# ---- browse: sitemap id-walk ------------------------------------------------
|
||||
def _load_ids(self) -> None:
|
||||
"""`self._sorted_ids = []` znaczy „katalog pusty", a to woła `crawl_page` do
|
||||
zwrócenia [], czyli „koniec katalogu". Dlatego błąd pobrania NIE MOŻE tu
|
||||
ustawiać []: przy 429 scraper raportował 0 scen i 0 błędów, więc przez 12 dni
|
||||
wyglądał na zdrowy. Zostawiamy None = „nie wiadomo", co crawl_page tłumaczy na
|
||||
transient-fail. Status sprawdzamy jawnie, bo `browser_get` nie rzuca na 4xx —
|
||||
i to właśnie przez to treść błędu 429 była parsowana jako XML."""
|
||||
try:
|
||||
res = browser_get(_SITEMAP_INDEX, timeout=self._timeout)
|
||||
res = browser_get(_SITEMAP_INDEX, timeout=self._timeout, proxy=self._proxy)
|
||||
if getattr(res, "status_code", 200) >= 400:
|
||||
log.warning("vjav: sitemap index HTTP %s — przerywam", res.status_code)
|
||||
self._sorted_ids = None
|
||||
return
|
||||
idx = res.text if hasattr(res, "text") else res
|
||||
except Exception as e:
|
||||
log.warning("vjav: sitemap index fetch fail: %s", e)
|
||||
self._sorted_ids = []
|
||||
self._sorted_ids = None
|
||||
return
|
||||
maps = list(dict.fromkeys(_SITEMAP_RE.findall(idx)))
|
||||
if not maps:
|
||||
log.warning("vjav: sitemap index bez sitemap wideo (%d B) — przerywam", len(idx))
|
||||
self._sorted_ids = None
|
||||
return
|
||||
ids: set[int] = set()
|
||||
for sm in maps:
|
||||
try:
|
||||
res = browser_get(sm, timeout=self._timeout)
|
||||
res = browser_get(sm, timeout=self._timeout, proxy=self._proxy)
|
||||
if getattr(res, "status_code", 200) >= 400:
|
||||
log.info("vjav: sitemap %s HTTP %s", sm, res.status_code)
|
||||
continue
|
||||
body = res.text if hasattr(res, "text") else res
|
||||
except Exception as e:
|
||||
log.info("vjav: sitemap %s fetch fail: %s", sm, e)
|
||||
|
|
@ -177,7 +202,14 @@ class VjavScraper(BaseBrowseScraper):
|
|||
out: list[RawScene] = []
|
||||
for vid in chunk:
|
||||
try:
|
||||
res = browser_get(self._meta_url(vid), timeout=self._timeout, headers={"Referer": _BASE + "/"})
|
||||
# Proxy także tutaj — API metadanych siedzi na tym samym hoście, więc
|
||||
# obejmuje je ten sam 429 co sitemap.
|
||||
res = browser_get(
|
||||
self._meta_url(vid),
|
||||
timeout=self._timeout,
|
||||
headers={"Referer": _BASE + "/"},
|
||||
proxy=self._proxy,
|
||||
)
|
||||
body = res.text if hasattr(res, "text") else res
|
||||
v = json.loads(body).get("video")
|
||||
except Exception as e:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue