1. Обработка ошибок в скриптах
Проблемы веб-скрейпинга
Представьте: ваш скрипт сидит такой весь красивый, готовый к работе, но внезапно поскользнулся на банановой корке — и на тебе! Ошибки и сбои. Как сделать так, чтобы он выживал в суровых условиях Интернета? Сегодня мы с вами обучим его двум важнейшим навыкам: выдержке и повторению попыток. Да-да, мы настроим ретраи и таймауты.
Работа с веб-скрейпингом может быть славной до тех пор, пока вы не обнаружите, что ваш скрипт внезапно отключился благодаря:
- Сбоям соединения.
- Временной недоступности серверов.
- Непредсказуемым изменениям в HTML-структуре страниц.
Ваш скрипт, словно джедай, должен быть готов к неожиданностям и уметь справляться с ними. Иногда проблемы можно решить, просто подождав минутку и повторив запрос. И вот тут на сцену выходят наши герои — ретраи и таймауты!
Введение в механизмы обработки ошибок
Для начала, давайте вспомним основу — обработка ошибок в Python. Мы используем блоки try-except, чтобы управлять ошибками и не давать им загубить работу нашего скрипта.
import requests
try:
response = requests.get('https://example.com')
response.raise_for_status() # проверка успешности запроса
except requests.exceptions.RequestException as e:
print(f'Произошла ошибка: {e}')
2. Настройка ретраев
Почему стоит использовать повторы попыток?
Скрипт, который просто сдается при первом же сбое, — это как кот, который боится проливного дождя. А вам нужен скрипт, который стойко переживет пару неудобств. Именно поэтому мы настраиваем ретраи — так ваш скрипт станет уверенным в себе.
Как настраивать повторные попытки
Теперь давайте разберемся, как мы можем организовать повторные попытки. Один из самых простых способов — использовать библиотеку urllib3, которая предоставляет функциональность для автоматической повторной отправки запроса при ошибках.
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. Таймауты: предотвращение зависания
Отложим капризное ожидание
Таймауты — как будильник: помогут не зависнуть в ожидании ответа сервера. Установив таймаут, вы говорите вашему скрипту: "Хватит ждать! Если сервер не ответит за указанное время, двигайся дальше!"
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. Примеры настройки
Реализация устойчивого скрипта с применением ретраев
Теперь давайте соберем наш скрипт, который будет устойчив как броня железного человека. Мы будем использовать как таймауты, так и повторы.
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('Успешно скачали данные!')
Использование таймаутов для предотвращения зависания скрипта
Мы уже продемонстрировали, как установить таймауты. Давайте теперь убедимся, что наш скрипт не просто устойчив, но и разумно реагирует на долгое ожидание. Вместо того чтобы "подвиснуть", он просто напомнит об этом хозяину: "Эй, сервер слишком долго думает, я не собираюсь ждать!"
Вот такой простой и лаконичный подход сделает ваш код надежным и готовым к бою с всевозможными непредсказуемыми ситуациями, которые могут возникнуть в Интернете.
Практическое применение
Когда вы разрабатываете реальные проекты по скрейпингу, часто приходится иметь дело с различными ограничениями со стороны серверов. Ретраи и таймауты являются вашими лучшими друзьями для минимизации риска сбоев. Это поможет вам обеспечить бесперебойную работу вашего кода, особенно при автоматизированной обработке данных и в тех случаях, когда важно получать точные результаты в срок. Эти техники также могут повысить качество вашего резюме и уровень доверия клиентов, которым вы предоставляете данные.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ