Python 爬虫中代理的使用
1. 为什么需要使用代理?
在爬虫工作中,频繁使用同一 IP 地址向目标服务器发起请求容易被识别为爬虫行为,可能导致:
- IP 被封禁:服务器拒绝该 IP 的后续请求。
- 访问频率限制:限制单位时间内来自同一 IP 的请求数量。
- 验证码挑战:要求用户输入验证码以证明非机器人操作。
使用代理服务器可以:
- 隐藏真实 IP:目标服务器看到的是代理服务器的 IP。
- 绕过 IP 限制:通过更换代理 IP 来规避封禁或频率限制。
- 访问地域限制内容:选择特定地区的代理 IP 来访问地理限制的内容。
- 提高匿名性:增加追踪真实用户身份的难度。
2. 代理的类型
常见的代理协议包括:
- HTTP 代理:主要用于 HTTP 流量。
- HTTPS 代理:主要用于 HTTPS 流量(也常能处理 HTTP)。
- SOCKS 代理:通用性更强,可处理各种类型流量(HTTP, HTTPS, FTP 等)。常见版本有 SOCKS4 和 SOCKS5(支持 UDP 和认证)。
3. Python 中使用代理的方式
3.1 使用 requests 库
requests 库是最常用的 HTTP 库之一,通过 proxies 参数设置代理。
-
基本用法:
pythonimport requests # 定义代理字典,格式为 {'协议': '代理地址'} proxies = { 'http': 'http://127.0.0.1:8080', # HTTP 代理 'https': 'https://127.0.0.1:8080', # HTTPS 代理 } try: response = requests.get('https://www.example.com', proxies=proxies, timeout=10) print(response.text) except requests.exceptions.RequestException as e: print(f"请求出错: {e}") -
带认证的代理 :
如果代理服务器需要用户名和密码认证:
pythonproxies = { 'http': 'http://username:password@127.0.0.1:8080', 'https': 'https://username:password@127.0.0.1:8080', } -
SOCKS 代理 :
需要额外安装
requests[socks]:bashpip install requests[socks]使用方式:
pythonproxies = { 'http': 'socks5://127.0.0.1:1080', 'https': 'socks5://127.0.0.1:1080', }
3.2 使用 urllib 库
Python 标准库 urllib 也支持代理。
-
设置代理:
pythonimport urllib.request # 创建代理处理器 proxy_handler = urllib.request.ProxyHandler({ 'http': 'http://127.0.0.1:8080', 'https': 'https://127.0.0.1:8080', }) # 创建使用代理的 opener opener = urllib.request.build_opener(proxy_handler) # 使用 opener 发送请求 try: response = opener.open('https://www.example.com', timeout=10) print(response.read().decode('utf-8')) except urllib.error.URLError as e: print(f"请求出错: {e}") -
带认证的代理 :
需要使用
HTTPBasicAuthHandler或ProxyBasicAuthHandler(可能需要自定义):pythonimport urllib.request # 创建密码管理器 password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() password_mgr.add_password(None, 'http://127.0.0.1:8080', 'username', 'password') password_mgr.add_password(None, 'https://127.0.0.1:8080', 'username', 'password') # 创建认证处理器 auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr) proxy_handler = urllib.request.ProxyHandler({ 'http': 'http://127.0.0.1:8080', 'https': 'https://127.0.0.1:8080', }) # 组合处理器并创建 opener opener = urllib.request.build_opener(proxy_handler, auth_handler) # 使用 opener response = opener.open('https://www.example.com')
4. 代理池的使用
对于大规模爬虫,单个代理不够用,需要代理池来管理多个代理 IP。
代理池的基本思路:
- 获取代理:从免费代理网站或购买付费代理 API 获取 IP 列表。
- 验证代理:定期检测代理是否可用、速度如何、是否匿名。
- 存储代理:将验证通过的代理存入数据库(如 Redis)或队列。
- 调度使用:爬虫请求时,从代理池中随机或按策略(如轮询)取出一个代理使用。
- 异常处理:如果使用代理请求失败(连接超时、返回错误码),将该代理标记为无效或移出池子。
简单示例代码片段:
python
import requests
from random import choice
# 假设我们有一个从某处获取并验证过的代理列表
proxy_pool = [
'http://111.111.111.111:8080',
'http://222.222.222.222:8080',
'socks5://333.333.333.333:1080',
# ... 更多代理
]
def get_with_proxy(url):
while proxy_pool: # 确保还有代理可用
proxy = choice(proxy_pool) # 随机选择一个代理
proxies = {'http': proxy, 'https': proxy}
try:
response = requests.get(url, proxies=proxies, timeout=10)
if response.status_code == 200:
return response.text
else:
# 非200状态码,可能代理有问题,移除
proxy_pool.remove(proxy)
except requests.exceptions.RequestException:
# 请求异常,代理不可用,移除
proxy_pool.remove(proxy)
# 所有代理都试过了还是失败
raise Exception("没有可用的代理了!")
# 使用
content = get_with_proxy('https://www.targetsite.com')
print(content)
5. 重要注意事项
- 代理来源:免费代理不稳定、速度慢、失效快,适合低要求场景。付费代理通常更可靠高效。
- 代理质量检测:务必在使用前或定期验证代理的匿名性(是否透露真实 IP)、速度、稳定性。
- 错误处理:务必对代理请求失败进行捕获和处理(超时、连接错误、代理拒绝连接等),并做好代理失效的标记或移除。
- 遵守规则 :尊重目标网站的
robots.txt协议,合理控制请求频率,避免对目标服务器造成过大负担。 - HTTPS 与证书 :使用 HTTPS 代理时,注意证书验证问题(可能需要设置
verify=False,但这会降低安全性)。 - 响应时间:代理会增加请求的响应时间,设置合理的超时时间。
使用代理是爬虫应对反爬机制的重要手段之一。合理选择和轮换代理 IP,结合请求头设置、Cookies 管理等其他技巧,能显著提高爬虫的稳定性和成功率。