Python爬虫中如何处理HTTPS请求的问题?

笔者在 app 抓包的时候发现问题。

我用的 charles

比如抓包美团,手机配置代理后,美团就请求不到数据。

后来 google 后知道人家用了 ssl,这个证书在 charles 的 ca 里没有,所以通不过。

嗯,好吧,那就常规的 app,charles 可以抓包

我在写爬虫时候,根据抓包的 url cookie header 就可以去请求数据了。

这里我就突然困惑了,即使可以抓包,也是因为安装了 ca,而我在用 requests 库时候,并没有带任何证书,服务器仍旧会给我反馈,那么在爬虫层面 http 和 https 就没有区别了

这是为什么呢?


Python爬虫中如何处理HTTPS请求的问题?

4 回复

手动捂脸
刚刚我想明白了
平时我一直用的代理
偶尔用本地 ip 去请求是时候会 SSL 报错
requests 这个库去进行 https 请求也需要带 ca 的


import requests
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
import ssl

# 方案1:直接忽略证书验证(仅测试环境使用)
def simple_https_request():
    response = requests.get('https://example.com', verify=False)
    return response.text

# 方案2:自定义SSL上下文(处理特定证书问题)
class CustomSSLAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        kwargs['ssl_context'] = ctx
        return super().init_poolmanager(*args, **kwargs)

def custom_ssl_session():
    session = requests.Session()
    session.mount('https://', CustomSSLAdapter())
    return session.get('https://example.com')

# 方案3:指定自定义证书路径
def with_custom_cert():
    response = requests.get(
        'https://example.com',
        verify='/path/to/certificate.pem'  # 或使用 cert=('client.cert', 'client.key')
    )
    return response

# 方案4:调整协议版本(解决协议协商失败)
class TLSAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        ctx = ssl.create_default_context()
        ctx.minimum_version = ssl.TLSVersion.TLSv1_2  # 强制使用TLS1.2+
        kwargs['ssl_context'] = ctx
        return super().init_poolmanager(*args, **kwargs)

# 完整示例:处理自签名证书+超时设置
def robust_https_request(url, timeout=10):
    session = requests.Session()
    
    # 配置SSL适配器
    adapter = TLSAdapter()
    session.mount('https://', adapter)
    
    # 设置请求头模拟浏览器
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    
    try:
        response = session.get(
            url,
            headers=headers,
            timeout=timeout,
            verify=False,  # 生产环境应替换为真实证书
            allow_redirects=True
        )
        response.raise_for_status()
        return response
        
    except requests.exceptions.SSLError as e:
        print(f"SSL错误: {e}")
    except requests.exceptions.Timeout:
        print("请求超时")
    except Exception as e:
        print(f"其他错误: {e}")

# 使用示例
if __name__ == '__main__':
    # 简单请求(测试用)
    print(simple_https_request()[:100])
    
    # 完整请求示例
    result = robust_https_request('https://httpbin.org/get')
    if result:
        print(f"状态码: {result.status_code}")

HTTPS请求主要问题集中在证书验证、协议版本和SSL配置三方面。核心是创建自定义的SSL上下文或适配器来处理特定站点的证书问题,但生产环境务必使用有效证书。

简单说就是配好SSL上下文啥都能爬。

你好像对 hash 有所误解

我觉得你应该先搞清楚 http 和 https,然后了解一下 MITM,然后了解一下 ssl pinning

回到顶部