Подписывайтесь:

Блог AST-SoftPro

Как мы строим автоматический мониторинг судебных дел: проект CourtWatcher

20.08.2026 18 мин чтения
Как мы строим автоматический мониторинг судебных дел: проект CourtWatcher

Введение

Каждый юрист, работающий с судебными спорами, знает эту рутину: открыть портал суда, вбить номер дела или фамилию стороны, дождаться загрузки страницы и вручную сверить, что изменилось. Если дел много — это часы каждый день, а пропущенное заседание или новая дата разбирательства могут стоить клиенту денег и репутации компании.

В этой статье я расскажу о проекте CourtWatcher — внутреннем сервисе мониторинга судебных дел, который мы разрабатываем для реального заказчика из юридической сферы. Мы покажем, как устроен парсинг открытых порталов судов Москвы, почему «наивный» скрейпинг быстро ломается и что нужно учесть при проектировании подобной системы. Статья не будет учебником по копированию кода — фокус на архитектурных решениях, типичных ловушках и планах развития сервиса в мультипользовательский продукт с уведомлениями и ботами.

Зачем нужен автоматический мониторинг судебных дел

Ручное отслеживание дел имеет несколько системных проблем:

  1. Повторяемость. Один и тот же поиск выполняется десятки раз в день по каждому делу.

  2. Человеческий фактор. Легко пропустить новую строку в истории состояний или перепутать дату заседания.

  3. Масштабируемость. Юридическая служба, ведущая 50–500 дел, физически не может проверять каждое вручную несколько раз в сутки.

  4. Скорость реакции. Уведомление о новом заседании или изменении статуса должно прийти до того, как наступит дедлайн.

Автоматизация решает все четыре пункта: планировщик сам обходит порталы по заданным запросам, сохраняет изменения в базу данных и может уведомлять ответственных людей. Для бизнеса это прямая экономия рабочего времени юристов и снижение рисков пропустить важный процессуальный срок.

💡 При оценке целесообразности автоматизации стоит прикинуть простой показатель: сколько часов в неделю команда тратит на ручную проверку порталов × средняя стоимость часа юриста. Обычно окупаемость такого сервиса наступает в течение первых месяцев работы.

Общая архитектура CourtWatcher

Проект построен по классической трёхслойной схеме, которая хорошо масштабируется и упрощает поддержку:

Слой 1 — Парсер. Отдельный модуль знает про каждый портал (его URL, структуру HTML, особенности поиска) и умеет возвращать нормализованные данные: номер дела, стороны, суд, заседания, историю состояний. Парсер не знает о базе данных и не общается с пользователем.

Слой 2 — Хранилище. SQLite в режиме WAL + SQLAlchemy (асинхронный). Четыре основные сущности: дело, заседание, аудит-журнал изменений и журнал запусков парсера. Все изменения записываются транзакционно, что позволяет отследить историю по каждому полю дела.

Слой 3 — Веб-слой. FastAPI-приложение с двумя API: внутренним (для SPA-интерфейса) и внешним /v1 (для интеграции с другими системами заказчика). Интерфейс — одностраничное приложение на ванильном JavaScript с роутингом по hash, без тяжёлых фреймворков.

Дополнительно внутри процесса работает планировщик задач (APScheduler), который по заданному интервалу запускает парсинг для каждого источника. Всё это упаковано в Docker-контейнер и разворачивается на сервере заказчика.

Почему такой стек? Python + FastAPI — быстрый путь к REST API с асинхронностью «из коробки», SQLite достаточно для одного процесса и десятков тысяч записей, а отсутствие фронтенд-фреймворка упрощает сборку и деплой. Для сервисов такого масштаба избыточная абстракция только замедляет разработку.

Как устроен парсинг порталов судов Москвы

Сервис работает с двумя порталами: mos-gorsud.ru (районные суды и Московский городской суд) и mos-sud.ru (мировые судьи). У каждого — своя структура выдачи и свои особенности, поэтому в проекте два независимых парсера.

Поиск дел

На mos-gorsud.ru поиск ведётся по HTML-странице с параметрами запроса и пагинации. Важная особенность: портал отдаёт дела отсортированными по номеру, то есть самые свежие — сверху. Это позволяет обходить страницы по 500 записей и останавливаться, когда собрано нужное количество релевантных дел.

Но есть нюанс: свежие дела первой инстанции не всегда видны в общей выдаче по запросу «наименование участника». Поэтому парсер дополнительно проходит по списку районных судов с фильтром по конкретному суду. Дедупликация выполняется по URL-ключу дела, а не по номеру — номера могут совпадать между разными судами.

На mos-sud.ru механизм проще: поиск по участнику с пагинацией по ~15 дел на страницу. Но карточки здесь требуют заголовок Referer со страницы поиска, иначе портал отвечает 403. Такие мелочи обнаруживаются только при живой отладке и не описаны ни в одном публичном руководстве.

Загрузка карточек дела

После сбора списка парсер загружает карточки дел параллельно (ограниченная конкурентность, по умолчанию 5 одновременных запросов). Из карточки извлекаются: стороны с ролями, судья, категория дела, дата поступления, текущее состояние, таблица «История состояний» и таблица «Судебные заседания».

Разбор выполняется через BeautifulSoup4. Ключевые блоки определяются по CSS-классам и текстовым подписям («Стороны», «Судья», «История состояний»). Если вёрстка изменилась — парсер пишет предупреждение в лог, а не падает. Это важно: сервис должен пережить редизайн портала и продолжить работу с деградацией, а не остановиться полностью.

⚠️ Главный риск любого HTML-парсера — привязка к конкретной разметке. При проектировании стоит заложить мониторинг качества разбора (например, доля карточек, из которых удалось извлечь хотя бы стороны и заседания) и алерты при её падении.

Борьба с rate-limit

Порталы судов чувствительны к частоте запросов: слишком активный клиент получает HTTP 202 (soft-лимит), 429 или таймауты. В CourtWatcher это решается на нескольких уровнях:

  • Таймауты и ретраи. Каждый запрос имеет ограниченный таймаут; при «мягких» ошибках выполняется до трёх повторных попыток с нарастающей паузой.

  • Паузы между страницами. Отдельные настройки для обхода выдачи и для прохода по судам — разные режимы требуют разных интервалов.

  • Ограниченная параллельность карточек. Число одновременных запросов к карточкам настраивается; при частых 429 его снижают до 2–3.

  • Все значения вынесены в настройки, которые можно менять из админки без перезапуска сервиса. Это критично: после деплоя часто приходится «подкручивать» режим под текущую отзывчивость порталов.

💡 Если строить подобный сервис с нуля, заложите с первого дня механизм адаптивной нагрузки: фиксированный интервал между запросами + экспоненциальная пауза при ошибках + возможность динамической настройки из админки. Это сэкономит недели ручной отладки на проде.

Хранение данных и отслеживание изменений

База данных проектировалась вокруг принципа «всё, что меняется, — фиксируется». Четыре основные сущности:

Сущность Назначение
Дело Номер, источник, суд, судья, статус, стадия, категория, стороны (JSON), URL, дата регистрации
Заседание Привязка к делу: дата-время, зал, тип/стадия, результат
Аудит История изменений полей дела: кто/когда/что изменилось
Журнал запусков Каждый цикл парсера: время, источник, запрос, сколько найдено/добавлено/обновлено, успех или ошибка

Сопоставление найденных дел с базой выполняется по URL-ключу. Новое дело — вставка; существующее — обновление изменённых полей и синхронизация списка заседаний (новые заседания добавляются, существующие обновляются). Аудит-журнал позволяет ответить на вопрос «когда именно судья назначил новое заседание» без перебора логов.

SQLite выбран сознательно: один процесс, одна машина, десятки тысяч записей — это его комфортная зона. Режим WAL даёт читаемость во время записи, что важно при одновременной работе парсера и веб-интерфейса. При росте нагрузки (мультипользовательский режим) база легко мигрируется на PostgreSQL без переписывания модели данных.

Веб-интерфейс и API

Интерфейс разделён на шесть экранов: дашборд со статистикой, журнал дел с фильтрами, поиск по порталу с возможностью «найти и сохранить», карточка дела, диагностика (логи парсера) и админка настроек. Всё это — SPA без серверного рендеринга; данные приходят через внутреннее REST API.

Внешний API /v1 защищён ключом и предназначен для интеграции с другими системами заказчика: CRM, внутренние сервисы, боты. Он отдаёт дела, заседания, суды и позволяет выполнять поиск и импорт. Разделение внутреннего и внешнего API — осознанное решение: внешнему потребителю не нужно видеть логи парсера или настройки, а внутренним инструментам не нужен ключевой доступ.

Планы развития: от внутреннего инструмента к сервису

Сейчас CourtWatcher работает как «однопользовательский» сервис для конкретного заказчика. Дальнейшее развитие — превращение в мультипользовательскую платформу мониторинга судебных дел для юридических служб разного размера. Основные направления:

Мультиарендность и персональные поиски

Каждый пользователь (юридическая фирма, корпоративный отдел, частный юрист) получит собственный набор отслеживаемых запросов: свои контрагенты, свои категории дел, свои суды. Технически это добавление уровня «аккаунт» в модель данных и фильтрация всех запросов по нему. Планировщик при этом остаётся общим — он обрабатывает задачи всех пользователей в очереди с учётом лимитов нагрузки на порталы.

Уведомления

Самый востребованный функционал для юристов. События, которые должны генерировать уведомления:

  • Новое заседание назначено или перенесено

  • Изменилось состояние дела (решение вынесено, дело приостановлено и т.д.)

  • Появилось новое дело по отслеживаемому запросу

  • Прошло заседание — результат зафиксирован

Каналы доставки: e-mail как базовый, плюс мессенджеры. Архитектурно уведомления вынесутся в отдельную очередь событий: парсер пишет событие в БД, а независимый диспетчер доставляет его по каналам. Это изолирует сбои в доставке от основного цикла парсинга.

Telegram-бот и бот для MAX

Telegram-бот — естественный канал для юридических команд: уведомление «по делу N назначено заседание на 14.09, зал 305» приходит прямо в рабочий чат. Бот позволит не только получать уведомления, но и выполнять действия: посмотреть статус дела, список ближайших заседаний, добавить новый запрос на отслеживание.

Бот для мессенджера MAX — ответ на требования локализации коммуникации. Для юридических служб, работающих с государственными структурами, наличие канала в российском мессенджере становится всё более значимым требованием. Технически это отдельный адаптер доставки поверх той же очереди событий: интерфейс диспетчера каналов не меняется, добавляется новый драйвер.

💡 При проектировании ботов для юридических сервисов важно с первого дня заложить привязку уведомлений к конкретному делу и пользователю: в чате фирмы несколько юристов следят за разными делами, и «шум» чужих уведомлений снижает ценность канала до нуля.

Расширение на другие суды и регионы

Сейчас сервис работает с двумя порталами Москвы. Логичное расширение — арбитражные суды (картотека kad.arbitr.ru) и региональные порталы общей юрисдикции. Каждый новый источник — это отдельный парсер, но общая модель данных и планировщик остаются неизменными. Именно поэтому архитектура изначально разделяла «знание о портале» и «знание о деле».

Отчёты и аналитика

Для юридических департаментов ценны сводные отчёты: динамика по категориям дел, загрузка судей, среднее время рассмотрения, распределение исковых требований. Данные уже хранятся в структурированном виде — остаётся добавить слой агрегации и экспорт (PDF/Excel).

Что стоит учесть при построении подобных систем

Если вы планируете аналогичный сервис для своей юридической практики или как продукт, вот ключевые уроки, которые мы усвоили:

  1. Начинайте с одного портала. Два источника сразу — двойная отладка. Протестируйте полный цикл (поиск → карточка → БД → интерфейс) на одном портале, затем добавляйте второй.

  2. Заложите адаптивность нагрузки с первого дня. Фиксированные таймауты и паузы, вынесенные в настройки, — не «оптимизация на потом», а базовое требование для работы с государственными порталами.

  3. Дедупликация по URL, а не по номеру дела. Номера пересекаются между судами; это классический источник дублей.

  4. Мониторьте качество разбора. Доля успешно распарсенных карточек — главный индикатор того, что портал не изменил вёрстку. Без этого сервис может «тихо» собирать мусор неделями.

  5. Разделяйте парсинг, хранение и доставку уведомлений. Три независимых контура с чёткими интерфейсами между ними упрощают отладку и позволяют развивать каждый слой отдельно.

  6. Планируйте мультиарендность заранее. Добавление уровня «пользователь» в готовую систему — это миграция данных и переработка планировщика; заложенный с начала уровень аккаунта экономит месяцы работы.

⚠️ Важно понимать: автоматизация мониторинга — это не «написать скрипт и забыть». Порталы судов периодически меняют вёрстку, ужесточают лимиты нагрузки, обновляют сертификаты. Сервис требует постоянного сопровождения: мониторинг качества разбора, оперативная реакция на изменения порталов, тюнинг интервалов. Команды, которые доверяют критичные задачи такого рода опытным разработчикам с опытом работы с реальными государственными порталами, экономят значительное время на предотвращении скрытых сбоев — тех, которые проявляются не в день релиза, а через месяц-два эксплуатации.

Заключение

CourtWatcher — пример того, как относительно компактная система (один Python-процесс, SQLite, один контейнер) решает реальную бизнес-задачу: экономит часы ручного труда юристов и снижает риск пропустить процессуальный срок. Архитектурные решения — разделение парсеров по порталам, адаптивная нагрузка, аудит изменений, изоляция внешнего API — делают систему устойчивой к изменениям внешней среды и готовой к развитию в мультипользовательский сервис.

Планы на ближайшую перспективу: мультиарендность с персональными наборами поисков, система уведомлений (e-mail, Telegram, MAX), расширение на арбитражные суды и региональные порталы, аналитические отчёты. Каждый из этих блоков проектируется поверх уже работающего фундамента, что снижает риск и ускоряет доставку ценности заказчику.

Если ваша юридическая служба тратит заметное время на ручную проверку судебных порталов — автоматизация мониторинга стоит рассмотрения как инвестиция с понятной окупаемостью. А если вы хотите обсудить реализацию подобной системы под свои процессы — мы открыты к диалогу: от прототипа до промышленного сервиса с поддержкой.

Источники

AI-Помощник