You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中检测网站是否支持HTTP/2协议

如何在Python中批量检测网站是否支持HTTP/2?

问题背景

我尝试通过Socket将HTTP/1连接升级为HTTP/2以获取101 Switching Protocol响应,测试了google.com、twitter.com这类支持HTTP/2的大型网站,但未得到预期结果:使用升级请求返回400错误;手动设置ALPN协议['h2']后,google.com返回帧响应,twitter.com返回空帧。现在需要基于网站列表(wordlist)批量检测,请问如何在Python中正确检测网站是否支持HTTP/2?

你的尝试代码

针对twitter.com的请求代码

import socket
import ssl

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
context = ssl.create_default_context()
context.set_ciphers(cipher)
sock.connect(('twitter.com', 443))
sock = context.wrap_socket(sock, server_hostname='twitter.com')
sock.sendall(bytes('GET h2://twitter.com/ HTTP/1.1\r\nHost: twitter.com\r\nConnection: Upgrade, HTTP2-Settings\r\nUpgrade: h2\r\nHTTP2-Settings: \r\nAlt-Svc: h2=":443"\r\n\r\n',encoding='utf-8'))

sock.settimeout(5)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
line = str(sock.recv(10000))
print(line)

针对google.com的请求代码

sock.connect(('www.google.com', 443))
sock = context.wrap_socket(sock, server_hostname='www.google.com')
sock.sendall(bytes('GET / HTTP/1.1\r\nHost: www.google.com\r\nConnection: Upgrade, HTTP2-Settings\r\nUpgrade: h2\r\nHTTP2-Settings: \r\n\r\n',encoding='utf-8'))

设置ALPN的代码片段

context.set_alpn_protocols(['h2'])

正确的批量检测方案

HTTP/2的主流启用方式是通过ALPN协议协商(而非HTTP/1升级),绝大多数现代网站只支持ALPN方式的HTTP/2,不支持HTTP/1升级(这就是你用Upgrade请求返回400的原因)。因此正确的检测方式是在SSL握手阶段设置ALPN列表,然后检查协商结果。

以下是可批量检测的Python代码:

import socket
import ssl
from concurrent.futures import ThreadPoolExecutor

def check_http2_support(host):
    result = {"host": host, "supports_http2": False, "error": None}
    try:
        # 创建TCP socket
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(10)
        # 连接443端口
        sock.connect((host, 443))
        
        # 创建SSL上下文,设置ALPN协议列表(h2是HTTP/2的标识)
        context = ssl.create_default_context()
        context.set_alpn_protocols(['h2', 'http/1.1'])
        
        # 握手并获取协商的协议
        with context.wrap_socket(sock, server_hostname=host) as ssock:
            negotiated_protocol = ssock.selected_alpn_protocol()
            if negotiated_protocol == 'h2':
                result["supports_http2"] = True
    except Exception as e:
        result["error"] = str(e)
    finally:
        sock.close()
    return result

def batch_check(wordlist_path, max_workers=10):
    # 读取网站列表
    with open(wordlist_path, 'r', encoding='utf-8') as f:
        hosts = [line.strip() for line in f if line.strip()]
    
    # 多线程批量检测
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(check_http2_support, hosts))
    
    # 输出结果
    for res in results:
        status = "支持" if res["supports_http2"] else "不支持"
        error_msg = f" | 错误: {res['error']}" if res["error"] else ""
        print(f"{res['host']}: {status} HTTP/2 {error_msg}")

# 示例调用
if __name__ == "__main__":
    batch_check("website_list.txt")

关键说明

  • ALPN协商是标准方式:HTTP/2的官方推荐启用方式是TLS握手时通过ALPN协商,绝大多数网站(包括Google、Twitter)只支持这种方式,不支持HTTP/1升级请求。
  • 多线程提升效率:批量检测时用多线程可以大幅缩短总耗时,避免单线程等待超时的低效问题。
  • 错误处理:代码包含超时、连接失败等异常处理,确保批量检测不会因单个网站故障中断。

内容的提问来源于stack exchange,提问作者user19219732

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:33:28