为什么需要代理?
在使用 requests 时,我们通常直接连接目标服务器,但在某些场景下,我们需要通过代理服务器来发送请求,主要原因包括:
- 访问受限资源:当你的网络环境无法直接访问某些网站(如公司内网限制、地理位置限制)时,可以通过代理服务器进行访问。
- 提高性能:通过缓存代理,可以加速对常用网站的访问。
- 隐私保护:隐藏你的真实 IP 地址,防止被目标网站追踪。
- 数据抓取:在进行大规模网页爬虫时,使用代理可以避免因请求过于频繁而被目标网站封禁 IP。
- 绕过访问限制:某些网站会根据 IP 地址限制访问频率或访问内容。
requests 如何使用代理?
requests 库使用代理非常简单,核心是在发起请求时传入 proxies 参数,这个参数是一个字典,键是协议(如 'http' 或 'https'),值是对应的代理服务器地址。
基本语法
import requests
proxies = {
'http': 'http://your_http_proxy:port',
'https': 'https://your_https_proxy:port', # 或者 'http://your_https_proxy:port'
}
response = requests.get('http://example.com', proxies=proxies)
print(response.text)
代理的类型和格式
代理服务器有不同的类型,主要分为 HTTP 代理和 SOCKS 代理,它们的配置方式略有不同。
a) HTTP/HTTPS 代理
这是最常见的代理类型,适用于 HTTP 和 HTTPS 流量,HTTPS 请求通常通过 CONNECT 方法通过 HTTP 代理隧道传输。
- 格式:
http://user:password@host:port或http://host:port
示例(不带用户名和密码)
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:3128',
}
示例(带用户名和密码) 如果代理需要身份验证,格式如下:
proxies = {
'http': 'http://username:password@10.10.1.10:3128',
'https': 'http://username:password@10.10.1.10:3128',
}
b) SOCKS 代理
SOCKS 代理功能更强大,它工作在比 HTTP 更低的层次,可以转发任何类型的流量(如 TCP、UDP),不关心具体的协议,对于爬虫来说,SOCKS 代理通常比 HTTP 代理更难被检测和屏蔽。
requests 本身不直接支持 SOCKS 代理,但我们可以借助第三方库 requests[socks]。
第一步:安装依赖
pip install requests[socks] # 或者 pip install requests socks
第二步:配置代理
SOCKS 代理的 URL 格式为 socks5:// 或 socks4://。
示例(不带用户名和密码)
proxies = {
'http': 'socks5://127.0.0.1:1080', # 假设你的 SOCKS5 代理在本地的 1080 端口
'https': 'socks5://127.0.0.1:1080',
}
response = requests.get('http://example.com', proxies=proxies)
print(response.text)
示例(带用户名和密码)
proxies = {
'http': 'socks5://user:password@127.0.0.1:1080',
'https': 'socks5://user:password@127.0.0.1:1080',
}
完整代码示例
下面是一个结合了超时设置、异常处理的完整示例。
import requests
from requests.exceptions import ProxyError, ConnectTimeout, RequestException
# 代理配置 (请替换为你的真实代理地址)
# proxies = {
# 'http': 'http://10.10.1.10:3128',
# 'https': 'http://10.10.1.10:3128',
# }
# 如果使用 SOCKS 代理,确保已安装 requests[socks]
proxies = {
'http': 'socks5://127.0.0.1:1080',
'https': 'socks5://127.0.0.1:1080',
}
target_url = 'http://httpbin.org/ip' # 这个网站会返回你的 IP 地址
try:
print(f"正在通过代理访问 {target_url}...")
# 发起 GET 请求,设置超时和代理
response = requests.get(
target_url,
proxies=proxies,
timeout=10 # 设置 10 秒超时
)
# 检查请求是否成功
response.raise_for_status() # 如果状态码不是 200,则抛出异常
print("请求成功!")
print("响应内容:")
print(response.json()) # httpbin.org 的响应通常是 JSON 格式
except ProxyError:
print("错误:无法连接到代理服务器,请检查代理地址和端口是否正确。")
except ConnectTimeout:
print("错误:连接代理服务器超时。")
except RequestException as e:
print(f"发生了一个请求错误: {e}")
环境变量方式设置代理
如果你希望 requests 默认就使用代理,而不必在每个请求中都指定 proxies 参数,你可以通过设置环境变量来实现。
这在某些场景下非常有用,例如让整个应用程序都走代理。
import os
import requests
# 设置环境变量
# Windows: set HTTP_PROXY=http://10.10.1.10:3128
# set HTTPS_PROXY=http://10.10.1.10:3128
# Linux/macOS: export HTTP_PROXY="http://10.10.1.10:3128"
# export HTTPS_PROXY="http://10.10.1.10:3128"
# 在 Python 代码中设置
os.environ['HTTP_PROXY'] = 'http://10.10.1.10:3128'
os.environ['HTTPS_PROXY'] = 'http://10.10.1.10:3128'
# 现在发起的任何 requests 请求都会自动使用代理
response = requests.get('http://example.com')
print(response.text)
# 如果想临时禁用环境变量中的代理,可以在请求时传入 proxies={}
response_no_proxy = requests.get('http://example.com', proxies={})
print(response_no_proxy.text)
最佳实践和常见问题
-
不要硬编码代理:将代理地址、用户名、密码存储在配置文件或环境变量中,而不是直接写在代码里。
-
处理代理失败:代理服务器可能会宕机或变得非常慢,你的代码应该能够优雅地处理
ProxyError和ConnectTimeout等异常,并可以切换到备用代理或直接连接。 -
使用会话对象:如果你需要多次请求,并且希望复用代理设置、TCP 连接等,请使用
requests.Session对象。session = requests.Session() session.proxies = proxies # 在会话级别设置代理 # 后续所有请求都会自动使用这个代理 session.get('http://example.com/page1') session.get('http://example.com/page2') -
HTTPS 代理与 SSL 证书:当你通过 HTTP 代理访问 HTTPS 网站时,
requests默认会验证 SSL 证书,但中间人代理(MITM)为了解密流量,通常会使用自己的证书,这会导致requests报告SSLError。- 解决方案:如果你信任你的代理服务器,可以在请求时禁用 SSL 验证(注意:这会降低安全性)。
response = requests.get('https://example.com', proxies=proxies, verify=False)禁用后,
requests会发出一个InsecureRequestWarning警告,你可以通过以下方式忽略它:import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
- 解决方案:如果你信任你的代理服务器,可以在请求时禁用 SSL 验证(注意:这会降低安全性)。
希望这份详细的指南能帮助你完全掌握在 requests 中使用代理!
