139 lines
5.2 KiB
Python
139 lines
5.2 KiB
Python
import requests
|
||
from bs4 import BeautifulSoup
|
||
from pprint import pprint
|
||
import re
|
||
|
||
|
||
def parse_html(url=str):
|
||
"""
|
||
Фунция принимает строку URL,
|
||
выполняет запрос,
|
||
создает и возращает объект BeautifulSoup(HTML).
|
||
"""
|
||
# Запрос страницы
|
||
response = requests.get(url)
|
||
# Проверка статуса страницы
|
||
if not(200 <= response.status_code <= 299):
|
||
print("Ошибка при запросе:", response.status_code)
|
||
return response.status_code
|
||
# Создание обьекта BeautifulSoup
|
||
soup = BeautifulSoup(response.text, 'html.parser')
|
||
return soup
|
||
|
||
def parse_date_report(url=str):
|
||
"""
|
||
Функия ожидает list из URL ввида:
|
||
url = https://formats.saby.ru/report/fns/128513
|
||
Заходит по URL, запоминает дату.
|
||
Возвращает две строки ввида:
|
||
'date = 01.07.22'
|
||
'id_date = 5.01'
|
||
"""
|
||
soup = parse_html(url)
|
||
# Поиск в 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:
|
||
regex = r'\w+\s\w+\s(\S+) (\S+)'
|
||
date, id_date = re.search(regex, text).groups()
|
||
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
|
||
|
||
def parse_reports(soup=BeautifulSoup,
|
||
report_title = str,
|
||
url_formats = str,
|
||
name_title = str):
|
||
"""
|
||
Достаются все необходимые данные, возвращаются в ввиде словаря:
|
||
{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 = href.rstrip('/').split('/')[-1]
|
||
#URL записи
|
||
url_report = f'{url_formats}{href}'
|
||
#Добавление url в лист(не используется)
|
||
#list_report_url.append(url_title)
|
||
link = soup.find('a', href=href)
|
||
# Имя записи
|
||
span = link.find('span', class_="ProxySbisRu__registry-BrowserItem_typeName")
|
||
# Передаем текущию запись цикла
|
||
date, id_date = parse_date_report(url_report)
|
||
# Добавление всех данных в итоговый словарь
|
||
result_dict_data.update({id: (name_title, span.text, date, id_date)})
|
||
|
||
return result_dict_data
|
||
|
||
def write_report_data(filename, dict_name = dict, name_title = str):
|
||
"""
|
||
Сохраняем запись, каждая запись с новой строки:
|
||
'ключ: значение'
|
||
'ключ: значение'
|
||
"""
|
||
dash = '-'*30
|
||
with open(filename, 'a', encoding='utf-8') as f:
|
||
f.write(f'\n{dash}START_{name_title}{dash}\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')
|
||
|
||
def serth_title():
|
||
"""
|
||
Функция ищет все тайтлы,
|
||
возвращает лист сотоящий из:
|
||
['/report/fns', ...]
|
||
"""
|
||
url_format_report = 'https://formats.saby.ru/report'
|
||
html = parse_html(url_format_report)
|
||
list_reports = []
|
||
# Перебераем все URL
|
||
for link in html.find_all('a'):
|
||
# Ищет по тегу: href
|
||
href = link.get('href')
|
||
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()
|
||
|
||
URL_FORMATS = 'https://formats.saby.ru'
|
||
|
||
for report_title in list_title:
|
||
name_title = report_title.rstrip('/').split('/')[-1]
|
||
|
||
url_title = f'{URL_FORMATS}{report_title}'
|
||
# Объект HTML
|
||
soup = parse_html(url_title)
|
||
# Словарь с нужными данными
|
||
dict_result = parse_reports(soup, report_title, URL_FORMATS, name_title)
|
||
# Запись данных в текстовый файл
|
||
write_report_data(filename_save, dict_result, name_title)
|
||
|
||
|
||
|
||
|