Багато розробників вважають за краще використовувати бібліотеку Requests в Python для веб-скрапінгу, завдяки її простоті та ефективності. Однак, незважаючи на всі її переваги, бібліотека Requests має обмеження, особливо коли йдеться про невдалі запити, які можуть серйозно вплинути на стабільність процесу вилучення даних. У цій статті ми розглянемо, як реалізувати повторні запити в Python, що дасть змогу більш ефективно обробляти HTTP-помилки і значно підвищити надійність виконуваних скриптів веб-скрапінгу.
Перед початком роботи переконайтеся, що у вас встановлений Python і вибране середовище розробки. Після цього встановіть бібліотеку Requests, якщо вона ще не встановлена.
pip install requests
Далі, спробуємо надіслати запит до сайту example.com, використовуючи модуль Requests у Python. Нижче представлено просту функцію, яка виконує цю дію:
import requests
def send_request(url):
"""
Надсилає HTTP GET запит на вказаний URL і виводить код стану відповіді.
Parameters:
url (str): URL для надсилання запиту.
"""
response = requests.get(url)
print('Response Status Code: ', response.status_code)
send_request('https://example.com')
Результат виконання коду показано нижче:
Розглянемо докладніше, що являють собою HTTP-статус коди.
Сервери використовують HTTP-статус коди для інформування про результат обробки запитів. Ось короткий огляд різних кодів стану:
У нашому прикладі статус код 200 свідчить про те, що запит до https://example.com було успішно оброблено.
Статус коди можуть також допомогти у виявленні активності ботів і вказувати на обмеження доступу, викликані схожою з діями ботів активністю.
Нижче подано короткий огляд таких кодів:
Під час роботи з мережевими запитами неминучі випадки, коли запити не вдаються через тимчасові мережеві збої або перевантаження сервера. Для підвищення стабільності скрапінгу, можна реалізувати механізм повторних спроб.
Функція "send_request_with_basic_retry_mechanism" виконує HTTP GET-запити за заданим URL із базовим механізмом повторних спроб, що спрацьовує тільки в разі виникнення винятків, пов'язаних із мережею або запитом, таких як помилка підключення. Вона повторює запит кількість разів, що визначається параметром "max_retries". Якщо всі спроби завершуються невдачею з таким винятком, функція генерує останнє зустрінуте виключення.
import requests
import time
def send_request_with_basic_retry_mechanism(url, max_retries=2):
"""
Надсилає HTTP GET-запит на URL з базовим механізмом повторних спроб.
Parameters:
url (str): URL для надсилання запиту.
max_retries (int): Максимальна кількість спроб повторного запиту.
Raises:
requests.RequestException: Генерує останнє виключення, якщо всі спроби невдалі.
"""
for attempt in range(max_retries):
try:
response = requests.get(url)
print('Response status: ', response.status_code)
break # Вийти з циклу, якщо запит виконано успішно
except requests.RequestException as error:
print(f"Attempt {attempt+1} failed:", error)
if attempt < max_retries - 1:
print(f"Retrying...")
time.sleep(delay) # Зачекайте перед повторною спробою
else:
print("Max retries exceeded.")
# Згенеруйте останнє виключення, якщо досягнуто максимальної кількості спроб
raise
send_request_with_basic_retry_mechanism('https://example.com')
Для надійнішого скрапінгу даних із веб-сайтів, що використовують механізми виявлення ботів, необхідно адаптувати наш підхід до реалізації повторних спроб. У випадках, коли запити можуть бути заблоковані через підозри в бот-активності або через тимчасові проблеми з мережею або сервером, корисно мати механізм, що дозволяє адаптивно керувати повторними спробами.
Функція "send_request_with_advance_retry_mechanism" реалізує такий підхід, відправляючи HTTP GET-запити на заданий URL з можливістю налаштування кількості повторних спроб і затримки між ними. Ця функція не тільки повторює запити в разі виникнення помилок, а й враховує необхідність зниження частоти запитів, щоб уникнути виявлення анти-ботовими системами безпеки.
Параметр затримки відіграє ключову роль у механізмі повторних спроб, оскільки він запобігає надмірному навантаженню на сервер шляхом надсилання множинних запитів у короткі часові проміжки. Замість цього затримка між спробами дає серверу достатньо часу для обробки запитів, створюючи враження, що за запитами стоїть людина, а не автоматизована система.
import requests
import time
def send_request_with_advance_retry_mechanism(url, max_retries=3, delay=1):
"""
Надсилає HTTP GET-запит на вказаний URL із просунутим механізмом повторних спроб.
Parameters:
url (str): URL, на який надсилається запит.
max_retries (int): Максимальна кількість повторних спроб запиту. За замовчуванням - 3.
delay (int): Затримка (у секундах) між спробами. За замовчуванням - 1.
Raises:
requests.RequestException: Генерує останнє виключення, якщо всі спроби невдалі.
"""
for attempt in range(max_retries):
try:
response = requests.get(url)
# Згенерувати виняток для статус-кодів 4xx або 5xx
response.raise_for_status()
print('Response Status Code:', response.status_code)
except requests.RequestException as e:
# Вивести повідомлення про помилку і номер спроби, якщо запит не вдався
print(f"Attempt {attempt+1} failed:", e)
if attempt < max_retries - 1:
# Вивести повідомлення про повторну спробу і почекати перед повторним запитом
print(f"Retrying in {delay} seconds...")
time.sleep(delay)
else:
# Якщо перевищено максимальну кількість спроб, вивести повідомлення і знову згенерувати виняток
print("Max retries exceeded.")
raise
# Приклад використання
send_request_with_advance_retry_mechanism('https://httpbin.org/status/404')
Нижче представлено коректний код, що усуває ці недоліки:
import requests
import time
def send_request_with_advance_retry_mechanism(url, max_retries=3, delay=1, min_content_length=10):
"""
Надсилає HTTP GET-запит на вказаний URL із просунутим механізмом повторних спроб.
Parameters:
url (str): URL, на який надсилається запит.
max_retries (int): Максимальна кількість разів, яку запит може бути повторено. За замовчуванням 3.
delay (int): Затримка (у секундах) між спробами. За замовчуванням 1.
min_content_length (int): Мінімальна довжина вмісту відповіді, щоб вважати її дійсною. За замовчуванням 10.
Raises:
requests.RequestException: Генерує останнє виключення, якщо всі спроби невдалі.
"""
for attempt in range(max_retries):
try:
response = requests.get(url)
# Згенерувати виняток для статус-кодів 4xx або 5xx
response.raise_for_status()
# Перевірити, чи дорівнює статус-код відповіді 404
if response.status_code == 404:
print("404 Error: Not Found")
break # Вихід із циклу в разі помилок 404
# Перевірити, чи менша довжина тексту відповіді за вказану мінімальну довжину вмісту
if len(response.text) < min_content_length:
print("Response text length is less than specified minimum. Retrying...")
time.sleep(delay)
continue # Повторити запит
print('Response Status Code:', response.status_code)
# Якщо умови виконані, вийти з циклу
break
except requests.RequestException as e:
print(f"Attempt {attempt+1} failed:", e)
if attempt < max_retries - 1:
print(f"Retrying in {delay} seconds...")
time.sleep(delay)
else:
print("Max retries exceeded.")
# Згенерувати останнє виключення, якщо досягнуто максимальної кількості спроб
raise
# Приклад використання
send_request_with_advance_retry_mechanism('https://httpbin.org/status/404')
У випадку з такими помилками 429 too many requests, використання проксі з ротацією може допомогти розподілити ваші запити й уникнути обмежень за частотою запитів.
Нижче наведено код, що реалізує просунуту стратегію повторних спроб разом із використанням проксі. Важливо використовувати резидентські або мобільні проксі для веб-скрапінгу, оскільки вони дають змогу гнучко налаштовувати алгоритм ротації та надають великий пул адрес.
import requests
import time
def send_request_with_advance_retry_mechanism(url, max_retries=3, delay=1, min_content_length=10):
"""
Надсилає HTTP GET-запит на вказаний URL із просунутим механізмом повторних спроб.
Parameters:
url (str): URL, на який надсилається запит.
max_retries (int): Максимальна кількість разів, яку запит може бути повторено. За замовчуванням 3.
delay (int): Задержка (в секундах) между попытками. По умолчанию 1.
Raises:
requests.RequestException: Генерує останнє виключення, якщо всі спроби невдалі.
"""
proxies = {
"http": "http://USER:PASS@HOST:PORT",
"https": "https://USER:PASS@HOST:PORT"
}
for attempt in range(max_retries):
try:
response = requests.get(url, proxies=proxies, verify=False)
# Згенерувати виняток для статус-кодів 4xx або 5xx
response.raise_for_status()
# Перевірити, чи дорівнює статус-код відповіді 404
if response.status_code == 404:
print("404 Error: Not Found")
break # Вихід із циклу в разі помилок 404
# Перевірити, чи менше 10 символів довжина тексту відповіді
if len(response.text) < min_content_length:
print("Response text length is less than 10 characters. Retrying...")
time.sleep(delay)
continue # Повторити запит
print('Response Status Code:', response.status_code)
# Якщо умови виконані, вийти з циклу
break
except requests.RequestException as e:
print(f"Attempt {attempt+1} failed:", e)
if attempt < max_retries - 1:
print(f"Retrying in {delay} seconds...")
time.sleep(delay)
else:
print("Max retries exceeded.")
# Згенерувати останнє виключення, якщо досягнуто максимальної кількості спроб
raise
send_request_with_advance_retry_mechanism('https://httpbin.org/status/404')
Повторні спроби запитів у Python - ключовий елемент успішного веб-скрапінгу. Розглянуті способи управління повторними спробамидопомагають уникнути блокувань і забезпечують більш ефективний і надійний збір даних. Застосування цих технік робить ваші скрипти веб-скрапінгу ефективнішими та стійкішими перед системами виявлення ботів.
Мы получили вашу заявку!
Ответ будет отправлен на почту в ближайшее время.
С уважением proxy-seller.com!
Коментарі: 0