From 3daf09c7e4cfce178cbbca1d1fe55712491401e0 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Tue, 8 Sep 2026 23:44:09 +0300 Subject: [PATCH] =?UTF-8?q?fix(msk-collector):=20=D1=83=D0=B7=D0=BA=D0=B8?= =?UTF-8?q?=D0=B9=20=D1=80=D0=B5=D1=82=D1=80=D0=B0=D0=B9=20page.content()?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=B3=D0=BE=D0=BD=D0=BA=D0=B5=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Авито дорисовывает выдачу после domcontentloaded, и content() иногда попадает ровно в смену документа — Playwright бросает "page is navigating and changing the content". Это не отказ площадки, но прогон падал целиком: на 1110-й карточке потеряно 100 несброшенных строк. Ретрай узкий — только на этот текст ошибки и только 4 попытки; любая другая ошибка поднимается как есть, гварды блокировки не ослаблены. runs/ (планы и CSV прогонов) в .gitignore. --- .../scripts/local-avito-msk/.gitignore | 1 + .../scripts/local-avito-msk/collect.py | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tradein-mvp/scripts/local-avito-msk/.gitignore diff --git a/tradein-mvp/scripts/local-avito-msk/.gitignore b/tradein-mvp/scripts/local-avito-msk/.gitignore new file mode 100644 index 00000000..a1e03960 --- /dev/null +++ b/tradein-mvp/scripts/local-avito-msk/.gitignore @@ -0,0 +1 @@ +runs/ diff --git a/tradein-mvp/scripts/local-avito-msk/collect.py b/tradein-mvp/scripts/local-avito-msk/collect.py index 8df91f48..7a2ff186 100644 --- a/tradein-mvp/scripts/local-avito-msk/collect.py +++ b/tradein-mvp/scripts/local-avito-msk/collect.py @@ -270,10 +270,32 @@ class Loader: await self._page.wait_for_selector('[data-marker="item"]', timeout=7_000) except Exception: # noqa: BLE001 — пустая/блочная страница разбирается ниже pass - html = await self._page.content() + html = await self._read_content() _guard(html, status) return html, status + async def _read_content(self, attempts: int = 4) -> str: + """page.content() с узким ретраем на гонку клиентской перенавигации. + + Авито дорисовывает выдачу после domcontentloaded, и content() иногда + попадает ровно в момент смены документа: "Unable to retrieve content + because the page is navigating and changing the content". Это НЕ отказ + площадки — гвардов не касается, поэтому ретраим только эту ошибку и + только её, а любую другую поднимаем как есть. + """ + last: Exception | None = None + for i in range(attempts): + try: + return await self._page.content() + except Exception as exc: # noqa: BLE001 — сузили проверкой текста ниже + if "page is navigating" not in str(exc): + raise + last = exc + print(f" content() поймал перенавигацию, попытка {i + 2}/{attempts}", + flush=True) + await asyncio.sleep(1.5) + raise RuntimeError(f"page.content() не отдал документ за {attempts} попыток") from last + # --- заливка в msk_raw -----------------------------------------------------