脚本如何检测代理有效性

wen 实用脚本 29

本文目录导读:

脚本如何检测代理有效性

  1. 基础连通性检测(Python + requests)
  2. 匿名性检测(检查真实IP是否泄露)
  3. 批量检测 + 并发(提升效率)
  4. Shell脚本方式(适合Linux/Unix)
  5. 高级检测:DNS泄露和WebRTC泄露
  6. 关键检测指标总结
  7. 注意事项
  8. 推荐工具类(无需重复造轮子)

连通性(是否能建立连接)和匿名性(是否暴露真实IP),以下是几种常见的脚本检测方法及代码示例:

基础连通性检测(Python + requests)

这是最直接的方法,通过代理访问一个固定网站,检查是否能够成功返回响应。

import requests
import socket
def check_proxy(proxy_url, timeout=5):
    """
    检测代理是否可用
    :param proxy_url: 如 http://127.0.0.1:8080 或 socks5://127.0.0.1:1080
    :param timeout: 超时时间(秒)
    :return: (是否可用, 响应时间, 异常信息)
    """
    proxies = {
        "http": proxy_url,
        "https": proxy_url
    }
    try:
        start_time = time.time()
        # 使用百度或 httpbin.org 验证(需稳定)
        response = requests.get(
            "http://httpbin.org/ip",  # 返回你的IP地址
            proxies=proxies,
            timeout=timeout,
            headers={"User-Agent": "Mozilla/5.0"}
        )
        elapsed = time.time() - start_time
        if response.status_code == 200:
            return True, round(elapsed, 2), None
        else:
            return False, None, f"HTTP状态码:{response.status_code}"
    except requests.exceptions.ConnectTimeout:
        return False, None, "连接超时"
    except requests.exceptions.ProxyError as e:
        return False, None, f"代理错误:{str(e)[:50]}"
    except Exception as e:
        return False, None, f"未知错误:{str(e)[:50]}"
# 使用示例
import time
proxy = "http://192.168.1.100:8080"
is_valid, delay, error = check_proxy(proxy)
print(f"代理 {proxy} 可用?{is_valid},延迟:{delay}s,错误:{error}")

匿名性检测(检查真实IP是否泄露)

通过代理访问返回IP的网站,对比代理IP与真实IP是否相同。

def check_anonymity(proxy_url, timeout=5):
    """
    检测代理匿名性
    :return: (透明/匿名/高匿, 检测到的IP)
    """
    proxies = {
        "http": proxy_url,
        "https": proxy_url
    }
    try:
        # 1. 先获取真实IP(不使用代理)
        real_ip_response = requests.get(
            "http://httpbin.org/ip",
            timeout=timeout,
            headers={"User-Agent": "Mozilla/5.0"}
        )
        real_ip = real_ip_response.json().get("origin", "").split(",")[0].strip()
        # 2. 通过代理获取目标IP
        proxy_response = requests.get(
            "http://httpbin.org/ip",
            proxies=proxies,
            timeout=timeout,
            headers={"User-Agent": "Mozilla/5.0"}
        )
        proxy_ip = proxy_response.json().get("origin", "").split(",")[0].strip()
        # 3. 额外检测(查看是否带有客户IP信息)
        headers_response = requests.get(
            "http://httpbin.org/headers",
            proxies=proxies,
            timeout=timeout,
            headers={"User-Agent": "Mozilla/5.0"}
        )
        headers = headers_response.json().get("headers", {})
        # 检查是否泄露客户IP(如 X-Forwarded-For, X-Real-IP)
        has_leak = any(
            key in headers and headers[key] != proxy_ip
            for key in ["X-Forwarded-For", "X-Real-IP", "Via"]
        )
        if proxy_ip == real_ip:
            return "透明代理", proxy_ip
        elif has_leak:
            return "匿名代理(有泄露)", proxy_ip
        else:
            return "高匿代理", proxy_ip
    except Exception as e:
        return f"检测失败:{str(e)[:50]}", None

批量检测 + 并发(提升效率)

使用 concurrent.futures 对多个代理进行并发检测。

import concurrent.futures
def batch_check(proxy_list, max_workers=20, timeout=5):
    """批量检测代理列表"""
    results = {}
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_proxy = {
            executor.submit(check_proxy, proxy, timeout): proxy 
            for proxy in proxy_list
        }
        for future in concurrent.futures.as_completed(future_to_proxy):
            proxy = future_to_proxy[future]
            try:
                is_valid, delay, error = future.result()
                results[proxy] = {
                    "valid": is_valid,
                    "delay": delay,
                    "error": error
                }
            except Exception as e:
                results[proxy] = {"valid": False, "delay": None, "error": str(e)[:50]}
    return results
# 使用示例
proxy_batch = [
    "http://192.168.1.100:8080",
    "http://10.0.0.1:3128",
    "http://8.8.8.8:8888"
]
results = batch_check(proxy_batch)
for proxy, info in results.items():
    print(f"{proxy} -> 有效:{info['valid']}, 延迟:{info['delay']}s")

Shell脚本方式(适合Linux/Unix)

创建一个简单的bash脚本检测HTTP代理:

#!/bin/bash
# 检测代理是否可用
# 参数:代理地址和端口
check_proxy() {
    local proxy=$1
    local port=$2
    local timeout=5
    # 使用curl检测
    result=$(curl --proxy "http://$proxy:$port" \
                  --connect-timeout $timeout \
                  --max-time $timeout \
                  -s -o /dev/null -w "%{http_code}" \
                  http://httpbin.org/ip 2>/dev/null)
    if [ "$result" = "200" ]; then
        # 获取代理显示的真实IP
        ip=$(curl --proxy "http://$proxy:$port" \
                  --connect-timeout $timeout \
                  -s http://httpbin.org/ip 2>/dev/null | grep -o '"origin": "[^"]*"' | cut -d'"' -f4)
        echo "可用 | IP: $ip | 端口: $port"
        return 0
    else
        echo "不可用 | HTTP状态: $result"
        return 1
    fi
}
# 调用示例
check_proxy "192.168.1.100" "8080"

高级检测:DNS泄露和WebRTC泄露

对于一些需要高匿名性的场景(如爬虫规避反爬),还需检测DNS和WebRTC是否泄露。

# 需要安装 pproxy 用于测试DNS泄露
def check_dns_leak(proxy_url):
    """
    检测DNS是否通过代理解析(防止DNS泄露)
    """
    # 使用代理访问一个域名,检查DNS解析是否通过代理
    test_domain = "httpbin.org"
    try:
        # 设置代理的DNS解析
        # 实际检测可以对比:直接解析IP vs 通过代理访问IP
        direct_ip = socket.gethostbyname(test_domain)
        # 通过代理访问(利用响应中的IP)
        # ...(此处省略具体实现,需结合代理类型)
        return True  # 示例简化
    except:
        return False

关键检测指标总结

检测项 方法 标准
连通性 请求目标网站且返回200 成功率>90%
响应速度 记录请求耗时 lt;3秒
匿名性 比较真实IP与代理IP是否一致 高匿:完全不同
稳定性 连续请求5次,成功率 连续失败阈值<2次
协议支持 分别测试HTTP/HTTPS/SOCKS 需全部通过
DNS泄露 检查DNS请求是否经代理 必须经代理
多站点兼容 测试不同地域的站点 避免特定站点限制

注意事项

  1. 目标网站选择:不要只测百度/Google,有些代理可能针对特定网站被封。
  2. 超时设置:一般设5-10秒,太短容易误判,太长影响效率。
  3. IP频率限制:批量检测时注意不要触发目标网站的验证码/封IP。
  4. HTTPS支持:有些代理只支持HTTP,检测时需分别测试。
  5. 自定义错误处理:代理返回403、429等状态码表示被目标拒绝,也应视为"不可用"。

推荐工具类(无需重复造轮子)

  • Pythonrequests + SOCKSpip install PySocks
  • 专业库proxy-scraper-checker(支持多线程、自动提取)
  • 命令行curl -xproxychains(Linux测代理链)

根据你的具体需求(爬虫、科学上网、还是商业应用),选择合适的检测粒度和并发规模,如果是大规模代理池,建议加上连续失败后降级逻辑(如失败3次后视为死亡代理,移除出池)。

抱歉,评论功能暂时关闭!