JavaRush /Курси /Python SELF UA /Оптимізація скрипта для стабільної роботи й мінімізації п...

Оптимізація скрипта для стабільної роботи й мінімізації помилок

Python SELF UA
Рівень 38 , Лекція 3
Відкрита

1. Аналіз продуктивності

Навіщо потрібна оптимізація?

Уявіть собі потужний автомобіль, який здатний розганятися до 100 км/год за три секунди, але при цьому споживає бензин, як кит — планктон. От і ваш скрипт може бути дуже швидким, але надто "ненажерливим", якщо говорити про ресурси й час виконання. Більше того, "витоки" ресурсів можуть зробити його нестабільним, що своєю чергою може призвести до помилок. Оптимізація допомагає уникнути подібних проблем.

Перш за все, як кажуть хірурги, робимо "розріз". Проведемо аналіз продуктивності нашого скрипта, щоб зрозуміти, де він може "страждати".

Методи перевірки швидкості й стабільності виконання скрипта

Одним із простих способів аналізу є використання базових засобів Python, таких як модуль time. Давайте додамо в наш скрипт пару рядків, щоб зрозуміти, які операції займають найбільше часу.

Python

import time

start_time = time.time()
# Тут ваш код для виконання дій із Selenium
end_time = time.time()

print(f"Час виконання: {end_time - start_time} секунд")
  

Цей невеликий фрагмент коду допоможе вам визначити, скільки часу займає виконання частини коду. За допомогою таких "таймерів" можна локалізувати "вузькі" місця.

Ідентифікація слабких місць і їх оптимізація

Як тільки ви знайдете частину коду, яка "поглинає" час, можна вживати заходів. Можливо, ви звертаєтеся до динамічних елементів частіше, ніж це необхідно, або ваш код став схожий на "спагеті". Перший крок — ідентифікація, другий — дії.

Зменшення кількості запитів: Перевірте, чи не робите ви багато зайвих переходів по сторінках або оновлень DOM. Наприклад, використання методу WebDriverWait допомагає запускати скрипт тільки після повного завантаження потрібних елементів.

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'myDynamicElement'))
)
  

Кешування даних: Якщо ви працюєте з одними й тими ж даними багаторазово, подумайте про кешування. Зберігайте дані в змінних або кеші для мінімізації ресурсоємних операцій.

2. Покращення структури скрипта

Якщо ваш код читається як карта метро без вказівників і назв станцій, час його покращити. Оптимальна структура коду — запорука легкого розуміння й, відповідно, стійкості до помилок.

Використання пайплайнів даних і оптимальних алгоритмічних рішень

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

Python

def load_page(url):
    driver.get(url)

def extract_data():
    # Код для збирання даних
    pass

def save_data():
    # Код для збереження даних
    pass

load_page("http://example.com")
extract_data()
save_data()
  

Покращення читабельності й тестованості коду

Дотримуйтеся принципу "одна функція — одне завдання". Це полегшить тестування й рефакторинг. Використовуйте іменовані константи замість "магічних чисел" і рядків для більшої ясності.

Python

MAX_RETRIES = 5

def fetch_data_with_retry():
    for attempt in range(MAX_RETRIES):
        try:
            # Спроба запиту даних
            pass
        except Exception as e:
            print(f"Спроба {attempt+1} не вдалася: {e}")
  

3. Якщо код можна покращити - його треба покращити

Використовуйте явні очікування замість неявних

Явні очікування дозволяють точно контролювати, коли Selenium починає виконувати дії, дочекавшись появи потрібних елементів. Замість того щоб покладатися на неявні очікування (наприклад, implicitly_wait), використовуйте бібліотеку WebDriverWait, яка дозволяє налаштувати очікування для конкретних елементів на основі умов (наприклад, елемент видно, доступний для кліку тощо).

Приклад використання явного очікування

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "target_element"))
)
  

Переконайтеся в готовності сторінки

Після завантаження сторінки не завжди одразу доступні всі елементи, особливо якщо сайт використовує асинхронні методи завантаження (AJAX). Використовуйте document.readyState для перевірки повного завантаження документа перед початком взаємодії.

Приклад перевірки повного завантаження сторінки

Python

def wait_for_page_load(driver):
    WebDriverWait(driver, 10).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
  

Мінімізуйте використання time.sleep

Метод time.sleep() змушує скрипт чекати фіксований час та уповільнює його роботу, особливо при довгих затримках. Замість цього використовуйте WebDriverWait, який більш гнучкий і завершує очікування, щойно потрібна умова виконана.

Використовуйте стійкі шляхи до елементів

Крихкі локатори, такі як шляхи XPath, що залежать від певних HTML-структур, можуть швидко перестати працювати, якщо структура сайту зміниться. Щоб цього уникнути, намагайтеся використовувати більш стійкі локатори, наприклад, атрибути id, name, class і data-*, які більш стабільні.

Приклад надійного використання атрибутів

Python

# Використовуємо id для пошуку, якщо доступний
element = driver.find_element(By.ID, "submit_button")

# Якщо нема id, можна використати атрибут data-* або унікальні класи
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
  

Закривайте спливаючі вікна та банери

Деякі сайти містять спливаючі вікна, які заважають виконанню скрипта. Обробка таких елементів дозволяє уникнути блокування основних дій.

Приклад закриття спливаючого вікна

Python

from selenium.common.exceptions import ElementClickInterceptedException

try:
    close_popup = driver.find_element(By.CLASS_NAME, "popup-close-button")
    close_popup.click()
except (NoSuchElementException, ElementClickInterceptedException):
    pass  # Ігноруємо, якщо елемент не знайдено або закриття неможливе
  

Налаштуйте обробку логування

Логування допомагає відстежувати дії скрипта та виявляти помилки у роботі. Використовуйте вбудований модуль logging для логування кожного важливого кроку скрипта, що спростить налаштування та аналіз.

Приклад налаштування логування

Python

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info("Скрипт запущений")
logging.warning("Елемент не знайдено, продовжуємо роботу")
logging.error("Виникла помилка")
  

Перевіряйте видимість елементів перед взаємодією

Іноді елементи завантажуються на сторінці, але невидимі або недоступні для взаємодії. Використовуйте WebDriverWait з умовою element_to_be_clickable, щоб переконатися, що елемент доступний перед кліком чи введенням даних.

Python

from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "button_id"))
)
element.click()
  

Обробляйте помилки з'єднання та таймаути

Під час скрейпінгу веб-сайтів іноді трапляються помилки з'єднання або таймаути, коли сервер не відповідає на запити. Налаштуйте обробку таких помилок, щоб скрипт міг пропустити або повторити дії у разі тимчасової недоступності сайту.

Приклад обробки помилок з'єднання

Python

from selenium.common.exceptions import TimeoutException

try:
    driver.get("https://example.com")
except TimeoutException:
    logging.error("Не вдалося підключитися до сторінки. Перехід до наступного завдання.")
  

Закривайте браузер

Щоб уникнути накопичення ресурсів та закриття браузера у разі помилок, завжди використовуйте try-finally чи конструкції, щоб завершити роботу коректно.

Python

try:
    # Ваші дії з Selenium
    pass
finally:
    driver.quit()  # Закриття браузера
  

4. Типові помилки новачків

Не забувайте оновлювати веб-драйвери та бібліотеки. Це допоможе уникнути несумісностей і помилок, пов'язаних з оновленнями браузера та змінами в API Selenium.

І наостанок, якщо ваш скрипт часто "валиться" без явної причини, можливо, ваш тестовий сервер блокує часті запити. Перевірте, чи не порушуєте ви правила доступу, і подумайте про використання проксі-серверів або регулювання частоти запитів.

Оптимізація скриптів — це не просто технічне завдання, а мистецтво, яке приходить з досвідом. Сподіваюся, сьогоднішні поради допоможуть вам створити надійні та стабільні скрипти, які витримають будь-яке навантаження.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ