You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中更快调用API获取印度股市数据?

针对批量API请求的提速方案

你的场景属于典型的IO密集型任务,以下几个优化方向能大幅提升处理数千只股票的效率:

1. 复用HTTP连接

每次requests.get都会新建TCP连接,握手过程会消耗额外时间。用requests.Session复用连接池,能减少重复的TCP握手开销:

import requests

# 全局创建一个Session,所有请求复用同一个连接池
session = requests.Session()

def get_prices(stock):
    start_unix = 1669794745
    end_unix = start_unix + 1800
    interval = 1
    # 用f-string拼接URL更简洁
    url = f'https://priceapi.moneycontrol.com/techCharts/indianMarket/stock/history?symbol={stock}&resolution={interval}&from={start_unix}&to={end_unix}'
    
    with session.get(url) as resp:
        resp.raise_for_status()  # 主动捕获HTTP错误
        return resp.json()['c']  # 返回结果,不要在函数内print

2. 使用线程池替代手动管理线程

手动创建数千个线程会产生大量调度开销,线程池可以限制并发数、复用线程,同时代码更简洁:

from concurrent.futures import ThreadPoolExecutor

stocks = ['ACC','ADANIENT','ADANIGREEN','ADANIPORTS','ADANITRANS','AMBUJACEM','ASIANPAINT','ATGL','BAJAJ-AUTO','BAJAJHLDNG']

# max_workers设置并发数,建议先测试20-50,根据API限流和机器性能调整
with ThreadPoolExecutor(max_workers=30) as executor:
    # 批量提交任务并获取所有结果
    results = list(executor.map(get_prices, stocks))

# 统一处理结果
for stock, price in zip(stocks, results):
    print(f"{stock}: {price}")

3. 改用异步请求(高并发场景最优解)

异步框架aiohttp不需要线程切换,能更高效地处理大量IO请求,适合数千只股票的场景:

import aiohttp
import asyncio

async def get_prices_async(session, stock):
    start_unix = 1669794745
    end_unix = start_unix + 1800
    interval = 1
    url = f'https://priceapi.moneycontrol.com/techCharts/indianMarket/stock/history?symbol={stock}&resolution={interval}&from={start_unix}&to={end_unix}'
    
    async with session.get(url) as resp:
        resp.raise_for_status()
        data = await resp.json()
        return (stock, data['c'])

async def main():
    stocks = ['ACC','ADANIENT','ADANIGREEN','ADANIPORTS','ADANITRANS','AMBUJACEM','ASIANPAINT','ATGL','BAJAJ-AUTO','BAJAJHLDNG']
    
    # limit控制并发连接数,避免触发API限流
    connector = aiohttp.TCPConnector(limit=50)
    async with aiohttp.ClientSession(connector=connector) as session:
        # 创建所有异步任务
        tasks = [get_prices_async(session, s) for s in stocks]
        # 批量执行任务,return_exceptions=True允许个别任务失败不中断整体
        results = await asyncio.gather(*tasks, return_exceptions=True)
    
    # 过滤并处理结果
    for res in results:
        if isinstance(res, Exception):
            print(f"请求失败: {str(res)}")
        else:
            stock, price = res
            print(f"{stock}: {price}")

# Jupyter Notebook中直接用await运行异步函数
await main()

额外优化建议

  • 控制并发数:不要盲目调大并发数,否则可能被API服务商限流,建议先从20开始测试,逐步找到最优值。
  • 减少实时IO:不要在请求函数内print,先把所有结果存到内存,最后统一写入文件或打印,降低IO开销。
  • 添加重试机制:对失败的请求添加重试(比如用tenacity库),应对网络波动导致的请求失败。
  • 检查API批量接口:查看Moneycontrol是否支持批量查询多只股票的接口,若有,能大幅减少请求次数,效率提升最明显。

内容的提问来源于stack exchange,提问作者Samit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 10:25:35