Москва: пред-геокод Авито, Яндекс третьей площадкой, продукт отвечает по региону 77 #3440
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3440
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/msk-collector-cian"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что и зачем
Ветка закрывает наполнение Москвы: сырьё двух площадок доезжает до
listings, продукт начинает отвечать по региону 77, и добавляется третья площадка сбора.Пред-геокод Авито
У московских карточек Авито нет координат ни у одной из 50 335, адрес — голая улица с домом («Варшавское ш.,62к1»). Сбор шёл по
/moskva_i_mo/, поэтому Москву от области отделить было нечем: префиксный фильтр по округу, работающий у Циана, здесь отбросил бы 100% строк. Прямой матч кhouses(77)даёт ровно 0 совпадений.Одного геокода мало: с констрейнтом «Москва + Московская» дом находится у 92% адресов, но верхний кандидат DaData расходится с реальным городом у 15% и почти всегда в пользу столицы. Недостающий сигнал нашёлся бесплатно — слаг города в
source_url, заполнен у 100% карточек. Город берётся из слага и сужает констрейнт, регион — из КЛАДР ответа, не из слага: Новая Москва идёт своими слагами, но это регион 77.Прогон на проде 11.09: прочитано 50 335, записано 26 687, область(50) 18 043 отложена в кэш, не разрешено 5 505 (10.9%), геокод-вызовов 24 279, счётчики сходятся. В
listingsavito/77 geom у 100%,house_id_fkу 99.1%.Яндекс как третья площадка
rgid Москвы 587795 установлен эмпирически и подтверждён счётчиком gate-API: вторичка 18 705 против 4 060 у ЕКБ. Адаптер не тащит DOM-парсер — источник отдаёт JSON через gate-API. Потолок пагинации у Яндекса 500 офферов на набор фильтров, втрое ниже соседей, поэтому
--target-countстал платформо-зависимым.offerId19-значный, добавлен отсев за пределами signed bigint. Пробный прогон 100 загрузок: 0 признаков блока, координаты и адрес у 100% карточек.Починка сухого прогона
Кэш
msk_raw.avito_geocodeсоздавался только боевым прогоном, а читался безусловно —--dry-runпадал на проде с UndefinedTable, то есть ломалась ровно та репетиция, ради которой сухой прогон существует. Наличие отношения проверяется черезto_regclass, а не ловится исключением: упавший оператор в Postgres кладёт транзакцию целиком.Проверено
uv run python -m pytest tests/test_msk_raw_import.py— 37 passeduv run ruff check .— All checks passedЗамечание по деплою
Прод сейчас работает на файлах, скопированных в контейнер руками (
docker cpвtradein-backend), потому что импорт надо было запустить до мержа. После деплоя этого PR контейнер должен пересоздаться и подобрать код из образа.🤖 Generated with Claude Code
https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh
Сборщик получает ключ --platform {avito,cian}: платформо-зависимые куски (URL коридора, счётчик, парс, потолок пагинации, целевая таблица) вынесены в PlatformAdapter, общая часть — бисекция по цене, guard на блок, накопитель и заливка — одна на обе площадки. Скоуп Циан проверен живыми запросами 10.09, а не взят из документации: - region=1 и region=4593 двумя параметрами НЕ объединяются, сервер берёт последний. Прежний базовый URL собрал бы одну Московскую область и молча потерял Москву целиком (92 817 объявлений). Правильный скоуп — region=-1. - object_type[0]=1 обязателен: без него счётчик считает новостройки, которые дальше не сохраняются, и расходится с числом карточек вдвое. - Итоговый скоуп: 62 548 объявлений вторички по Москве и МО. - Потолок пагинации 54 страницы подтверждён: страница 55 пуста. Фильтра новостроек в адаптере нет, и это сознательное отличие от кита. Кит считает новостройкой всё, у чего есть offer.newbuilding.id (serp.py:401-402), потому что для ЕКБ выдача бралась без object_type. На московской странице из 28 карточек 16 имеют этот блок, и у всех шестнадцати isFromBuilder=false, isFromLeadFactory=false — это вторичка в ЖК, а не лоты застройщика. С китовым фильтром прогон терял бы 57 % корпуса безвозвратно. msk_raw — сырьё, payload несёт listing_segment целиком, сегмент отделяется на импорте в listings. Детект блока Циан. Капча приходит как HTTP 200 с обычной на вид страницей: поймана живьём, 40 КБ, title «Captcha - база объявлений ЦИАН», без window._cianConfig. По статусу её не отличить, поэтому маркер ищется в первых 4 КБ (в нормальной выдаче на 2,6 МБ там ни одного вхождения). Вторая сеть в parse_page: счётчик None при нуле сырых карточек — тоже стоп. Без этого блок засчитывался бы как пустая страница, коридор уходил в done, а --resume его уже не перебрал бы. Гвард empty_page считает карточки ДО фильтра: иначе штатный ноль после фильтрации был бы неотличим от блока. У Авито атрибута нет, дефолт — длина итогового списка, поведение прежнее. Заливка. Целевая таблица берётся из адаптера, staging создаётся с INCLUDING IDENTITY (без него identity-колонка не переносится, а NOT NULL переносится всегда, и \copy падал бы на каждом батче). Наличие таблицы проверяется на старте одним SELECT to_regclass — иначе прогон умирал бы на первой заливке, после часов планирования. Миграция 299 заводит cian_cards, domclick_cards, yandex_cards и три вью по образцу avito_cards/avito_latest. id — bigserial, а не IDENTITY, ровно по причине выше. Заодно: _wt-mskcol/ выведен из индекса и закрыт в .gitignore. Копия-worktree попала в репозиторий 09.09, и три фикса ушли в дубликат мимо канонического collect.py — дефект нашёлся только при сверке размера страницы. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VQ8jqr4SFirX5tFLwdSrXh