Files
CourseWork_IRFM/instructions/CRAWLER_README.md
T
Dmitry 0b41577a42 Add loader and processor modules with documentation and output files
- Implemented loader in `modules/loader.py` to download HTML pages using curl and urllib.
- Created processor in `modules/processor.py` for processing the text of the Russian Criminal Code (УК РФ).
- Added README files for both loader and processor explaining their functionality and usage.
- Generated output files including original text, prepared text, and subject index in CSV and JSON formats.
2026-04-16 21:38:00 +03:00

5.7 KiB
Raw Blame History

Как работает crawler

Crawler находится в modules/crawler.py. Его задача простая: пройти по страницам статей УК РФ на ConsultantPlus и вернуть только содержательный текст статей.

В коде используются: urllib/curl для загрузки, lxml и XPath для разбора HTML, регулярные выражения для очистки строк.

Общий алгоритм

  1. Загружаем стартовую страницу УК РФ:
START_URL = "https://www.consultant.ru/document/cons_doc_LAW_10699/"
  1. Ищем ссылки на статьи вида УК РФ Статья 1....
  2. Берем первую статью.
  3. Загружаем страницу статьи.
  4. Извлекаем текст из блока document-page__content.
  5. Удаляем заголовки, служебные блоки и редакционные пометки.
  6. Переходим к следующей странице по ссылке pages__right.
  7. Повторяем, пока не дойдем до последней статьи или до лимита max_pages.

Главная функция:

pages = crawl_document()

Она возвращает список словарей:

{
    "url": "адрес страницы",
    "title": "заголовок статьи",
    "text": "очищенный текст статьи",
}

Загрузка страницы

Загрузка вынесена в modules/loader.py.

Для обычных сайтов используется urllib, а для ConsultantPlus сначала пробуется curl, потому что сайт иногда нестабильно отдает большие HTML-страницы.

В crawler используется функция:

download_document_page(url)

Она делает несколько попыток с таймаутами 8, 30, 30 секунд. Для страниц статей проверяется, что HTML полный и содержит </html>.

Для стартовой страницы допускается частичный HTML:

download_document_page(start_url, allow_partial=True)

Это нужно потому, что оглавление может успеть прийти даже тогда, когда сайт оборвал конец HTML.

Определение страницы статьи

Страница считается статьей, если ее заголовок подходит под регулярное выражение:

ARTICLE_RE = re.compile(r"^\s*(?:УК РФ,?\s+)?Статья\s+\d+(?:\.\d+)?\.")

То есть подходят такие варианты:

УК РФ Статья 1. ...
УК РФ, Статья 53.1. ...
Статья 361. ...

Проверка выполняется функцией:

is_article_page(page_html)

Извлечение текста статьи

Текст достается функцией:

extract_page_text(page_html)

Она делает четыре шага:

  1. Парсит HTML через lxml.html.fromstring.
  2. Находит основной блок:
document-page__content
  1. Удаляет служебные элементы:
  • h1;
  • doc-style;
  • doc-insert;
  • doc-roll.
  1. Берет текст из абзацев p.

Дополнительно функция clean_text():

  • заменяет неразрывные пробелы;
  • схлопывает лишние пробелы;
  • убирает номера пунктов вроде 1., 2., а).

Удаление служебных строк

Функция:

service_line(line)

убирает строки, которые не относятся к содержанию статьи:

(в ред. Федерального закона ...)
(см. текст в предыдущей редакции)
(часть третья введена ...)
Президент
Б.ЕЛЬЦИН
13 июня 1996 года
N 63-ФЗ

Переход к следующей статье

Основной способ перехода:

extract_next_document_url(page_html, current_url)

Функция ищет правую ссылку ConsultantPlus:

pages__right

Если такой ссылки нет, crawler использует запасной список known_urls. В него заранее складываются все найденные ссылки на статьи. Это помогает продолжить обход, если нижняя навигация не попала в загруженный HTML.

Защита от лишних ссылок

Crawler проверяет, что каждая ссылка относится именно к УК РФ:

is_same_document(url, prefix)

Для УК РФ правильный префикс:

/document/cons_doc_LAW_10699/

Поэтому crawler не уходит в новости, другие кодексы, комментарии и внешние документы.

Где используется результат

В main.py результат объединяется в один текст:

pages = crawl_document(SOURCE_URL)
original_text = "\n".join(page["text"] for page in pages)

После этого original_text передается в modules/processor.py, где строятся подготовленный текст и предметный указатель.