requests无法连接WebSocket地址,因其仅支持http/https协议,未实现WebSocket握手及帧解析;调用requests.get(ws://)会报InvalidSchema错误,且底层不处理Sec-WebSocket-Key校验与Sec-WebSocket-Accept生成。

requests 无法处理 WebSocket,这不是配置或技巧问题,而是协议层不兼容——它压根没实现 WebSocket 握手和帧解析能力。
为什么 requests 连不上 WebSocket 地址?
当你对 ws:// 或 wss:// 地址调用 requests.get(),会直接报 InvalidSchema 错误。因为 requests 只注册了 http 和 https 协议,根本不认识 ws。
即使你强行用 urllib3 拼接 TCP 连接,也过不了握手阶段:服务端要求客户端发送带 Sec-WebSocket-Key 的 Upgrade 请求,并校验返回的 Sec-WebSocket-Accept 值(SHA1 + base64),这步必须由专用库完成。
websocket-client 同步写法常见踩坑点
这个库适合调试或轻量任务,但新手常卡在三个地方:
- 没调用
ws.run_forever()—— 连上就退出,根本收不到消息 -
ws.on_message = handler写在on_open回调里 —— 首条消息可能已在回调执行前到达,导致丢失 - 收到
bytes类型消息却直接.decode('utf-8')—— 股票行情、IM 协议常用OPCODE_BINARY发送 Protobuf 或加密 payload,需先判断type(msg),再决定解码方式
异步场景优先选 websockets 库
如果你要并发连接多个行情源、做心跳保活、或集成进 FastAPI/asyncio 项目,websockets 是更干净的选择。它原生支持 async/await,不用手动管理线程;自动处理 PING/PONG 帧(只要传 ping_interval=20);错误类型也更明确(如 websockets.exceptions.ConnectionClosedError 可直接捕获)。
注意:它不提供开箱即用的重连逻辑,需要自己用 while True + try/except 包裹 connect(),并在断连后 sleep 几秒再重试,否则容易触发服务端限流。
立即学习“Python免费学习笔记(深入)”;
抓到数据却是乱码或空字段?先看 opcode 和协议封装
WebSocket 本身只负责传输帧,业务数据怎么组织完全由服务端定义。常见情况:
- 字段名被缩写或哈希(如
"p"代替"price")—— 查网页 JS 源码或反编译前端包,找map或enum定义 - 整个 payload 是 zlib 压缩过的 JSON —— 收到
bytes后先zlib.decompress(msg),再json.loads() - 使用自定义二进制协议(如币安的
BNB行情流)—— 必须按文档解析字段偏移,不能当字符串处理
真正难的从来不是连上 WebSocket,而是读懂服务端扔过来的那堆字节到底在说什么。


















