Compare commits
No commits in common. "1441e189c8e155d38ed8569b78e5134df8b1a8a9" and "1e96a6f12d77361c489ed96d717ac5ff8eff874e" have entirely different histories.
1441e189c8
...
1e96a6f12d
1 changed files with 1 additions and 37 deletions
|
|
@ -60,11 +60,6 @@ _BATCH_ID_RE = re.compile(r"^[A-Za-z0-9._-]+$")
|
||||||
_POW_MARKERS = ("startpow", "доступ ограничен: проверка безопасности")
|
_POW_MARKERS = ("startpow", "доступ ограничен: проверка безопасности")
|
||||||
|
|
||||||
|
|
||||||
# Заполняется при входе в Loader.__aenter__ (playwright импортируется лениво,
|
|
||||||
# чтобы --help работал без установленного пакета).
|
|
||||||
PlaywrightTimeoutError: type[BaseException] = TimeoutError
|
|
||||||
|
|
||||||
|
|
||||||
class Blocked(Exception):
|
class Blocked(Exception):
|
||||||
"""Первый признак блока. Ретраев нет — только немедленный стоп."""
|
"""Первый признак блока. Ретраев нет — только немедленный стоп."""
|
||||||
|
|
||||||
|
|
@ -217,10 +212,6 @@ class Loader:
|
||||||
|
|
||||||
async def __aenter__(self) -> "Loader":
|
async def __aenter__(self) -> "Loader":
|
||||||
from playwright.async_api import async_playwright
|
from playwright.async_api import async_playwright
|
||||||
from playwright.async_api import TimeoutError as _PwTimeout
|
|
||||||
|
|
||||||
global PlaywrightTimeoutError
|
|
||||||
PlaywrightTimeoutError = _PwTimeout
|
|
||||||
|
|
||||||
endpoint = os.environ.get("AVITO_CDP", "http://localhost:9222")
|
endpoint = os.environ.get("AVITO_CDP", "http://localhost:9222")
|
||||||
self._pw = await async_playwright().start()
|
self._pw = await async_playwright().start()
|
||||||
|
|
@ -271,7 +262,7 @@ class Loader:
|
||||||
if not self.budget_left():
|
if not self.budget_left():
|
||||||
raise BudgetExhausted()
|
raise BudgetExhausted()
|
||||||
await self._pause()
|
await self._pause()
|
||||||
resp = await self._goto(url)
|
resp = await self._page.goto(url, wait_until="domcontentloaded", timeout=90_000)
|
||||||
self.loads += 1
|
self.loads += 1
|
||||||
self._last_load = time.monotonic()
|
self._last_load = time.monotonic()
|
||||||
status = resp.status if resp is not None else None
|
status = resp.status if resp is not None else None
|
||||||
|
|
@ -283,33 +274,6 @@ class Loader:
|
||||||
_guard(html, status)
|
_guard(html, status)
|
||||||
return html, status
|
return html, status
|
||||||
|
|
||||||
async def _goto(self, url: str, attempts: int = 3):
|
|
||||||
"""goto с ограниченным ретраем на таймаут навигации.
|
|
||||||
|
|
||||||
Авито изредка держит соединение до упора и goto падает по timeout. Это
|
|
||||||
НЕ признак отказа: в наблюдавшемся случае вкладка показывала нормальную
|
|
||||||
выдачу, а маркеров фаервола/PoW не было. Но и молча ретраить бесконечно
|
|
||||||
нельзя — тихий отказ выглядит ровно так же. Поэтому: перед каждым
|
|
||||||
повтором пробуем прочитать то, что в документе, и прогнать через _guard,
|
|
||||||
чтобы настоящий блок остановил прогон с правильной причиной; исчерпали
|
|
||||||
попытки — жёсткий стоп с причиной nav_timeout.
|
|
||||||
"""
|
|
||||||
for i in range(attempts):
|
|
||||||
try:
|
|
||||||
return await self._page.goto(url, wait_until="domcontentloaded",
|
|
||||||
timeout=90_000)
|
|
||||||
except PlaywrightTimeoutError:
|
|
||||||
try:
|
|
||||||
partial = await self._page.content()
|
|
||||||
except Exception: # noqa: BLE001 — документа может не быть вовсе
|
|
||||||
partial = ""
|
|
||||||
if partial:
|
|
||||||
_guard(partial, None) # настоящий блок остановит прогон здесь
|
|
||||||
if i == attempts - 1:
|
|
||||||
raise Blocked("nav_timeout") from None
|
|
||||||
print(f" таймаут навигации, попытка {i + 2}/{attempts}", flush=True)
|
|
||||||
await asyncio.sleep(10.0)
|
|
||||||
|
|
||||||
async def _read_content(self, attempts: int = 4) -> str:
|
async def _read_content(self, attempts: int = 4) -> str:
|
||||||
"""page.content() с узким ретраем на гонку клиентской перенавигации.
|
"""page.content() с узким ретраем на гонку клиентской перенавигации.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue