给 IP 出口做一次"体检":用 Python 测匿名度和真实出口位置
给 IP 出口做一次"体检":用 Python 测匿名度和真实出口位置
为什么要自己测
服务商页面写的"高匿"、"原生"、"住宅"这些词,落到代码里到底是什么效果,我一般不完全信。自己跑一次脚本,至少能确认三件事:服务端看到的出口 IP 是什么、有没有暴露本地信息、以及这个 IP 归属地和 ISP 是不是我想要的。
这篇文章只聊前两个:匿名度和出口位置。DNS 泄漏因为发生在更底层,代码测不准,我一般用专业工具做那一步。
一、匿名度检测
思路
通过代理访问 httpbin.org/get,这个接口会把服务端收到的请求头原样返回。我们看返回的 headers 里有没有泄露真实 IP 或代理特征的头。
需要关注的头
| Header | 含义 | 危险程度 |
|---|---|---|
X-Forwarded-For |
代理链路上经过的 IP | 若包含你的真实 IP,匿名度很低 |
X-Real-Ip |
部分反向代理会带 | 可能暴露真实 IP |
Via |
经过的代理服务器标识 | 暴露代理存在,但不一定会泄露真实 IP |
Proxy-Connection |
HTTP 代理连接标识 | requests 自己可能带上,不代表泄露真实 IP |
怎么理解结果
- 透明代理:
origin字段显示的是你的真实 IP,或X-Forwarded-For里包含你的真实 IP。这种情况基本不能用。 - 匿名代理:
origin是代理 IP,但返回头里有Via、Proxy-Connection等特征。目标站知道你在用代理,但不知道真实 IP。 - 高匿代理:
origin是代理 IP,且没有明显代理特征头。这是最理想的情况。
不过要注意,Proxy-Connection 是 requests 在走 HTTP 代理时自己加上的,所以看到它不要太紧张,真正要盯的是 X-Forwarded-For 里有没有出现你的本地 IP。
二、出口位置查询
思路
用 ip-api.com/json/ 查询代理出口 IP 的地理位置和 ASN。这个接口对个人非商业使用免费,无需 key。
为什么看 ASN
ASN(自治系统号)比城市名更靠谱。有些代理商会标注"美国纽约",但 ASN 一查是数据中心或云计算厂商。看 ASN 能帮你判断这是住宅 ISP、机房还是 CDN 出口。
静态和动态 IP 的区别
- 静态住宅 IP:连续跑多次,出口 IP 不变,ASN 归属稳定。
- 动态住宅 IP:每次请求可能换 IP,位置和 ASN 也可能跟着变,所以单次结果只能代表这一次会话。
三、完整脚本
import json
import requests
PROXY = "http://user:pass@host:port" # 替换成你自己的代理
def fetch(url, headers=None):
proxies = {"http": PROXY, "https": PROXY}
r = requests.get(url, proxies=proxies, headers=headers, timeout=10)
return r.json()
def check_anonymity():
data = fetch("https://httpbin.org/get")
headers, origin = data["headers"], data["origin"]
found = {h: headers.get(h) for h in ["X-Forwarded-For", "X-Real-Ip", "Via", "Proxy-Connection"] if headers.get(h)}
print(f"\n出口 IP:{origin}")
print(json.dumps(found, ensure_ascii=False) if found else "未发现代理特征头")
xff = found.get("X-Forwarded-For", "")
if origin in xff:
print("匿名度:低(可能泄露真实 IP)")
elif found:
print("匿名度:中(隐藏真实 IP,但可能暴露代理存在)")
else:
print("匿名度:高")
def check_location():
data = fetch("http://ip-api.com/json/", headers={"User-Agent": "Mozilla/5.0"})
print(f"\n出口:{data.get('city')}, {data.get('country')}")
print(f"ISP:{data.get('isp')}")
print(f"ASN:{data.get('as')}")
if __name__ == "__main__":
try:
check_anonymity()
check_location()
except Exception as e:
print("请求失败:", e)
四、关于 DNS 泄漏
代码层面很难精确检测 DNS 泄漏,因为 DNS 查询发生在网络层,requests 走的是应用层。Python 里 socket.gethostbyname 这类调用甚至会绕过代理配置直接走本地 DNS。
所以我的习惯是:脚本只做辅助判断,真正的 DNS 泄漏用专业工具检测。跑完上面的脚本后,如果 check_location() 返回的 ISP/城市和代理购买地区一致,泄漏风险相对低;如果显示本地运营商,那就需要重点排查代理客户端的 DNS 转发设置。
我的使用习惯
- 新拿到一批 IP,先跑一遍这个脚本,心里有个底。
- 不迷信"高匿"这两个字,只看
httpbin.org/get返回的实际头。 - 对动态 IP 会多跑几次,避免被单次结果误导。
- 这段代码只测 HTTP/HTTPS 代理;SOCKS5 代理需要把
PROXY改成socks5://...,并安装requests[socks]。
浙公网安备 33010602011771号