使用Python Requests模块能否获取请求响应中的TLS传输层信息?
获取requests请求的传输层TLS信息
嘿,这个问题问得很实用!requests本身默认不会直接返回TLS版本、密码套件这类传输层数据,但咱们可以借助它底层依赖的urllib3库,或者结合Python的ssl模块来拿到这些信息。下面给你两种可行的方法:
方法一:通过requests的响应对象获取底层连接信息
这种方法最直接,利用requests会话保持连接的特性,拿到底层的SSL连接对象后提取信息:
import requests # 创建会话以保持连接 session = requests.Session() response = session.get('https://yahoo.com') # 获取底层urllib3的连接实例 connection = response.raw._connection # 提取TLS版本和密码套件(仅当连接是SSL连接时有效) if hasattr(connection.sock, 'version'): tls_version = connection.sock.version() print(f"服务器选定的TLS版本: {tls_version}") if hasattr(connection.sock, 'cipher'): cipher_info = connection.sock.cipher() print(f"使用的密码套件: {cipher_info[0]}") # cipher()返回元组,第一个元素是套件名称
注意:这个方法依赖于requests底层的实现细节,不同版本的requests/urllib3可能略有差异,而且必须在连接未关闭时获取(用会话保持连接就能避免连接被立即释放)。
方法二:手动配置SSL上下文,自定义获取握手信息
如果需要更可控的方式,比如在握手阶段就获取详细信息,可以结合Python的ssl模块自定义SSL上下文,再传给requests的适配器:
import requests from requests.adapters import HTTPAdapter import ssl class TLSInfoAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): # 创建自定义SSL上下文 context = ssl.create_default_context() # 可选:设置允许的TLS版本 # context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 # 重写wrap_socket方法,捕获握手后的信息 original_wrap_socket = context.wrap_socket def wrapped_socket(sock, server_hostname=None, **kwargs): ssl_sock = original_wrap_socket(sock, server_hostname=server_hostname, **kwargs) # 在这里获取TLS信息 print(f"TLS版本: {ssl_sock.version()}") print(f"密码套件: {ssl_sock.cipher()[0]}") return ssl_sock context.wrap_socket = wrapped_socket kwargs['ssl_context'] = context super().init_poolmanager(*args, **kwargs) # 使用自定义适配器 session = requests.Session() session.mount('https://', TLSInfoAdapter()) response = session.get('https://yahoo.com')
这种方法更灵活,能在连接建立时就捕获传输层信息,还可以自定义SSL的配置规则。
内容的提问来源于stack exchange,提问作者user9371654
相关产品推荐
相关产品推荐

