Улучшена читаемость кода

Разделил код строками на отдельные смысловые части для лучшей читаемости и добавил комментариев
This commit is contained in:
Ilia Miheev
2025-11-11 21:45:49 +03:00
parent 1184bfe2a0
commit eb8255d54c
+26 -4
View File
@@ -13,11 +13,14 @@ from cerberus import Validator
class Pars: class Pars:
'''Модуль для работы с запросами и bs4''' '''Модуль для работы с запросами и bs4'''
def __validation(self, schema, expected): def __validation(self, schema, expected):
'''Валидация введённых данных для методов'''
v = Validator(schema) v = Validator(schema)
if not v.validate(expected): if not v.validate(expected):
raise ValueError(v.errors) raise ValueError(v.errors)
def listdir(self, path: str) -> dict: def listdir(self, path: str) -> dict:
'''Возвращает список файлов в указанной директории''' '''Возвращает список файлов в указанной директории'''
schema = {'path': {'type': 'string'}} schema = {'path': {'type': 'string'}}
@@ -26,6 +29,7 @@ class Pars:
return listdir(path) return listdir(path)
def mkdir(self, nameDir: str): def mkdir(self, nameDir: str):
'''Создаёт папку если её ещё нет '''Создаёт папку если её ещё нет
@@ -37,6 +41,7 @@ class Pars:
if not exists(nameDir): if not exists(nameDir):
mkdir(nameDir) mkdir(nameDir)
def returnBs4Object(self, pathToFile: str, encoding: str = 'utf8', parser: str = 'lxml'): def returnBs4Object(self, pathToFile: str, encoding: str = 'utf8', parser: str = 'lxml'):
'''Возвращаем объект beautifulsoup '''Возвращаем объект beautifulsoup
@@ -44,6 +49,7 @@ class Pars:
encoding: кодировка открытия html файла encoding: кодировка открытия html файла
parser: парсер, который будет использоваться для работы''' parser: парсер, который будет использоваться для работы'''
schema = { schema = {
'pathToFile': {'type': 'string'}, 'pathToFile': {'type': 'string'},
'encoding': {'type': 'string'}, 'encoding': {'type': 'string'},
@@ -52,17 +58,21 @@ class Pars:
expected = {'pathToFile': pathToFile, 'encoding': encoding, 'parser': parser} expected = {'pathToFile': pathToFile, 'encoding': encoding, 'parser': parser}
sels.__validation(schema, expected) sels.__validation(schema, expected)
# Открываем файл и возвращаем объяект bs4 на его основе
with open(pathToFile, encoding=encoding) as file: with open(pathToFile, encoding=encoding) as file:
src = file.read() src = file.read()
soup = BeautifulSoup(src, parser) soup = BeautifulSoup(src, parser)
return soup return soup
def getTexts(self, arr: list, needFix: bool = 0) -> list: def getTexts(self, arr: list, needFix: bool = 0) -> list:
'''Возвращаем текст из элементов bs4 '''Возвращаем текст из элементов bs4
arr: список объектов bs4 из которых будет извлекаться текст arr: список объектов bs4 из которых будет извлекаться текст
needFix (0/1): если этот параметр установлен как True, то из текста будут удалены \\n, \\t и пробелы с концов''' needFix (0/1): если этот параметр установлен как True, то из текста будут удалены \\n, \\t и пробелы с концов'''
schema = { schema = {
'arr': {'type': 'list'}, 'arr': {'type': 'list'},
'needFix': {'type': 'boolean'}, 'needFix': {'type': 'boolean'},
@@ -70,9 +80,12 @@ class Pars:
expected = {'arr': arr, 'needFix': needFix} expected = {'arr': arr, 'needFix': needFix}
self.__validation(schema, expected) self.__validation(schema, expected)
result = [] result = []
for item in arr: for item in arr:
data = item.text data = item.text
# Удаляем пробелы в начале и конце строки, табуляцию, переносы строки
if needFix: if needFix:
data = data.strip() data = data.strip()
data = data.replace('\t', '') data = data.replace('\t', '')
@@ -86,12 +99,14 @@ class Pars:
return None return None
return result return result
def getAttributes(self, arr: list, att: str) -> list: def getAttributes(self, arr: list, att: str) -> list:
'''Возвращаем список значений атрибутов '''Возвращаем список значений атрибутов
arr: список объектов bs4 из которых будет извлекаться атрибут arr: список объектов bs4 из которых будет извлекаться атрибут
att: строка с названием атрибута по которому будет осуществляться поиск''' att: строка с названием атрибута по которому будет осуществляться поиск'''
schema = { schema = {
'arr': {'type': 'list'}, 'arr': {'type': 'list'},
'att': {'type': 'string'} 'att': {'type': 'string'}
@@ -110,12 +125,14 @@ class Pars:
return None return None
return result return result
def pprint(self, data: any) -> None: def pprint(self, data: any) -> None:
'''Выводим данные в удобочитаемом виде '''Выводим данные в удобочитаемом виде
data: данные которые надо вывести''' data: данные которые надо вывести'''
pprint(data) pprint(data)
def getStaticPage(self, pathToSaveFile: str, url: str, writeMethod: str = 'w', headers: dict = None) -> int: def getStaticPage(self, pathToSaveFile: str, url: str, writeMethod: str = 'w', headers: dict = None) -> int:
'''Сохраняем статическую страницу и возвращаем статус ответа от сервера '''Сохраняем статическую страницу и возвращаем статус ответа от сервера
@@ -124,8 +141,8 @@ class Pars:
writeMethod: метод записи данных в файл. "w" записывает текст, "wb" — байты writeMethod: метод записи данных в файл. "w" записывает текст, "wb" — байты
headers: заголовки запроса к серверу''' headers: заголовки запроса к серверу'''
# Устанавливаем случайный user-agent если пользователь не указал свой
if headers is None: if headers is None:
# Получаем случайный user agent
software_names = [ software_names = [
SoftwareName.FIREFOX.value, SoftwareName.FIREFOX.value,
SoftwareName.CHROME.value, SoftwareName.CHROME.value,
@@ -141,7 +158,6 @@ class Pars:
] ]
user_agent_rotator = UserAgent(software_names=software_names, operating_systems=operating_systems, limit=10) user_agent_rotator = UserAgent(software_names=software_names, operating_systems=operating_systems, limit=10)
user_agent = user_agent_rotator.get_random_user_agent() user_agent = user_agent_rotator.get_random_user_agent()
headers = { headers = {
"Accept": "*/*", "Accept": "*/*",
"User-Agent": user_agent "User-Agent": user_agent
@@ -182,6 +198,7 @@ class Pars:
except Exception as e: except Exception as e:
raise RuntimeError(e) from e raise RuntimeError(e) from e
def __scrollAndSave(self, driver, timeSleep, pathToSaveFile): def __scrollAndSave(self, driver, timeSleep, pathToSaveFile):
# Прокручиваем страницу до самого низа # Прокручиваем страницу до самого низа
lastHeight = driver.execute_script("return document.body.scrollHeight") lastHeight = driver.execute_script("return document.body.scrollHeight")
@@ -199,6 +216,7 @@ class Pars:
with open(pathToSaveFile, "w", encoding="utf-8") as file: with open(pathToSaveFile, "w", encoding="utf-8") as file:
file.write(htmlContent) file.write(htmlContent)
def getDynamicPage(self, pathToSaveFile: str, url: str, closeWindow: bool = True, timeSleep: int = 2) -> None: def getDynamicPage(self, pathToSaveFile: str, url: str, closeWindow: bool = True, timeSleep: int = 2) -> None:
'''Получаем динамическую страницу '''Получаем динамическую страницу
@@ -207,6 +225,7 @@ class Pars:
closeWindow (False/True): если указана единица, то браузер открывается в фоновом режиме, 0 — открывается как обычное приложение closeWindow (False/True): если указана единица, то браузер открывается в фоновом режиме, 0 — открывается как обычное приложение
timeSleep: время ожидания в секундах браузера перед тем как скролить страницу дальше''' timeSleep: время ожидания в секундах браузера перед тем как скролить страницу дальше'''
schema = { schema = {
'pathToSaveFile': {'type': 'string'}, 'pathToSaveFile': {'type': 'string'},
'url': {'type': 'string'}, 'url': {'type': 'string'},
@@ -217,7 +236,7 @@ class Pars:
self.__validation(schema, expected) self.__validation(schema, expected)
# Устанавливаем опции для Chrome WebDriver # Ставим настройку на запуск баузера в фоновом режиме, если closeWindow = True
options = Options() options = Options()
if closeWindow: if closeWindow:
options.add_argument('--headless') options.add_argument('--headless')
@@ -227,6 +246,7 @@ class Pars:
driver.get(url) driver.get(url)
self.__scrollAndSave(driver, timeSleep, pathToSaveFile) self.__scrollAndSave(driver, timeSleep, pathToSaveFile)
def gpsa(self, pathToSaveFile: str, url: str, timeSleep=2): def gpsa(self, pathToSaveFile: str, url: str, timeSleep=2):
'''Получаем страницу в полуавтоматическом режиме '''Получаем страницу в полуавтоматическом режиме
gpsa - get page semi-automatically gpsa - get page semi-automatically
@@ -235,6 +255,7 @@ class Pars:
url: ссылка на сайт url: ссылка на сайт
timeSleep: время ожидания браузера перед тем как скролить страницу дальше''' timeSleep: время ожидания браузера перед тем как скролить страницу дальше'''
schema = { schema = {
'pathToSaveFile': {'type': 'string'}, 'pathToSaveFile': {'type': 'string'},
'url': {'type': 'string'}, 'url': {'type': 'string'},
@@ -243,7 +264,8 @@ class Pars:
expected = {'pathToSaveFile': pathToSaveFile, 'url': url, 'timeSleep': timeSleep} expected = {'pathToSaveFile': pathToSaveFile, 'url': url, 'timeSleep': timeSleep}
self.__validation(schema, expected) self.__validation(schema, expected)
with webdriver.Chrome() as driver: with webdriver.Chrome() as driver:
driver.get(url) driver.get(url)
a = input('Нажми ENTER когда закончишь') a = input('Нажми ENTER когда окажешься на нужной тебе странице')
self.__scrollAndSave(driver, timeSleep, pathToSaveFile) self.__scrollAndSave(driver, timeSleep, pathToSaveFile)