Python中如何判断一个代理IP支持哪种协议?

如题 现在一般请求一个 http 的网址也会自动跳转到 https 如百度,想知道怎么才能判断一个 ip 是否支持 http/https


Python中如何判断一个代理IP支持哪种协议?
8 回复

使用代理访问一个 https 地址试试。


import socket
import requests
from urllib.parse import urlparse

def check_proxy_protocols(proxy_ip, proxy_port, timeout=5):
    """
    检测代理IP支持的协议类型
    
    参数:
        proxy_ip: 代理IP地址
        proxy_port: 代理端口
        timeout: 连接超时时间(秒)
    
    返回:
        dict: 包含支持的协议和测试结果
    """
    results = {
        'http': False,
        'https': False,
        'socks4': False,
        'socks5': False
    }
    
    # 测试HTTP代理
    try:
        proxies = {
            'http': f'http://{proxy_ip}:{proxy_port}',
            'https': f'http://{proxy_ip}:{proxy_port}'  # 注意:很多HTTP代理也用于HTTPS
        }
        response = requests.get('http://httpbin.org/ip', 
                              proxies=proxies, 
                              timeout=timeout)
        if response.status_code == 200:
            results['http'] = True
            # 尝试HTTPS
            try:
                response = requests.get('https://httpbin.org/ip', 
                                      proxies=proxies, 
                                      timeout=timeout)
                if response.status_code == 200:
                    results['https'] = True
            except:
                results['https'] = False
    except:
        results['http'] = False
        results['https'] = False
    
    # 测试SOCKS5代理
    try:
        proxies = {
            'http': f'socks5://{proxy_ip}:{proxy_port}',
            'https': f'socks5://{proxy_ip}:{proxy_port}'
        }
        response = requests.get('http://httpbin.org/ip', 
                              proxies=proxies, 
                              timeout=timeout)
        if response.status_code == 200:
            results['socks5'] = True
    except:
        results['socks5'] = False
    
    # 测试SOCKS4代理
    try:
        proxies = {
            'http': f'socks4://{proxy_ip}:{proxy_port}',
            'https': f'socks4://{proxy_ip}:{proxy_port}'
        }
        response = requests.get('http://httpbin.org/ip', 
                              proxies=proxies, 
                              timeout=timeout)
        if response.status_code == 200:
            results['socks4'] = True
    except:
        results['socks4'] = False
    
    return results

def check_proxy_by_socket(proxy_ip, proxy_port, timeout=5):
    """
    使用socket直接测试代理协议支持(更底层的方法)
    """
    protocols = []
    
    # 测试HTTP代理
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((proxy_ip, proxy_port))
        sock.send(b'GET http://httpbin.org/ip HTTP/1.0\r\n\r\n')
        response = sock.recv(1024)
        if b'HTTP' in response and b'200' in response:
            protocols.append('http')
        sock.close()
    except:
        pass
    
    # 测试SOCKS5(简化版)
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((proxy_ip, proxy_port))
        # SOCKS5握手
        sock.send(b'\x05\x01\x00')
        response = sock.recv(2)
        if response == b'\x05\x00':
            protocols.append('socks5')
        sock.close()
    except:
        pass
    
    return protocols

# 使用示例
if __name__ == "__main__":
    # 测试代理
    proxy_ip = "127.0.0.1"  # 替换为实际代理IP
    proxy_port = 1080       # 替换为实际代理端口
    
    print("方法1: 使用requests测试")
    results = check_proxy_protocols(proxy_ip, proxy_port)
    print(f"测试结果: {results}")
    
    print("\n支持的协议:")
    for protocol, supported in results.items():
        if supported:
            print(f"  ✓ {protocol.upper()}")
    
    print("\n方法2: 使用socket测试")
    protocols = check_proxy_by_socket(proxy_ip, proxy_port)
    print(f"支持的协议: {protocols}")

核心原理:

  1. HTTP/HTTPS代理:通过requests库设置代理,尝试访问测试网站
  2. SOCKS代理:使用socks5://或socks4://协议前缀测试
  3. 底层检测:使用socket直接发送协议握手包验证

关键点:

  • HTTP代理通常也支持HTTPS(通过CONNECT方法)
  • SOCKS5代理更通用,支持TCP和UDP
  • 实际使用时需要安装requestsrequests[socks]扩展

一句话建议: 用requests多协议轮询测试最可靠。

https 的可以主要是 http 的

一样的。不尝试一次就不清楚代理能不能用,比如有的代理不管访问什么网址都会返回同一个页面。除了访问一次加验证返回内容,没有更容易的判断方法。

只能去尝试连接,拿 TCP 请求一下 80 443 端口,但是 TCP 通了也不一定就是标准的 HTTP HTTPS。

现在用 https://httpbin.org/get 做代理验证

如果我开了个 http 服务在 2333 端口呢?
没那么容易。。。

回到顶部