直接用requests调接口大概率失败,因券商数据依赖websocket或长连接,需token、设备指纹、referer白名单等验证;抓包应关注ws://链接,用websocket-client解析二进制帧并手动解包。

为什么直接用 requests 调接口大概率失败
多数券商或行情平台(如东方财富、同花顺、雪球)的实时交易数据,实际由 WebSocket 或轮询长连接提供,前端通过 JavaScript 动态渲染。你用 requests 直接 GET 一个 URL,返回的往往是空数据、占位 HTML 或加密参数校验失败的 403 / 401 响应。
根本原因不是“没登录”,而是:接口带时间戳签名、设备指纹、Referer 白名单、甚至需要前置 WebSocket 握手获取 token。比如东方财富的 flash2018 接口,必须先请求 /api/flash2018/getToken,再用该 token 拼进后续 ws 连接地址。
- 别硬刚 Referer 或 User-Agent —— 它们只是第一道门,后面还有 session 绑定和心跳校验
- 抓包时重点看
ws://或wss://开头的连接,不是https://的 REST 接口 - 浏览器开发者工具 Network → WS → Messages 标签页里,每条
text消息才是真实行情帧(通常是 JSON 或二进制协议)
用 websocket-client 连接并解析原始行情帧
以雪球 Web 版为例,其行情推送走的是标准 WebSocket,但 payload 是自定义二进制格式(前 4 字节为长度,后接 JSON)。Python 默认不支持解包,得手动处理。
实操步骤:
- 安装:
pip install websocket-client - 用
websocket.create_connection()连接,注意传origin和header(如Origin: https://www.php.cn/link/7273faa69283ac4a72e9f06033c36011),否则被拒绝 - 收到消息后,先用
len(msg) > 4判断是否为二进制帧;若是,msg[4:].decode('utf-8')才是 JSON 字符串 - 关键字段通常在
data键下,例如data['quote']['current']是最新价,data['quote']['volume']是成交量
示例片段:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
import websocket
import json
<p>def on_message(ws, message):
if isinstance(message, bytes) and len(message) > 4:
try:
payload = message[4:].decode('utf-8')
data = json.loads(payload)
print(data.get('symbol'), data['quote'].get('current'))
except (UnicodeDecodeError, json.JSONDecodeError):
pass # 忽略脏数据</p><p>ws = websocket.WebSocket()
ws.connect("wss://hq.snowball.com/websocket",
origin="<a href="https://www.php.cn/link/7273faa69283ac4a72e9f06033c36011">https://www.php.cn/link/7273faa69283ac4a72e9f06033c36011</a>",
header=["Sec-WebSocket-Protocol: binary"])
ws.on_message = on_message</p>
绕过反爬的关键参数:如何稳定获取有效 token
像同花顺 iFinD、腾讯自选股这类平台,WebSocket 地址本身是动态生成的,依赖前端 JS 计算出的 token 或 cid,且 5–10 分钟失效。硬写死会断连。
可行解法不是逆向全部 JS,而是复用浏览器已加载的上下文:
- 用
selenium启动无头 Chrome,打开目标页面,等 JS 执行完后,用driver.execute_script("return window.TOKEN")提取变量值 - 更轻量的方式是监听 Network 面板中第一个 WebSocket 请求的 Request URL,复制完整地址(含 query 参数),其中
token=xxx就是你要的 - 某些平台(如聚宽)提供官方 Python SDK,内部已封装 token 自动刷新逻辑,直接调
jqdatasdk.get_price()更省事
注意:token 通常绑定 IP + UA + 浏览器指纹,换环境就得重取,不能多机共享
高频轮询 vs WebSocket:选哪个更稳
如果目标平台只开放了 HTTP 接口(如新浪 hq.sinajs.cn),就只能轮询。但要注意:每秒多次请求极易触发限流,返回 503 Service Temporarily Unavailable 或空响应。
- 新浪接口单次最多查 50 只股票,URL 长度超限会截断,需分批拼接
list=sh600000,sz000001,... - 轮询间隔建议 ≥ 3 秒,加随机抖动(如
time.sleep(3 + random.uniform(0, 1))),避免被识别为机器人 - WebSocket 稳定性高、延迟低(通常 on_error 和
on_close,失败后延迟 1–3 秒重连,最多试 5 次
真正难的不是连上,而是维持连接不被踢:心跳包必须按时发(比如每 25 秒 send {"action":"ping"}),且响应超时阈值设为 30 秒以上
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










