/
killogram
/
E-Analyzer
Обзор
Документация
Войти
/
killogram
/
E-Analyzer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
services/parser.py
157 строк
7 KB
Korabliov Kirill
Add purchases
01 июн 2025, 16:49
01 июн 2025, 16:49
376f2c0
Код
Авторство
О чём код?
import os import time import logging from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, NoSuchElementException, WebDriverException from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options # Настройка логирования logging.basicConfig( filename='services/parser.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) def wait_for_download(download_dir, timeout=60, expected_new_files=1): """Ожидает завершения загрузки новых файлов в указанной папке""" start_time = time.time() initial_files = set(os.listdir(download_dir)) while time.time() - start_time < timeout: current_files = set(os.listdir(download_dir)) new_files = current_files - initial_files completed_files = [f for f in new_files if not f.endswith('.crdownload') and 'OrderSearch' in f] if len(completed_files) >= expected_new_files: logging.info(f"Найдено {len(completed_files)} новых завершенных файлов: {completed_files}") return list(completed_files) time.sleep(2) logging.warning(f"Таймаут ожидания загрузки в {download_dir}. Текущие файлы: {os.listdir(download_dir)}") return [] # Настройки драйвера Chrome (headless) def get_chrome_options(): options = Options() options.add_argument("--headless") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--window-size=1920,1080") options.add_argument("--disable-gpu") options.add_argument("--disable-extensions") options.add_argument("user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.7151.55 Safari/537.36") options.add_experimental_option("prefs", { "download.default_directory": os.path.abspath("data"), "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True }) return options # Инициализация драйвера def init_driver(): service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service, options=get_chrome_options()) return driver # Функция для выполнения шагов до выгрузки def navigate_to_download_page(driver, url): driver.get(url) logging.info("Страница загружена") # 🚫 Закрытие всплывающего окна сертификата try: close_button = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "#sslCertificateChecker-right > span:nth-child(1)")) ) close_button.click() logging.info("Окно сертификата закрыто") except TimeoutException: logging.info("Окно сертификата не найдено — пропускаем") # 🔍 Поиск кнопки "Выгрузить" try: download_button = WebDriverWait(driver, 20).until( EC.visibility_of_element_located((By.CSS_SELECTOR, "#quickSearchForm_header > section.content.content-search-registry-block > div > div > div.col-9.search-results > div.sort-by-block.noselect > div.d-flex.justify-content-between.align-items-baseline > div.d-flex.align-items-baseline.sort-by-list > a.downLoad-search")) ) driver.execute_script("arguments[0].click();", download_button) logging.info("Кнопка 'Выгрузить' нажата") except Exception as e: logging.error(f"Ошибка при нажатии кнопки 'Выгрузить': {e}") raise # ✅ Выбор "Все параметры" try: all_params_checkbox = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.CSS_SELECTOR, "#mCSB_2_container > ul > li > span > span.dynatree-checkbox")) ) driver.execute_script("arguments[0].click();", all_params_checkbox) logging.info("Выбраны все параметры") except Exception as e: logging.error(f"Ошибка при выборе 'Все параметры': {e}") raise # ➡️ Переход на шаг "Выбор записей" try: next_button = WebDriverWait(driver, 20).until( EC.element_to_be_clickable((By.ID, "btn-primary")) ) next_button.click() logging.info("Кнопка 'Далее' нажата") # Ждем загрузки следующей страницы WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.CSS_SELECTOR, "div.csvDownload.cursorPointer")) ) logging.info("Страница с кнопками выгрузки загружена") except Exception as e: logging.error(f"Ошибка при нажатии 'Далее': {e}") raise # Основная функция парсинга def download_csv_files(): url = "https://zakupki.gov.ru/epz/order/extendedsearch/results.html" download_dir = os.path.abspath("data") total_files = 10 # Сколько файлов хотим загрузить for i in range(1, total_files + 1): driver = None try: driver = init_driver() navigate_to_download_page(driver, url) # 📥 Загружаем один файл logging.info(f"Начинаю выгрузку файла #{i}") csv_buttons = WebDriverWait(driver, 30).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, "div.csvDownload.cursorPointer")) ) logging.info(f"Найдено {len(csv_buttons)} кнопок для выгрузки") if i > len(csv_buttons): logging.warning(f"Запрошенный файл #{i} превышает количество доступных кнопок ({len(csv_buttons)})") break csv_button = csv_buttons[i - 1] # Берем кнопку по индексу driver.execute_script("arguments[0].scrollIntoView({block: 'center', inline: 'center'});", csv_button) time.sleep(1) driver.execute_script("arguments[0].click();", csv_button) logging.info(f"Файл #{i} начат загрузкой") # Ожидаем завершения загрузки downloaded_files = wait_for_download(download_dir, timeout=60, expected_new_files=1) if downloaded_files: logging.info(f"Загружен файл: {downloaded_files[0]}") else: logging.warning(f"Файл #{i} не был загружен в течение 60 секунд") except Exception as e: logging.error(f"Ошибка при загрузке файла #{i}: {e}") finally: if driver: driver.quit() logging.info("Браузер закрыт") time.sleep(2) # Пауза между сессиями if __name__ == "__main__": download_csv_files()