Python行情API量化 02:顺序拉 20 要 2 秒?并发批量把时间压到 0.5 秒

需要补充说明的是, 因为样本数量比较小, 所以绝对耗时会随着网络情况而产生波动。

不过, 并发处理和顺序处理相比, 在加速比这一方面表现是稳定的, 具体而言, 当数据量级变大的时候, 它们之间的差距会变得非常显著, 比如在有五千个样本的情况下, 采用顺序方式可能得花上几十分钟, 但是使用并发手段可以把时间压缩到几分钟以内。

二、并发: + 共享

直观的做事方法是, 开启数量为 N 个的线程, 并且规定每只线程对应处理一个具体任务。但是这里有一个需要注意的坑, 那就是每个线程都需要新建一个对应的 TCP 连接, 这意味着连接的复用功能无法生效, 从而导致整体的运行速度反而变得更慢了。

所谓的正确处理方式, 其实就是把这个东西单拿出来。把它共享给所有正在运行的线程用。一旦使用了连接复用的技术之后, 速度提升的效果会非常明显。

from .

TOKEN = "

这里是TEST-API-TOKEN-MOMA, 它是官方演示证书的一个标记, 当使用它时返回的是预先设置好的演示数据, 这一点需要替换成你自己实际使用的证书。

BASE = ""

sess = .() # 关键: 共享一个, 连接复用。

def (code):

把基准地址加上三个斜杠,再加上代码, 然后再跟上d和n还有令牌, 后面再附上问号以及开始时间和结束的这两个参数。

我们让会话对象去拿到那个网页的源码, 把等待时间设为四十秒之后, 再把拿到的东西转换成json数据格式。

获取code的值,然后对rows进行类型判断, 如果rows是列表类型的话就取len(rows)的结果, 否则就取0。

codes =

".SZ", ".SZ", ".SH"

你手里的这些股票所构成的那个列表。

with (=5) as ex:

for code, n in ex.map(, codes):

在程序运行期间, 打印出由代码加上对应的条数组成的信息串。

真实输出(20 只样本):

顺序: 2344 ms

在并发度为5的时候, 耗时是590毫秒, 加速比达到了3.97倍。

三、在进行限流操作的时候, 一定不要把服务端打挂。

虽然并发处理起来感觉很爽, 但是要是没有节制地去搞并发, 那么就会触发服务器端的频率保护机制, 这种情况会导致响应变慢, 甚至还会暂时拒绝服务。在工程实践当中, 我们需要使用信号量来给并发的数量进行封顶。

from . ,

就是那个括号空着的调用。

sem 的初始值是五, 它的含义是让最多五个飞行相关的请求能够同时处于正在执行的活跃状态。

def (code):

在进入之前要获取信号量, 然后在退出之后来释放。

把基准地址加上三个斜杠,再加上代码, 然后再跟上d和n还有令牌, 后面再附上问号以及开始时间和结束的这两个参数。

我们让会话对象去拿到那个网页的源码, 把等待时间设为四十秒之后, 再把拿到的东西转换成json数据格式。

获取code的值,然后对rows进行类型判断, 如果rows是列表类型的话就取len(rows)的结果, 否则就取0。

with (=10) as ex:

结果是: 一个空字典, 因为代码里的写法在里面会报错。

for fut in ():

code, n = fut.()

在程序运行期间, 打印出由代码加上对应的条数组成的信息串。

(5) 你要保证线程池开启的数量是10个, 不过同时进行的请求只能有5个在跑, 这样就能既让速度提升起来, 又遵守规定。

四、这里出现的这个错误体, 它并不是一个符合要求的 JSON 格式数据, 这确实是一个非常大的坑。

这类行情接口里面的错误返回的内容是纯文字的形式, 而不是JSON的格式。举个例子, 当证书出现无效情况的时候, 它返回给用户的是一段字符串, 这段字符串的具体内容是"证书不存在", 并不是一种结构化的对象形式, 也就是类似那种包含了代码数字和具体信息描述这样的数据形式不会呈现出来。

所以不可以进行无脑的 r.json() 操作, 因为证书错误、网络抖动和超时情况, 都可能会使得 .json() 这个方法抛出异常, 正确的写法是:

def (code):

把基准地址加上三个斜杠,再加上代码, 然后再跟上d和n还有令牌, 后面再附上问号以及开始时间和结束的这两个参数。

try:

r 等于 sess.get(url, =40)

r.先判断一下 HTTP 状态码的情况, 如果返回的状态码是 403, 那就说明没有 token。但是如果返回的是 200 加上一些文本内容, 那就可能表示证书出现了错误。

data = r.json()

判断当前的数据列表是否为空, 如果不为空的话, 就进行后续操作。

code, None, f"非预期返回: {str(data)}"

code, data, None

. as e:

这段代码的返回值第一个部分是错误代码, 第二个部分是空值, 第三个部分是一个说明网络出现异常的字符串。

先执行那个判断状态的动作, 然后再进行 .json() 的操作, 把异常的情况分别拿到里面去捕获。这就是在并发批量处理场景下, 实现"一只失败不影响整体"这一情况的最基础做法。

五、完整的骨架设计当中, 它涉及了对并发的处理, 还设置了流量限制, 同时提供了容错机制, 并且实现了数据的汇总功能。

把这上边的那三块内容进行拼合, 得到的就是一个可以用来投入生产环境进行使用的, 能够实现并发操作的批量拉取数据的架构模型。

,

from . ,

TOKEN = "

TEST-API-TOKEN-MOMA-"

BASE = ""

就是那个括号空着的调用。

sem = .(5)

def (code):

with sem:

把基准地址加上三个斜杠,再加上代码, 然后再跟上d和n还有令牌, 后面再附上问号以及开始时间和结束的这两个参数。

try:

r = sess.get(url, =40); r.()

data = r.json()

把代码和数据放在一起, 如果数据是列表类型的话就使用这个列表, 如果不是列表类型的话就使用空值是None。

. as e:

code, , f"网络异常: {e}"

def (codes):

, = {}, {}

with (=10) as ex:

结果是: 一个空字典, 因为代码里的写法在里面会报错。

for fut in ():

code, data, err = fut.()

这个情况, 如果是错误了的话, 等于说是错误或者叫做数据。

,

if == "":

codes =

这实际上是一个代码片段, 它的意思是,使用获取到的会话对象sess去请求那个包含了BASE链接、hslt以及list还有TOKEN信息的完整网址, 然后把得到的JSON格式的数据里面的东西一个一个取出来放到s里面, 就这样反复地去执行这个操作。

好的情况被确定下来, 而对应的坏的情况则由这些编码所构成。

结果已经打印出来, 内容是显示成功处理的数量加上单位"只", 还有失败处理的数量同样也加上单位"只"。

要点回顾:

所谓共享,其实也就是连接复用这回事, 它比起那种为每个线程都重新新建一个连接的做法来, 速度要快出不少。

所谓限流, 就是让并发量提速的时候, 也不会把服务端给打挂。

先把那个 HTTP 的状态给判断清楚, 然后才开始去解析数据, 遇到异常情况的话, 就要把它分开放置、分开抓到。

这次对容错的情况进行了汇总, 具体的含义是一只失败了就不会影响到整体进度, 等到最后的时候再一起来查看。

六、小结

顺序拉取这种方式, 其实是工程化里面最大的一个隐形杀手。慢的根本原因不是计算过程, 而是网络等待时间的不断累积效应。如果我们采用并行的方式配合共享资源的管理机制, 再加上信号量的限流操作, 那么就可以把原本耗时几十倍的问题给压下来。

这样做的时候, 同时还要守住房务端关于频率设置的相关规则。下一篇的内容我们主要来解决另一个隐形的杀手问题。也就是当网络发生抖动的时候, 程序不会一下子全面失败。我们通过实现自动重试的策略, 并且结合指数退避的算法, 能让脚本自己去扛过那些毛刺状的干扰情况。

请注意, 本文是一篇技术方面的分享文章。在所有的接口调用操作中, 这里所使用的数据全部都是基于官方演示证书所返回的结果来进行的。需要特别强调的是, 这个数据仅仅作为一个演示的用途。在实际开发或测试的时候, 用户必须将自己手上的官方实际证书进行替换操作。魔码云服。

相关推荐
伞伞悦读12 分钟前
【第81期】特征缩放怎么选:标准化、MinMax 与 Robust 的原理、泄漏对照和完整实验
人工智能·python·深度学习·机器学习
新*1 小时前
从一段 WebSocket 代码聊开:bytes 不是 zlib、binaryType 决定一切,15MB 大消息的零拷贝优化
javascript·python·websocket·性能优化·blob·zlib·arraybuffer
卷无止境3 小时前
mathmodel-figure-templates 以及两个上手案例
后端·python
锋行天下3 小时前
服务器 Python 2.7 装不了 langgraph-cli?用本地生成 Dockerfile 曲线救国
人工智能·后端·python
一条大祥脚4 小时前
深入理解 PyTorch FlexAttention:从 Score Mod 到 Mask Mod 的稀疏加速之道
人工智能·pytorch·python·注意力机制·flex attention·可编程注意力
2601_967980115 小时前
Python自动化办公:模块、库与样式调整教程
python·excel·自动化办公·openpyxl·样式调整
长沙三为智能科技5 小时前
GEO与传统SEO的5个关键差异:排名与被引用、关键词与答案型的全维度对比
python·aigc·seo·ai搜索·geo优化
莽夫搞战术5 小时前
【量化实战】单卡3090部署Hy-SimulMT-30B-A3B-Interleave同传大模型
大模型·量化·混元·语音翻译·simulmt·ai同传
量化分析码农6 小时前
【Python量化趋势跟踪实战 02】突破买入总被假突破坑:通道系统与入场时机
python