Введение
В статье рассматривается парсинг/скрапинг перечня террористов физических лиц с сайта Росфинмониторинга. Скрапинг реализуем с помощью языка Python и библиотеки Selenium.
Программа будет заходить на страницу Росфинмониторинга,
находить список физических лиц и построчно преобразовывать информацию в табличный вид, как на картинке ниже.
В рамках статьи, в таблицу будет сохраняться только Имя и Фамилия, остальные параметры можете сохранять по своему желанию.
Саму программу я писал, ориентируясь только на первые 12 строк, поэтому допускаю, что при обработке всего списка программа может некачественно сработать, поэтому хотел бы подчеркнуть, что статья носит образовательный характер, и не описывает разработку реальной программы.
Решение похожей задачи, но с другим подходом к решению, можно посмотреть в статье: Парсинг (скрапинг) перечня террористов юридических лиц
Особенности программы:
- Извлекает первые 4 записи из перечня террористов с сайта https://www.fedsfm.ru/
- Преобразовывает информацию, для дальнейшей работы с ней
- Для "условной БД" будет использоваться эксель файл с расширением XLXB
- Так как в России существует ряд ограничений по обработке персональной информации физических лиц, то из всей информации в перечне террористов будет сохраняться в файле только связка: Имя+Фамилия
У статьи есть продолжение Нахождение террориста в перечне террористов, где будет рассматриваться интересный способ нахождения человека в черном списке.
За пределами статьи:
- заранее были подготовлены файлы для работы с виртуальной средой. О том, как их подготавливать, описываю в отдельной статье: https://dzen.ru/a/aEKVHTM_GULyazKa
- стартовые исходники для статьи лежат в GitLab. В рамках статьи не объясняется, как устанавливать и настраивать git. Всё это описываю в отдельной статье: https://dzen.ru/a/aGgSbU4TnF-_7wL_
- должен быть установлен Excel от версии 2007 и старше
- должен быть установлен Google Chrome
В конце статьи есть ссылка в GitLab на финальную версию программы.
Используемые технологии
ОС: Windows 10
Язык: Python 3.12
Основные библиотеки: re, pywin32, selenium
Прочее: Microsoft Office 2013, Google Chrome
План работы
- Клонируем репозиторий с GitLab
- Настраиваем виртуальную среду
- Изучаем архитектуру программы
- Правим конфиг
- Создаём программу
- Запускаем программу
Клонируем репозиторий с GitLab
Создадим папку "scrapper_fl", куда будем клонировать репозиторий
mkdir scrapper_fl
Клонируем репозиторий
git clone https://gitlab.com/pytechnotes1/scrapper_fl scrapper_fl
Заходим в папку
cd scrapper_fl/
Делаем чекаут версии коммита, который я сделал специально для статьи
git checkout b12fabb062a7fc8ff892c23d27fc61d363ed9377
Настраиваем виртуальную среду
Открываем в cmd наш проект scrapper_fl и создать виртуальную среду
py -3.12 -m venv venv
Активируем среду
venv\Scripts\activate
Производим установку библиотек из файла, который я подготовил заранее
pip install -r requirements.txt
Выходим из виртуальной среды
deactivate
Изучаем архитектуру программы
Заранее уже готова определенная структура программы.
- app.py - скрипт, который будет запускать нашу программу.
- config - папка, которая является пакетом с конфигами. В статье я не буду построчно объяснять работу этого пакета. У меня есть статья, где подробно объясняется, как создается такой конфиг: https://dzen.ru/a/aD1wIQ4l3nuUGV5o
- creator_xlsb - папка, которая также является пакетом и содержит программу, которая создает XLSB файл. Как создать такую программу, я объясняю в отдельной статье: https://dzen.ru/a/aGYTcoV41ARHOr2A
- data - папка, куда будут сохраняться XLSB файлы
- src - папка, со скриптами, которые мы будем разрабатывать в рамках данной статьи.
Правим конфиг
Откроем файл .\scrapper_fl\config\_settings\FedSFM.toml в текстовом редакторе.
Находим переменную xlsb_dir и меняем в ней путь на ваш.
Остальное оставляем как есть.
Создаём программу
Начнем реализацию с файла fedsfm.py
Реализуем конструктор __init__:
В момент создания экземпляра класса TerroristsListFL будут созданы:
- self.conf - конфиг из пакета config
- self.file_conf - отдельно сохраним конфиг для эксель файла
- self.dloader- объект DLoader, который мы создадим позже. Основной задачей объекта будет являться извлечение информации с сайта Росфинмониторинга
- self.parserFL- объект ParserFL, который мы создадим позже. Основной задачей объекта будет являться извлечение структурированной информации из списка террористов, который мы извлекли с помощью DLoader.
Укажем необходимые импорты
from config import Config
from creator_xlsb import XLSBCreator
from src.dloader import DLoader
from src.fl_parser import ParserFL
Реализуем метод run:
В методе run к self.dloader обращаемся через конструкцию with, для этого нам необходимо в классе DLoader реализовать методы __enter__ и __exit__.
Это мы делаем для того, чтобы, если при работе с DLoader произойдет ошибка, открытый браузер мог закрыться.
Через метод _loop_terrorists итерируем список террористов.
Перед тем как приступим к реализации _loop_terrorists, давайте реализуем метод _create_xlsb, который будет заниматься тем, что создаст эксель файл, который через метод _loop_terrorists будем заполнять данными.
Реализуем метод _create_xlsb
Как видно, метод _create_xlsb является декоратором. Он вызывает класс XLSBCreator, который создает эксель файл. Как создать такой класс, я объясняю в статье: https://dzen.ru/a/aGYTcoV41ARHOr2A
В рамках данного декоратора создаем self.xl, он нам пригодится для заполнения эксель файла данными.
Дополнительно импортируем Callable
from typing import Callable
Наконец, перейдем к реализации метода _loop_terrorists, заодно реализуем метод _set_data
Не забываем задекорировать метод _loop_terrorists методом _create_xlsb.
В строке self.xl.set_row(self.file_conf.first_row) мы создаем заголовки в эксель файле. Далее итерируемся по неструктурированным данным террористов и, чтобы не делать многоуровневый метод, часть логик выведем в отдельный метод: _set_data, где через метод prepare_row класса ParserFL формируем структурированный набор данных, а с помощью property prepared_rows построчно записываем террористов в файл.
На этом реализация класса TerroristsListFL завершена, перейдем к реализации класса DLoader.
Откроем файл dloader.py
Из архитектуры класса видно, что мы должны реализовать:
- конструктор класса __init__
- и методы __enter__ и __exit__ , реализовав которые, DLoader станет менеджером контекста и сможет вызываться через оператор with
Приступим к реализации конструктора класса __init__
Конструктор забирает из конфига необходимую для себя информацию:
- config.fedsfm_site - ссылка на страницу Росфинмониторинга, где лежит список террористов
- config.web_wait - время ожидания (в секундах) отклика/прогрузки информации на странице сайта
- config.xpath_fl - xpath, с помощью которого будет извлекаться информация.
В конструкторе указываем переменную _terrorist_list, она будет содержать неструктурированную информацию о террористах с сайта. Обращение к переменной реализуем через property.
Программа будет работать через браузер Google Chrome. Если в этом браузере открыть перечень террористов, то через меню Инструменты разработчика (Ctrl+Shift+I) можно найти теги, где лежит информация о террористах.
В конфиге уже указан готовый xpath, который нужен для извлечения информации. Запись [position()<=4] означает, что только первые 4 строки будем брать из всего списка.
//div[@id='russianFL']//ol[@class='terrorist-list']/li[position()<=4]
Реализуем методы __enter__ и __exit__
Так как это учебная программа, я эти методы реализую без try / except
Метод __enter__ открывает браузер, ожидает прогрузки контента и извлекает информацию о террористах.
Метод __exit__ закрывает браузер.
Эти методы мы не вызываем явно. Они вызываются сами, когда мы обращаемся к классу через оператор with
Импортируем класс Self
from typing import Self
Приступим к реализации методов из __enter__
Метод _open_website запускает браузер Google Chrome и открывает сайт Росфинмониторинга.
Метод _wait_content ожидает, когда на странице прогрузятся необходимые теги, для извлечения информации.
Метод _set_terrorist_list извлекает информацию и записывает ее в _terrorist_list
Укажем все необходимые импорты
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait as WDW
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Реализовываем property для переменной _terrorist_list
На этом реализацию DLoader завершаем и переходим к файлу fl_parser.py
Из архитектуры класса видно, что мы должны реализовать:
- конструктор класса __init__
- и метод prepare_row, который будет принимать на вход строку с неструктурированной информацией и возвращать строку для записи в эксель файле
Приступим к реализации конструктора класса __init__
Из конфигурационного файла возьмем шаблоны для регулярных выражений.
На скриншоте ниже указано, какие шаблоны за что отвечают
Дополнительно отмечу:
- p_fio_to_file - из ФИО берет связку Фамилия+Имя (таким образом, я намеренно срезаю часть ФИО)
- p_clean - очищаем ФИО от лишних символов, оставляем только буквы и пробелы
Так как придется работать с регулярками, добавим импорт
import re
Сразу реализуем property для _prepared_rows
Реализуем метод prepare_row
Метод подготавливает в рамках конкретного террориста массив всех ФИО, день рождения и регион. И передает в методу _set_final_data данные, которые будем передавать для сохранения в файл.
Метод _set_final_data принимает на вход только ФИО, так как эта программа демонстративная, а не реальная. Данный метод обновляет набор данных в переменной _prepared_rows.
Реализуем методы _find_bd и _find_region
В рамках данной программы эти методы мы реализуем, но их результат не используем, если хотите использовать, передайте результат этих методов в _set_final_data.
Метод _find_region помимо поиска нужной подстроки еще очищает полученный результат, вдруг в адресе региона окажутся нечитаемые символы.
Реализуем метод _get_clean_data
Реализуем метод _find_all_FIOs и связанные с ним методы
Метод _find_all_FIOs формирует перечень всех ФИО из ответов от методов _find_first_fio и _find_list_FIO.
Метод _find_first_fio находит первое ФИО
Метод _find_list_FIO находит все остальные ФИО
На этом реализацию программы заканчиваем.
Запускаем программу
Запускаем скрипт через "py", таким образом запустится интерпретатор из виртуальной среды.
py app.py
Откроется браузер, подождем, когда он закроется.
В результате работы программы, в папке data должен появиться файл sfmFL.xlsb
Исходники проекта
Подписывайтесь на Дзен, а также приглашаю в мой телеграмм канал, там публикую другой, но не менее интересный контент.