From 8706583cd2a4eb51fc4f6aca7d588641ee88413f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=B2?= Date: Thu, 24 Jul 2025 11:24:49 +0500 Subject: [PATCH] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=87=D0=B0=D1=8F=20=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D1=81=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cor_func.py | 111 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 34 deletions(-) diff --git a/cor_func.py b/cor_func.py index 72d9bf6..1ad2193 100644 --- a/cor_func.py +++ b/cor_func.py @@ -6,17 +6,18 @@ import re def parse_html(url=str): """ - Фунция принимает строку URL, - выполняет запрос, - создает и возращает объект BeautifulSoup(HTML). + Фунция принимает строку URL, выполняет запрос. + Создает и возращает объект BeautifulSoup(HTML). """ # Запрос страницы response = requests.get(url) - # Проверка статуса страницы + # Проверка статуса в ответе на запрос if not(200 <= response.status_code <= 299): - print("Ошибка при запросе:", response.status_code) + # Повторный запрос + response = requests.get(url) + print("Ошибка при запросе: ", response.status_code) return response.status_code - # Создание обьекта BeautifulSoup + # Создание обьекта BeautifulSoup(HTML страница) soup = BeautifulSoup(response.text, 'html.parser') return soup @@ -29,23 +30,27 @@ def parse_date_report(url=str): 'date = 01.07.22' 'id_date = 5.01' """ + # HTML report soup = parse_html(url) + # Если не удалось отправить запрос, ворзвращаем URL и код ошибки. + # Они будут занесы в файл. + if soup == int: + return url, soup # Поиск в HTML строки ввида: 'Действующий формат (с 10.01.23) 5.01' div_element = soup.find('div', class_='controls-Dropdown__text') # Извлекаем текст из элемента text = div_element.get_text() - print(text, ' ',url) - #Парсим нужные данные - date = '' - id_date = '' - if ('_') in text: + # Парсим нужные данные + # Уловия ловит: text = 'Действующий формат 02-04-2025 _2025_001' + if '_' in text: regex = r'\w+\s\w+\s(\S+) (\S+)' date, id_date = re.search(regex, text).groups() + return date, id_date + # Все остальные else: regex = r'(\d{2}\D\d{2}\D\d{2})(?:(?:.+)?\))? #?(\d+(?:\D\d+)?)' date, id_date = re.search(regex, text).groups() - print('date: ', date, 'id: ', id_date) - return date, id_date + return date, id_date def parse_reports(soup=BeautifulSoup, report_title = str, @@ -55,24 +60,21 @@ def parse_reports(soup=BeautifulSoup, Достаются все необходимые данные, возвращаются в ввиде словаря: {106538: ('fns', 'НД по косвенным налогам', '01.08.23', '5.04')} """ - # Содрежит url всех report(не используется) - #list_report_url = [] + result_dict_data = {} # Перебарает все URL, ищутся по тегу 'a' for link in soup.find_all('a'): # Ищет по тегу: href href = link.get('href') if f'{report_title}/' in href: - # id записи + # id report id = href.rstrip('/').split('/')[-1] - #URL записи + #URL report url_report = f'{url_formats}{href}' - #Добавление url в лист(не используется) - #list_report_url.append(url_title) link = soup.find('a', href=href) - # Имя записи + # Name report span = link.find('span', class_="ProxySbisRu__registry-BrowserItem_typeName") - # Передаем текущию запись цикла + # Данные получены из url после парсинга date, id_date = parse_date_report(url_report) # Добавление всех данных в итоговый словарь result_dict_data.update({id: (name_title, span.text, date, id_date)}) @@ -84,49 +86,90 @@ def write_report_data(filename, dict_name = dict, name_title = str): Сохраняем запись, каждая запись с новой строки: 'ключ: значение' 'ключ: значение' + ... """ - dash = '-'*30 + #Блок для красивого форлмения файла + + # Вычисляем количество подчёркиваний слева и справа + def center_text(): + """ + Функия парсит сколько нужно подчеркивания, + что бы центролизовать текст в строке с этими подчеркиваниями + Возвращает две строки одна для начало блока записей тайтал, вторая конца блока. + """ + start_str = f'START_{name_title}' + end_str = f'END_{name_title}' + dash = 100 + list_result = [] + # сначал вернеться dash_start, потом end_start. + for text in start_str, end_str: + remaining_space = dash - len(text) + left = remaining_space // 2 + right = remaining_space - left # Чтобы учесть нечётную разницу + list_result.append('_' * left + text + '_' * right) + return list_result[:2] + dash_start, dash_end = center_text() + + #Конец блока + #Запись в файл с красивым офрмление в виде нижнего подчеркивания with open(filename, 'a', encoding='utf-8') as f: - f.write(f'\n{dash}START_{name_title}{dash}\n') + f.write(f'\n{dash_start}\n') for key, value in dict_name.items(): str_k_v = f'{key}: {value}\n' f.write(str_k_v) - f.write(f'{dash}END_{name_title}{dash}\n') + f.write(f'{dash_end}\n') -def serth_title(): +def search_title(): """ Функция ищет все тайтлы, возвращает лист сотоящий из: ['/report/fns', ...] """ + # url по которому в котором будет происходить поиск, + # Используется только в этой функции url_format_report = 'https://formats.saby.ru/report' + # Объект HTML html = parse_html(url_format_report) + # Если придет int(он же respons.status_code)) + if html == int: + error_message = f'Ошибка при запросе {url_format_report}: {html}' + raise Exception(error_message) + # Лист в который будут заноситься тайтлы list_reports = [] # Перебераем все URL + # Ищем все тэги 'a' for link in html.find_all('a'): - # Ищет по тегу: href + # Ищем по тегу: href href = link.get('href') + #Проверям что href содержит: /report/{title} if re.search(r'\/report\/(\w+)$', href): - print('Cовпадение найдено: ', href) list_reports.append(href) return list_reports # Имя файла в который будет записан результат кода filename_save = 'ReportData.txt' -#Удаляем старые записи, что бы довабить новые +# Удаляем старые записи, что бы записать актульные with open(filename_save, 'w') as f: - #Файл перезаписывается в пустой + # Файл перезаписывается и становится пустым f.write('') # Лист имеет вид: ['/report/fns', '/report/sfr'...] -list_title = serth_title() - +list_title = search_title() +# Используется два раза, создал отдельную переменную URL_FORMATS = 'https://formats.saby.ru' - +""" +Цикл про бегается по каждому тайтлу. +Для всех записей(reports) выполняется запрос HTML страницы, +которая парситься в объект BeautifulSoup(HTML страница). +Из это обьекта достаются не боходимые данные, +которые записываются в текстовый файл. +""" +#report_title = '/report/fns' for report_title in list_title: + # Получаем имя тайтла через парсинг name_title = report_title.rstrip('/').split('/')[-1] - + # URL на конкретный title url_title = f'{URL_FORMATS}{report_title}' - # Объект HTML + # Объект HTML, конкретного title soup = parse_html(url_title) # Словарь с нужными данными dict_result = parse_reports(soup, report_title, URL_FORMATS, name_title)