You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
После мержа PR #19 (issue #11) ни один полный прогон wordstat collect не может завершиться успешно: сбор падает на первом же виде и до dynamics/regions не доходит.
Это блокирует работу по issue #6 (грануляция динамики) — живую проверку дневного/недельного экспорта провести нечем.
Что происходит
_is_untrustworthy_empty_export (collector.py:57) объявляет пустой экспорт недоверенным для трёх видов:
top_popular идёт первым в VIEW_SELECTORS и у Вордстата пуст всегда — это доказанное свойство платформы, а не наш дефект: в issue #11 пустой CSV получен ручным кликом по ссылке выгрузки, мимо нашего кода. Значит первый же вид всегда кидает InterfaceChangedError, и прогон обрывается.
То есть fail-closed, введённый чтобы не выдавать пустые данные за успех, превратился в «инструмент не работает вообще».
Почему включение DYNAMICS в это правило неверно
Рассуждение в докстринге (collector.py:88) выглядит стройным, но опирается на посылку, которую issue #11 опровергает:
A phrase that clears the pre-download gate has already had the code itself prove TABLE_ROW_SELECTOR.length > 0 moments earlier ... there is no code path left where that emptiness is legitimate
Такой путь есть, и он наблюдался: DOM показывает строки, а Вордстат отдаёт пустой файл. Ровно это и есть issue #11. Из «DOM доказал строки до клика» не следует «экспорт не может быть пустым» — доказано обратное, живым замером.
Поэтому «единообразие» здесь ошибочно: предикат унифицирован по структурному признаку (есть ли таблица в DOM), тогда как реальное различие между видами — отдаёт ли Вордстат для них непустой файл. Для top_popular/top_related не отдаёт никогда, для dynamics отдаёт стабильно (24 строки в трёх прогонах issue #11, плюс замеры в PR #20).
Регрессия по сравнению с тем, что решала issue #11
PR #19 в исходном виде проверял ещё и rendered_rows > 0 — то есть отказывал только когда файл пуст, а страница показывала строки. Это отличало аномалию от честного пустого отчёта. Сейчас эта проверка убрана, и предикат срабатывает на любой пустоте.
Мотивировка снятия (докстринг, collector.py:78) — что повторное чтение DOM после скачивания ненадёжно — сама по себе разумна. Но вместе с ней потеряна способность отличать «Вордстат дал пустое при непустой странице» от «данных действительно нет», а именно это различие и было содержанием issue #11.
Конкретный механизм — на усмотрение исполнителя. Возможные направления: не обрывать прогон, а помечать вид как несобранный и продолжать со следующего (у нас уже есть missing_views/incomplete из issue Устойчивость к сбою на середине прогона: инкрементальный манифест и дозапись #2); либо вернуть различение аномалии и честной пустоты; либо развести правила по видам явно, с опорой на замеренное поведение, а не на структурное сходство.
После мержа PR #19 (issue #11) ни один полный прогон
wordstat collectне может завершиться успешно: сбор падает на первом же виде и доdynamics/regionsне доходит.Это блокирует работу по issue #6 (грануляция динамики) — живую проверку дневного/недельного экспорта провести нечем.
Что происходит
_is_untrustworthy_empty_export(collector.py:57) объявляет пустой экспорт недоверенным для трёх видов:top_popularидёт первым вVIEW_SELECTORSи у Вордстата пуст всегда — это доказанное свойство платформы, а не наш дефект: в issue #11 пустой CSV получен ручным кликом по ссылке выгрузки, мимо нашего кода. Значит первый же вид всегда кидаетInterfaceChangedError, и прогон обрывается.То есть fail-closed, введённый чтобы не выдавать пустые данные за успех, превратился в «инструмент не работает вообще».
Почему включение DYNAMICS в это правило неверно
Рассуждение в докстринге (
collector.py:88) выглядит стройным, но опирается на посылку, которую issue #11 опровергает:Такой путь есть, и он наблюдался: DOM показывает строки, а Вордстат отдаёт пустой файл. Ровно это и есть issue #11. Из «DOM доказал строки до клика» не следует «экспорт не может быть пустым» — доказано обратное, живым замером.
Поэтому «единообразие» здесь ошибочно: предикат унифицирован по структурному признаку (есть ли таблица в DOM), тогда как реальное различие между видами — отдаёт ли Вордстат для них непустой файл. Для
top_popular/top_relatedне отдаёт никогда, дляdynamicsотдаёт стабильно (24 строки в трёх прогонах issue #11, плюс замеры в PR #20).Регрессия по сравнению с тем, что решала issue #11
PR #19 в исходном виде проверял ещё и
rendered_rows > 0— то есть отказывал только когда файл пуст, а страница показывала строки. Это отличало аномалию от честного пустого отчёта. Сейчас эта проверка убрана, и предикат срабатывает на любой пустоте.Мотивировка снятия (докстринг,
collector.py:78) — что повторное чтение DOM после скачивания ненадёжно — сама по себе разумна. Но вместе с ней потеряна способность отличать «Вордстат дал пустое при непустой странице» от «данных действительно нет», а именно это различие и было содержанием issue #11.Что нужно
top_popular/top_relatedпусты по вине платформы: пустота этих двух видов — известное состояние (issue top_popular/top_related возвращают 0 строк данных при --keep-raw, хотя интерфейс показывает данные #11), а не повод обрывать сбор остальных.dynamicsпри этом не должен молча проезжать как успех — issue status=complete при нулевом row_count — манифест не отражает фактическую пустоту представлений #16 про то, чтоstatus: completeпри нулевых данных недопустим, остаётся в силе.missing_views/incompleteиз issue Устойчивость к сбою на середине прогона: инкрементальный манифест и дозапись #2); либо вернуть различение аномалии и честной пустоты; либо развести правила по видам явно, с опорой на замеренное поведение, а не на структурное сходство.Проверка
collector.pyюнит-тестами не покрывается by design. Обязателен живой прогон (CDPhttp://127.0.0.1:9223, авторизация пройдена):wordstat collectна обычной фразе доходит до конца и пишетdynamicsиregions;top_popular/top_relatedпри этом видны вmanifest.json, а не выданы за успех;--granularity daily(после мержа Грануляция динамики: сбор по дням / неделям / месяцам #6) собирает динамику.