网络抓取是从网络中提取数据的有效方法。许多开发人员喜欢使用 Python 请求库来执行网络抓取项目,因为它简单而有效。然而,请求库虽好,也有其局限性。我们在网络搜刮中可能会遇到的一个典型问题就是请求失败,这通常会导致数据提取不稳定。在本文中,我们将介绍在 Python 中实现请求重试的过程,这样您就可以处理 HTTP 错误,并保持网络搜刮脚本的稳定和可靠。
让我们先设置一下环境。确保你已经安装了 Python 和你选择的 IDE。然后安装请求库(如果还没有)。
pip install requests
安装完成后,让我们使用 Python 的 requests 模块向 example.com 发送一个请求。下面是一个简单的函数,就可以实现这个功能:
import requests
def send_request(url):
"""
向指定 URL 发送 HTTP GET 请求,并打印响应状态代码。
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 的请求已经完成。服务器用这种方式表示:"一切正常,您的请求成功"。
这些状态代码还可以在僵尸检测中发挥作用,并在出现类似僵尸的行为时显示访问限制。
以下是主要因僵尸检测和身份验证问题而出现的 HTTP 错误代码的快速概览。
现在,让我们用 Python 编写一个简单的重试机制,利用请求库发出 HTTP GET 请求。有时,由于网络问题或服务器过载,网络请求会失败。因此,如果请求失败,我们应该重试这些请求。
函数 send_request_with_basic_retry_mechanism 在向给定 URL 发送 HTTP GET 请求时使用了基本重试机制,只有在遇到网络或请求异常(如连接错误)时才会重试。重试请求的次数最多为 max_retries。如果所有尝试都因此类异常而失败,它会引发最后一次遇到的异常。
import requests
import time
def send_request_with_basic_retry_mechanism(url, max_retries=2):
"""
向带有基本重试机制的 URL 发送 HTTP GET 请求。
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 向提供的 URL 发送 HTTP GET 请求,可选择重试次数和重试延迟。它会按照指定的尝试次数多次发送请求,如果请求成功获得响应,则打印响应状态代码。如果在请求操作过程中遇到错误,它会打印错误信息并重试。每次重试之间会等待指定的重试延迟时间。如果在指定的重试次数后请求仍然失败,则会引发上次遇到的异常。
延迟参数很重要,因为它可以避免在很近的时间间隔内向服务器发出多个请求。相反,它会等待服务器有足够的时间来处理请求,让服务器认为是人类而不是机器人在发出请求。因此,重试机制应该延迟,以避免服务器过载或服务器响应缓慢而触发反僵尸机制。
import requests
import time
def send_request_with_advance_retry_mechanism(url, max_retries=3, delay=1):
"""
通过高级重试机制向指定 URL 发送 HTTP GET 请求。
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):
"""
通过高级重试机制向指定 URL 发送 HTTP GET 请求。
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 请求过多),使用旋转代理可以帮助分配请求,避免速率限制。
下面的代码在使用代理的同时,还实现了一种高级重试策略。这样,我们就可以实现 Python 请求重试机制。使用高质量的网络搜索代理也很重要。这些代理应具有良好的代理轮换算法和可靠的池。
import requests
import time
def send_request_with_advance_retry_mechanism(url, max_retries=3, delay=1, min_content_length=10):
"""
通过高级重试机制向指定 URL 发送 HTTP GET 请求。
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