
代理API返回的数据结构特点
当我们从ipipgo这类代理服务商获取IP时,API通常会返回JSON格式的数据。这些数据包含多个键值对,比如IP地址、端口、协议类型、过期时间等。由于不同服务商的返回格式存在差异,直接处理原始数据很容易出错。
举个例子,ipipgo的动态住宅代理API返回的数据可能长这样:
{
"proxy": "192.168.1.1:8080",
"protocol": "socks5",
"country": "US",
"city": "Los Angeles",
"expires_in": 3600,
"valid": true
}
而静态住宅代理的返回格式可能稍有不同:
{
"ip_address": "192.168.1.2",
"port": 8081,
"type": "static",
"location": "US-LA",
"ttl": 86400
}
基础字典操作技巧
处理代理IP数据时,最常用的就是字典的键值访问。但直接通过键名获取值可能存在风险,比如键不存在时会抛出KeyError异常。
安全的做法是使用get方法:
response_data = {
"proxy": "192.168.1.1:8080",
"protocol": "socks5"
}
不安全的方式
ip_port = response_data["proxy"] 如果proxy键不存在会报错
安全的方式
ip_port = response_data.get("proxy", "默认值")
对于嵌套字典,可以使用链式get方法:
location_info = response_data.get("location", {}).get("city", "未知城市")
字典解析的高级应用
字典解析是Python中非常强大的特性,可以快速处理代理IP数据。比如我们需要从API返回中提取特定字段:
原始API返回数据
api_response = {
"status": "success",
"data": [
{"ip": "192.168.1.1", "port": 8080, "valid": True},
{"ip": "192.168.1.2", "port": 8081, "valid": False},
{"ip": "192.168.1.3", "port": 8082, "valid": True}
]
}
提取所有有效代理的IP和端口
valid_proxies = {
item["ip"]: item["port"]
for item in api_response.get("data", [])
if item.get("valid")
}
还可以结合条件判断创建更复杂的字典:
根据协议类型设置不同的配置
proxy_configs = {
"socks5": {"timeout": 30, "retries": 3},
"http": {"timeout": 20, "retries": 5}
}
current_protocol = response_data.get("protocol", "http")
config = proxy_configs.get(current_protocol, proxy_configs["http"])
错误处理与数据验证
处理代理IP数据时,必须考虑各种异常情况。以下是一个完整的错误处理示例:
def parse_proxy_data(response_data):
try:
基础验证
if not isinstance(response_data, dict):
raise ValueError("响应数据格式错误")
提取关键信息
proxy_info = {
"ip": response_data.get("ip_address") or response_data.get("ip"),
"port": response_data.get("port"),
"protocol": response_data.get("protocol", "http").lower(),
"location": response_data.get("location", {}),
"expires": response_data.get("expires_in") or response_data.get("ttl")
}
数据完整性检查
if not all([proxy_info["ip"], proxy_info["port"]]):
raise ValueError("IP或端口信息缺失")
端口范围验证
if not 1 <= proxy_info["port"] <= 65535:
raise ValueError("端口号无效")
return proxy_info
except Exception as e:
print(f"解析代理数据时出错: {e}")
return None
实际应用案例
假设我们需要从ipipgo获取一批代理IP,并格式化为requests库可用的格式:
import requests
def get_ipipgo_proxies(api_key, count=5):
"""从ipipgo获取代理IP列表"""
headers = {"Authorization": f"Bearer {api_key}"}
params = {"count": count, "protocol": "socks5"}
response = requests.get("https://api.ipipgo.com/proxies",
headers=headers, params=params)
if response.status_code == 200:
data = response.json()
使用字典解析格式化代理信息
proxies_dict = {
f"{item['ip']}:{item['port']}": {
"protocol": item.get("protocol", "socks5"),
"country": item.get("country", "未知"),
"city": item.get("city", ""),
"expires_in": item.get("expires_in", 3600)
}
for item in data.get("proxies", [])
}
return proxies_dict
else:
print("获取代理IP失败")
return {}
使用示例
proxies = get_ipipgo_proxies("your_ipipgo_api_key")
for proxy_addr, info in proxies.items():
print(f"代理: {proxy_addr}, 位置: {info['country']}-{info['city']}")
Frequently Asked Questions
Q: 如何处理API返回中键名不一致的问题?
A: 可以创建键名映射字典,统一处理不同命名约定:
key_mapping = {
"ip_address": "ip",
"ip_addr": "ip",
"port_number": "port",
"proxy_port": "port"
}
def normalize_keys(data):
return {key_mapping.get(k, k): v for k, v in data.items()}
Q: 如何批量验证代理IP的有效性?
A: 使用多线程或异步方式并发测试:
import concurrent.futures
import requests
def test_proxy(proxy_addr):
try:
proxies = {"http": f"http://{proxy_addr}", "https": f"http://{proxy_addr}"}
response = requests.get("http://httpbin.org/ip", proxies=proxies, timeout=10)
return proxy_addr if response.status_code == 200 else None
except:
return None
def validate_proxies(proxy_list):
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(test_proxy, proxy_list)
return [result for result in results if result]
Q: ipipgo的代理IP如何配置使用?
A: ipipgo支持多种协议,配置示例如下:
HTTP代理配置
http_proxy = {
"http": "http://用户名:密码@gateway.ipipgo.com:端口",
"https": "http://用户名:密码@gateway.ipipgo.com:端口"
}
SOCKS5代理配置
socks5_proxy = {
"http": "socks5://用户名:密码@gateway.ipipgo.com:端口",
"https": "socks5://用户名:密码@gateway.ipipgo.com:端口"
}

