Найти в Дзене

[РискТехнологии] Парсинг (скрапинг) перечня террористов юридических лиц с помощью Python

В статье рассматривается парсинг/скрапинг перечня террористов юридических лиц с сайта Росфинмониторинга. Скрапинг реализуем с помощью языка Python и библиотеки Selenium. Программа будет заходить на страницу Росфинмониторинга, находить список юридических лиц и построчно преобразовывать информацию в табличный вид, как на картинке ниже. Саму программу я писал, ориентируясь только на первые 12 строк, поэтому допускаю, что при обработке всего списка программа может некачественно сработать, поэтому хотел бы подчеркнуть, что статья носит образовательный характер, и не описывает разработку реальной программы. Решение похожей задачи, но с другим подходом к решению, можно посмотреть в статье: Парсинг (скрапинг) перечня террористов физических лиц Особенности программы: У статьи есть продолжение Нахождение террориста в перечне террористов, где будет рассматриваться интересный способ нахождения организации в черном списке, приближенный к тому, что я реализовывал в банках. За пределами статьи: В ко
Оглавление

Введение

В статье рассматривается парсинг/скрапинг перечня террористов юридических лиц с сайта Росфинмониторинга. Скрапинг реализуем с помощью языка Python и библиотеки Selenium.

Программа будет заходить на страницу Росфинмониторинга,

-2

находить список юридических лиц и построчно преобразовывать информацию в табличный вид, как на картинке ниже.

-3

Саму программу я писал, ориентируясь только на первые 12 строк, поэтому допускаю, что при обработке всего списка программа может некачественно сработать, поэтому хотел бы подчеркнуть, что статья носит образовательный характер, и не описывает разработку реальной программы.

Решение похожей задачи, но с другим подходом к решению, можно посмотреть в статье: Парсинг (скрапинг) перечня террористов физических лиц

Особенности программы:

  • Извлекает первые 12 записей из перечня террористов с сайта https://www.fedsfm.ru/
  • Преобразовывает информацию, для дальнейшей работы с ней
  • Результат сохраняем в БД PostgreSQL, которую разворачиваем заранее

У статьи есть продолжение Нахождение террориста в перечне террористов, где будет рассматриваться интересный способ нахождения организации в черном списке, приближенный к тому, что я реализовывал в банках.

За пределами статьи:

  • заранее были подготовлены файлы для работы с виртуальной средой. О том, как их подготавливать, описываю в отдельной статье: https://dzen.ru/a/aEKVHTM_GULyazKa
  • стартовые исходники для статьи лежат в GitLab. В рамках статьи не объясняется, как устанавливать и настраивать git. Всё это описываю в отдельной статье: https://dzen.ru/a/aGgSbU4TnF-_7wL_
  • должна быть установлена БД PostgreSQL. Установку рассматриваю в статье: https://dzen.ru/a/aEvZ9r7Yj290D80N
  • должен быть установлен Google Chrome

В конце статьи есть ссылка в GitLab на финальную версию программы.

Используемые технологии

ОС: Windows 10

Язык: Python 3.12

Основные библиотеки: re, selenium, pyodbc, pydantic

Прочее: PostgreSQL 17.5, Google Chrome

План работы

  • Клонируем репозиторий с GitLab
  • Настраиваем виртуальную среду
  • Поднимаем БД
  • Планируем архитектуру программы
  • Создаём программу
  • Запускаем программу

Клонируем репозиторий с GitLab

Создадим папку "scrapper_ul", куда будем клонировать репозиторий

mkdir scrapper_ul

Клонируем репозиторий

git clone https://gitlab.com/pytechnotes1/scrapper_ul scrapper_ul

Заходим в папку

cd scrapper_ul/

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

git checkout 472678ecdf4a7d55f1f9bc1ce9bcbb2b464d5ea7

Настраиваем виртуальную среду

Открываем в cmd наш проект scrapper_ul и создать виртуальную среду

py -3.12 -m venv venv

Активируем среду

venv\Scripts\activate

Производим установку библиотек из файла, который я подготовил заранее

pip install -r requirements.txt

Выходим из виртуальной среды

deactivate

Поднимаем БД

Поднятие БД подробно объясняется в статье https://dzen.ru/a/aEvZ9r7Yj290D80N.

В рамках этой статьи предоставлены два готовых bat-файла, которые лежат в папке postgresql:

  • 1_load_service.bat - файл поднимает БД в виде службы на Windows.

Перед запуском файла, откройте его в текстовом редакторе и замените путь к zip-файлу с postgresql

-4

Когда запустите файл, вам необходимо будет придумать и ввести 2 раза пароль от суперюзера с именем: postgres

В результате запуска bat-файла в Диспетчере задач в Службах должна появиться служба ServPostgre17

-5

Также в папке, где запускали bat-файл, должна появиться папка ServPostgre17. Если папка не появилась, а служба запущена, то, скорее всего, папка ServPostgre17 появилась в вашей пользовательской папке: C:\Users\ВашЮзер

  • 2_create_database.bat - файл создает БД, юзера и таблицы, к которым обращается программа.

Когда запустите файл, вам будет необходимо ввести пароль от юзера postgres (который вводили при запуске 1_load_service.bat)

Планируем архитектуру программы

Заранее уже готова определенная структура программы.

  • app.py - скрипт, который будет запускать нашу программу.
  • settings.py- скрипт-конфиг. Его править нет необходимости, однако, если у вас своя БД для подключения, конечно, укажите свою строку для подключения.
  • fedsfm.py - скрипт с нашей программой, которую мы будем реализовывать.
  • dloader.py - скрипт, который занимается извлечением информации с сайта Росфинмониторинга.
  • ul_parser.py - скрипт, который занимается обработкой информации, которую извлёк dloader.py

Создаём программу

Начнем реализацию с файла fedsfm.py

Реализуем конструктор __init__:

-6

В момент создания экземпляра класса TerroristsListUL будут созданы:

  • self.dloader- объект DLoader, который мы создадим позже. Основной задачей объекта будет являться извлечение информации с сайта Росфинмониторинга. DLoader будет принимать объект-конфиг, который мы создадим в этом же файле.
  • self.parserUL- объект ParserUL, который мы создадим позже. Основной задачей объекта будет являться извлечение структурированной информации из списка террористов, который мы извлекли с помощью DLoader.
  • self.sql_insert - sql скрипт для записи в БД

Создадим класс SFM

-7

Укажем необходимые импорты

import pyodbc
from pydantic import BaseModel
import settings
from dloader import DLoader
from ul_parser import ParserUL

Реализуем метод run и декоратор _connection_db:

-8

В методе run к self.dloader обращаемся через конструкцию with, для этого нам необходимо в классе DLoader реализовать методы __enter__ и __exit__.

Это мы делаем для того, чтобы, если при работе с DLoader произойдет ошибка, открытый браузер мог закрыться.

Через метод _loop_terrorists итерируем список террористов.

Декорируем метод run методом _connection_db. Таким образом планируем реализацию, когда откроется БД, выполнится содержимое метода run и закроется коннекшн к БД.

Реализуем методы _open_db и _close_db

-9

Реализуем методы _loop_terrorists и _set_row

-10

Метод _loop_terrorists итерируется по неструктурированным данным террористов и через метод prepare_rows класса ParserUL формируем структурированный набор данных, который построчно записывается в БД с помощью метода _set_row.

На этом реализация класса TerroristsListUL завершена, перейдем к реализации класса DLoader.

Откроем файл dloader.py

-11

Из архитектуры класса видно, что мы должны реализовать:

  • конструктор класса __init__
  • и методы __enter__ и __exit__ , реализовав которые, DLoader станет менеджером контекста и сможет вызываться через оператор with

Приступим к реализации конструктора класса __init__

-12

Конструктор забирает из конфига необходимую для себя информацию:

  • config.site - ссылка на страницу Росфинмониторинга, где лежит список террористов
  • config.wait - время ожидания (в секундах) отклика/прогрузки информации на странице сайта
  • config.xpath - xpath, с помощью которого будет извлекаться информация.

В конструкторе указываем переменную _terrorist_list, она будет содержать неструктурированную информацию о террористах с сайта. Обращение к переменной реализуем через property.

Программа будет работать через браузер Google Chrome. Если в этом браузере открыть перечень террористов, то через меню Инструменты разработчика (Ctrl+Shift+I) можно найти теги, где лежит информация о террористах.

-13

В конфиге уже указан готовый xpath, который нужен для извлечения информации. Запись [position()<=12] означает, что только первые 12 строк будем брать из всего списка.

//div[@id='russianUL']//ol[@class='terrorist-list']/li[position()<=12]

Реализуем методы __enter__ и __exit__

Так как это учебная программа, я эти методы реализую без try / except

-14

Метод __enter__ открывает браузер, ожидает прогрузки контента и извлекает информацию о террористах.

Метод __exit__ закрывает браузер.

Эти методы мы не вызываем явно. Они вызываются сами, когда мы обращаемся к классу через оператор with

Импортируем класс Self

from typing import Self

Приступим к реализации методов из __enter__

-15

Метод _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

-16

На этом реализацию DLoader завершаем и переходим к файлу ul_parser.py

-17

Из архитектуры класса видно, что мы должны реализовать:

  • конструктор класса __init__
  • и метод prepare_rows, который будет принимать на вход строку с неструктурированной информацией и возвращать строки для записи в БД

Приступим к реализации конструктора класса __init__

-18

В конструкторе укажем только шаблоны для регулярных выражений.

Давайте откроем конфигурационный файл и изучим регулярные выражения

файл settings.py
файл settings.py

Изучим устройство шаблонов на примере шаблона pattern_row_number.

Шаблон pattern_row_number имеет два последовательных шаблона поиска нужной подстроки.

-20

Шаблон pattern_remover находит нужную информацию путем удаления лишней информации. Он сначала удаляет порядковый номер записи, потом удаляет ИНН и ОГРН, потом удаляет разные символы, такие как * и -. Как итог, предполагается, что по итогу останется только нужная

-21

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

Так как придется работать с регулярками, добавим импорт

import re

Реализуем методы, которые будут итерировать шаблоны с регулярными выражениями.

-22

Реализуем метод prepare_rows

-23

В рамках строки only_names = self._loop_ptrns(self.ptrn_remover, terrorist) мы получили предварительно обработанную строку с названиями компаний. Давайте с помощью метода _get_ter_names финализируем обработку информации.

-24

Выделил красным строки, которые соединяют первое и второе название компаний, т.к. есть строки, где в скобках идет не отдельное название, а продолжение основного названия.

-25

На этом реализацию программы заканчиваем.

Запускаем программу

Запускаем скрипт через "py", таким образом запустится интерпретатор из виртуальной среды.

py app.py

Откроется браузер, подождем, когда он закроется.

В результате работы программы, в БД появятся данные.

Напишем скрипт, который извлечет данные из БД

файл test_print.py
файл test_print.py

Все работает

-27

Исходники проекта

PyTechNotes / scrapper_ul · GitLab

Подписывайтесь на Дзен, а также приглашаю в мой телеграмм канал, там публикую другой, но не менее интересный контент.