我们通常使用代理IP来避免在爬取网站时被封锁。代理IP可以从多个来源获取,其中一种方式是通过API获取。
假设我们有一个提供代理IP的API,该API返回的数据是txt格式,每行一个代理,格式为:IP:端口 或 其他类似格式。
下面我们写一个示例代码,包括获取代理、验证代理和使用代理。
核心步骤概览
1、获取API接口:找到提供TXT格式代理的API
2、发送HTTP请求:使用requests库获取数据
3、解析代理列表:处理TXT格式数据
4、代理验证:检查代理可用性
5、存储代理:保存到文件或数据库
6、应用代理:在爬虫中使用
详细实现代码(含注释)
import requests
import time
from concurrent.futures import ThreadPoolExecutor
def fetch_proxies(api_url):
"""
从API获取TXT格式的代理列表
:param api_url: 代理API地址
:return: 代理列表 [ip:port, ...]
"""
try:
response = requests.get(api_url, timeout=10)
response.raise_for_status() # 检查HTTP错误
# 解析TXT内容:每行一个代理,格式为IP:PORT
proxies = []
for line in response.text.splitlines():
line = line.strip()
if line and ':' in line: # 简单验证格式
proxies.append(line)
return proxies
except Exception as e:
print(f"获取代理失败: {e}")
return []
def validate_proxy(proxy, test_url="http://httpbin.org/ip", timeout=5):
"""
验证代理是否可用
:param proxy: 代理地址(ip:port)
:param test_url: 测试网址
:param timeout: 超时时间(秒)
:return: 可用返回True,否则False
"""
proxies = {
'http': f'http://{proxy}',
'https': f'http://{proxy}' # 根据代理类型调整
}
try:
start = time.time()
response = requests.get(test_url, proxies=proxies, timeout=timeout)
latency = time.time() - start
if response.status_code == 200:
print(f"✅ 代理可用: {proxy} | 延迟: {latency:.2f}s | 返回IP: {response.json()['origin']}")
return True
except Exception:
pass
print(f"❌ 代理失效: {proxy}")
return False
def save_proxies(proxies, filename="valid_proxies.txt"):
"""保存有效代理到TXT文件"""
with open(filename, 'w') as f:
for proxy in proxies:
f.write(proxy + '\n')
print(f"已保存 {len(proxies)} 个有效代理到 {filename}")
def main():
# 示例API(实际使用时需替换为有效API)
api_url = "https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=10000&country=all&ssl=all&anonymity=all&format=txt"
# 1. 获取代理列表
raw_proxies = fetch_proxies(api_url)
print(f"从API获取到 {len(raw_proxies)} 个原始代理")
# 2. 多线程验证代理
valid_proxies = []
with ThreadPoolExecutor(max_workers=50) as executor: # 调整线程数
results = executor.map(validate_proxy, raw_proxies)
valid_proxies = [proxy for proxy, valid in zip(raw_proxies, results) if valid]
# 3. 保存有效代理
save_proxies(valid_proxies)
# 4. 使用示例(在爬虫中随机选择代理)
if valid_proxies:
import random
proxy = random.choice(valid_proxies)
proxies = {'http': f'http://{proxy}', 'https': f'http://{proxy}'}
try:
response = requests.get("https://example.com", proxies=proxies, timeout=10)
print(f"\n使用代理 {proxy} 成功访问: 状态码 {response.status_code}")
except Exception as e:
print(f"使用代理请求失败: {e}")
if __name__ == "__main__":
main()
关键组件说明
1、获取代理API
-
推荐不要钱API(使用时请检查最新可用性):
https://www.proxy-list.download/api/v1/get?type=http&anon=elite
2、代理验证要点
-
测试网站选择:
http://httpbin.org/ip(推荐)
-
超时设置:建议3-5秒,避免等待过长
-
并发控制:使用线程池加速验证(max_workers根据网络调整)
3、代理类型处理
# 根据代理协议类型设置
proxies = {
'http': 'http://user:pass@ip:port', # HTTP代理
'https': 'socks5://user:pass@ip:port' # SOCKS代理
}
4、进阶功能扩展
- 定时更新:添加while循环 + time.sleep(3600)每小时更新
- 代理分类:按地区/速度/类型分类存储
- 失败重试:对验证失败的代理进行二次检查
- API轮询:使用多个API源获取更多代理
实际应用示例(在爬虫中使用)
from requests.exceptions import ProxyError
def use_proxy_in_crawler(url):
# 从保存的文件加载代理
with open("valid_proxies.txt") as f:
proxies = [line.strip() for line in f]
for attempt in range(3): # 失败重试3次
proxy = random.choice(proxies)
try:
response = requests.get(
url,
proxies={'http': f'http://{proxy}'},
timeout=10,
headers={'User-Agent': 'Mozilla/5.0'}
)
return response.text
except (ProxyError, ConnectionError, Timeout):
print(f"代理 {proxy} 失效,尝试下一个...")
proxies.remove(proxy) # 移除失效代理
raise ConnectionError("所有代理均不可用")
注意事项
1、法律合规:确保遵守目标网站的robots.txt和服务条款
2、频率控制:避免高频请求API(免费API通常有限制)
3、代理类型:区分HTTP/HTTPS/SOCKS代理的不同用法
4、认证代理:处理需要用户名密码的代理(http://user:pass@ip:port)
5、错误处理:添加完善的try-except应对网络波动
最后需要提醒大家,免费代理通常存活时间短,自建代理池维护长效代理资源更合适。如果大家有啥不懂的问题都可以这里留言讨论。