10 KiB
Build174 — парсеры новой разметки КХЛ
Версия приложения: 2026.09.29.11. Установка поверх build173. Архив содержит только 7 изменённых/новых рабочих файлов и эту инструкцию.
Установка
- Остановить приложение и сделать резервную копию заменяемых файлов и БД.
- Распаковать архив в корень проекта с сохранением каталогов.
- Перезапустить приложение, обновить браузер через Ctrl+F5.
- Во вкладке «КХЛ сайт» запустить нужное обновление либо дождаться планового запуска в 03:00 МСК.
- Проверить «Отчёт обновлений»: состояние списков и импорта в общую БД.
Файлы .env, пользовательские настройки, settings/local, существующие JSON-архивы КХЛ и база в архив не включены. Ночной режим, число потоков и очередь повторов из build172/173 сохраняются. Код оптимизации live-матча из build173 не изменяется.
Что изменено
- Профили читаются из нового блока personality-resume: имя, амплуа, номер, дата рождения, возраст, рост, вес, хват, гражданство, сборная, клуб, тип и срок контракта. Неизвестные дополнительные поля карточки сохраняются отдельно.
- Фотография выбирается из персонального блока. Локальные пути *_files из сохранённых HTML не выдаются за сетевые картинки; при отсутствии исходного URL показывается заглушка.
- Коллектор следует по ссылке /stats/ из карточки. Следующие обновления уже известной новой карточки запрашивают эту страницу напрямую: повторно загружать страницу «Об игроке» не нужно.
- Таблицы учитывают rowspan/colspan, многоуровневые заголовки и клубы, заданные только alt логотипа. Тексты подсказок не склеиваются с сокращениями показателей.
- У игроков раздельно сохраняются сезоны/клубы, регулярный чемпионат, плей-офф и точные итоговые строки КХЛ. Время показывается как минуты:секунды; сезоны сортируются по сезону, а не по техническому ID строки.
- У тренеров и судей сохраняются отдельные значения всего/хозяева/гости. Во вкладке есть переключатель и раскрываемые исходные таблицы со всеми колонками.
- Матчи, присутствующие в полученном HTML, сохраняются с датой, годом, турниром, командами, счётом и всеми статистическими колонками. Год берётся из раздела таблицы, а не из текущей даты.
- В JSON-поле существующей таблицы khl_career_records хранится полный разобранный архив персоны и метаданные сезонов, наряду с прежней сводной статистикой. SQL-миграция не нужна. Первый импорт этой версии пересохранит записи в расширенном формате; последующие импорты неизменённых источников пропускаются.
- Новая сохранённая карточка открывается из локальных данных. Просмотр не запускает отдельное обращение к КХЛ за её анкетой или уже сохранёнными матчами.
- Ошибка страницы статистики не обнуляет прежнюю карточку: она остаётся в архиве и попадает в очередь повторов.
Существенное ограничение: API и полнота каталогов/матчей
В присланных HTML найдены:
- адрес https://api-video.khl.ru/api/khl_site/ в конфигурации KHLActionsClass;
- data-idtype players/list, players/detail/profile, players/detail/stats, players/detail/matches;
- соответствующие разделы coaches и referees;
- вызовы EntitiesPage и initPersonStatisticsPageMatches;
- кнопки страниц data-page, у которых нет href.
Это признаки динамической загрузки. Формат запросов, параметры пагинации и формат ответов находятся во внешних JS, а не в присланном HTML. Их содержимого в приложениях нет. При проверке из среды разработки www.khl.ru ответил 403; отдельный API проверить не удалось. Непроверенные API-запросы в код не добавлены.
Поэтому build174 НЕ гарантирует обнаружение всех новых ID из нового каталога и НЕ загружает автоматически полную историю матчей через его JavaScript/API. Доступные HTML-таблицы читаются; известные ранее карточки обновляются.
При новой пагинации коллектор читает доступную первую страницу каталога, добавляет все ранее известные ID из сохранённого архива (для полного, не «текущего», обновления) и отмечает каталог как незавершённый в отчёте и очереди повторов. Старая неподдерживаемая пагинация PAGEN_1 не считается успешным обходом нового каталога.
Матчи показываются как «Сохранённые матчи» с предупреждением о неполной истории. Если сервер отдал /stats/ без динамической таблицы матчей, прежние сохранённые матчи остаются; при их отсутствии интерфейс сообщает, что таблица не загружена. Отсутствие таблицы не выдаётся за отсутствие сыгранных матчей.
Для завершения автоматического обхода и проверки JSON/API нужны внешние файлы из каталогов *_files, создаваемых браузером при сохранении страницы «Веб-страница полностью»:
- Api.js
- Actions_new.js
- entities-page.js
- pagination.js
- table-pagintaion.js (на сайте имя написано именно так)
- statisticsPersons.js
- persons.detail.js
Можно прислать одним ZIP каталоги *_files от списка игроков и страницы статистики с открытыми матчами. Варианты имён с суффиксом «.Без названия» подходят. Данных аккаунта или cookies для анализа этих JS не требуется.
Проверка
76 автоматических проверок прошли: новые парсеры на всех 11 приложениях, цепочка карточка → /stats/, сохранение всех данных в тестовой SQLite-базе, локальные API, повтор неудачной загрузки, сохранность прежних архивов; регрессии ночного обновления и оптимизации live-матча. Две устаревшие текстовые проверки, уже не соответствовавшие build173 (три потока и старое расположение вкладки), исключены.
Контрольные результаты приложений:
- Абрамов: 11 строк по сезонам/этапам/клубам, 6 сезонов; итого 333 игры, 75 шайб, 71 передача, 146 очков. В HTML с открытыми матчами — 20 строк.
- Андриевский: 15 строк статистики, 3 итоговые строки; всего 442 игры.
- Акузовский: 21 строка статистики, 3 итоговые строки; всего 480 игр; 20 загруженных матчей в каждом из двух примеров статистики.
- В каждом приложенном каталоге содержится 20 карточек; наличие кнопок следующих страниц подтверждает неполноту одного HTML.
Браузерная проверка: профили, сезонная статистика, матчи, переключение всего/хозяева/гости, полные таблицы и ширины 1440/1024 px; ошибок JavaScript нет. Проверка выполнялась на ваших файлах с подменёнными HTTP-ответами; действующая БД и сервер пользователя не использовались.
Рабочие файлы
- app.py
- hockey_data/khl_career.py
- khl_site/modern_html.py (новый)
- khl_site/khl_site_collector.py
- khl_site/khl_data_center.py
- khl_site/person_data.py
- khl_site/web/index.html