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

177 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Как работает crawler
Crawler находится в `modules/crawler.py`. Его задача простая: пройти по страницам статей УК РФ на ConsultantPlus и вернуть только содержательный текст статей.
В коде используются: `urllib`/`curl` для загрузки, `lxml` и `XPath` для разбора HTML, регулярные выражения для очистки строк.
## Общий алгоритм
1. Загружаем стартовую страницу УК РФ:
```python
START_URL = "https://www.consultant.ru/document/cons_doc_LAW_10699/"
```
2. Ищем ссылки на статьи вида `УК РФ Статья 1...`.
3. Берем первую статью.
4. Загружаем страницу статьи.
5. Извлекаем текст из блока `document-page__content`.
6. Удаляем заголовки, служебные блоки и редакционные пометки.
7. Переходим к следующей странице по ссылке `pages__right`.
8. Повторяем, пока не дойдем до последней статьи или до лимита `max_pages`.
Главная функция:
```python
pages = crawl_document()
```
Она возвращает список словарей:
```python
{
"url": "адрес страницы",
"title": "заголовок статьи",
"text": "очищенный текст статьи",
}
```
## Загрузка страницы
Загрузка вынесена в `modules/loader.py`.
Для обычных сайтов используется `urllib`, а для ConsultantPlus сначала пробуется `curl`, потому что сайт иногда нестабильно отдает большие HTML-страницы.
В crawler используется функция:
```python
download_document_page(url)
```
Она делает несколько попыток с таймаутами `8`, `30`, `30` секунд. Для страниц статей проверяется, что HTML полный и содержит `</html>`.
Для стартовой страницы допускается частичный HTML:
```python
download_document_page(start_url, allow_partial=True)
```
Это нужно потому, что оглавление может успеть прийти даже тогда, когда сайт оборвал конец HTML.
## Определение страницы статьи
Страница считается статьей, если ее заголовок подходит под регулярное выражение:
```python
ARTICLE_RE = re.compile(r"^\s*(?:УК РФ,?\s+)?Статья\s+\d+(?:\.\d+)?\.")
```
То есть подходят такие варианты:
```text
УК РФ Статья 1. ...
УК РФ, Статья 53.1. ...
Статья 361. ...
```
Проверка выполняется функцией:
```python
is_article_page(page_html)
```
## Извлечение текста статьи
Текст достается функцией:
```python
extract_page_text(page_html)
```
Она делает четыре шага:
1. Парсит HTML через `lxml.html.fromstring`.
2. Находит основной блок:
```text
document-page__content
```
3. Удаляет служебные элементы:
- `h1`;
- `doc-style`;
- `doc-insert`;
- `doc-roll`.
4. Берет текст из абзацев `p`.
Дополнительно функция `clean_text()`:
- заменяет неразрывные пробелы;
- схлопывает лишние пробелы;
- убирает номера пунктов вроде `1.`, `2.`, `а)`.
## Удаление служебных строк
Функция:
```python
service_line(line)
```
убирает строки, которые не относятся к содержанию статьи:
```text
(в ред. Федерального закона ...)
(см. текст в предыдущей редакции)
(часть третья введена ...)
Президент
Б.ЕЛЬЦИН
13 июня 1996 года
N 63-ФЗ
```
## Переход к следующей статье
Основной способ перехода:
```python
extract_next_document_url(page_html, current_url)
```
Функция ищет правую ссылку ConsultantPlus:
```text
pages__right
```
Если такой ссылки нет, crawler использует запасной список `known_urls`. В него заранее складываются все найденные ссылки на статьи. Это помогает продолжить обход, если нижняя навигация не попала в загруженный HTML.
## Защита от лишних ссылок
Crawler проверяет, что каждая ссылка относится именно к УК РФ:
```python
is_same_document(url, prefix)
```
Для УК РФ правильный префикс:
```text
/document/cons_doc_LAW_10699/
```
Поэтому crawler не уходит в новости, другие кодексы, комментарии и внешние документы.
## Где используется результат
В `main.py` результат объединяется в один текст:
```python
pages = crawl_document(SOURCE_URL)
original_text = "\n".join(page["text"] for page in pages)
```
После этого `original_text` передается в `modules/processor.py`, где строятся подготовленный текст и предметный указатель.