JavaRush /Курси /Python SELF UA /Ретрай і таймаути для стійкості скрипта

Ретрай і таймаути для стійкості скрипта

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

1. Обробка помилок у скриптах

Проблеми веб-скрейпінгу

Уяви: твій скрипт такий красивий, готовий до роботи, але раптом послизнувся на банановій шкірці — і на тобі! Помилки та збої. Як зробити так, щоб він виживав у суворих умовах Інтернету? Сьогодні ми з тобою навчимо його двом найважливішим навичкам: витримці та повторенню спроб. Так-так, ми налаштуємо ретраї та таймаути.

Робота з веб-скрейпінгом може бути чудовою, доки ти не виявиш, що твій скрипт раптово перестав працювати через:

  • Збої з'єднання.
  • Тимчасову недоступність серверів.
  • Непередбачувані зміни в HTML-структурі сторінок.

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

Вступ до механізмів обробки помилок

Для початку, давай згадаємо основу — обробка помилок у Python. Ми використовуємо блоки try-except, щоб керувати помилками і не дозволяти їм загубити роботу нашого скрипта.

Python

import requests

try:
    response = requests.get('https://example.com')
    response.raise_for_status()  # перевірка успішності запиту
except requests.exceptions.RequestException as e:
    print(f'Виникла помилка: {e}')

2. Налаштування ретраїв

Чому варто використовувати повтори спроб?

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

Як налаштувати повтори спроб

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

Python

from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests

session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))

try:
    response = session.get('https://example.com')
    response.raise_for_status()
    print(response.content)
except requests.exceptions.RequestException as e:
    print(f'Виникла помилка: {e}')

У цьому прикладі ми створили session, до якої застосували механізм повторів спроб (Retry). Ми зазначили, що варто зробити до 5 спроб у разі збою з кодами 500, 502, 503 і 504. backoff_factor=1 означає, що час між спробами буде зростати за принципом експоненційного росту (1, 2, 4, 8... секунд).

3. Таймаути: запобігання зависанню

Відкладемо капризне очікування

Таймаути — як будильник: допоможуть не зависнути в очікуванні відповіді сервера. Встановивши таймаут, ти кажеш своєму скрипту: "Досить чекати! Якщо сервер не відповість за вказаний час, рухайся далі!"

Python

try:
    response = requests.get('https://example.com', timeout=10)
    response.raise_for_status()
    print(response.content)
except requests.exceptions.Timeout:
    print('Запит перевищив час очікування')
except requests.exceptions.RequestException as e:
    print(f'Виникла помилка: {e}')

Навіщо це потрібно?

Чи застрягав ти в очікуванні, поки твій скрипт отримає відповідь від сервера, який уже "згорів" як тост? Таймаути запобігають зайвому очікуванню і дають твоєму коду можливість швидко відновитися і продовжити роботу. Не змушуй свій скрипт "думати", що він міг би кілька разів сходити на перекур за цей час!

4. Приклади налаштування

Реалізація стійкого скрипта із застосуванням ретраїв

Тепер давай зберемо наш скрипт, який буде стійким як броня Залізної людини. Ми використовуватимемо як таймаути, так і повтори.

Python

from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests

def fetch_url(url):
    session = requests.Session()
    retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
    session.mount('https://', HTTPAdapter(max_retries=retries))

    try:
        response = session.get(url, timeout=10)
        response.raise_for_status()
        return response.content
    except requests.exceptions.Timeout:
        print('Запит перевищив час очікування')
    except requests.exceptions.RequestException as e:
        print(f'Виникла помилка: {e}')
    return None

content = fetch_url('https://example.com')
if content:
    print('Успішно завантажили дані!')

Використання таймаутів для запобігання зависанню скрипта

Ми вже продемонстрували, як встановити таймаути. Давай тепер переконаємося, що наш скрипт не просто стійкий, але й розумно реагує на довге очікування. Замість того, щоб "зависнути", він просто нагадає про це хазяїну: "Гей, сервер занадто довго думає, я не збираюся чекати!"

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

Практичне застосування

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

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