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

调用Yahoo Finance接口随机触发JSONDecodeError问题排查

问题:通过ISIN获取股票代码的函数随机触发JSON解析错误

我实现了一个通过ISIN获取股票代码的函数,输入苹果ISIN「US0378331005」有时能正常返回「AAPL」,但多数时候会触发如下JSON解析错误,成功或报错完全随机,怀疑问题出在请求头但无法确定。

错误信息

raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

完整代码

import requests

def get_symbol_for_isin(isin):
    url = 'https://query1.finance.yahoo.com/v1/finance/search'

    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.109 Safari/537.36',
    }

    params = dict(
        q=isin,
        quotesCount=1,
        newsCount=0,
        listsCount=0,
        quotesQueryId='tss_match_phrase_query'
    )

    resp = requests.get(url=url, headers=headers, params=params)
    data = resp.json()
    if 'quotes' in data and len(data['quotes']) > 0:
        return data['quotes'][0]['symbol']
    else:
        return None

apple_isin = 'US0378331005'
print(get_symbol_for_isin(apple_isin))

问题原因及解决办法

  1. 核心原因
    Yahoo Finance的非公开API会对不符合验证规则的请求返回空响应或验证码页面,导致resp.json()解析失败;随机成功是因为部分请求恰好通过了服务器的临时验证。

  2. 修复方案

  • 补充更完整的请求头,模拟真实浏览器行为
  • 添加重试机制,遇到错误时自动重试请求
  • 先校验响应状态码,再尝试解析JSON

修改后的代码

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def get_symbol_for_isin(isin):
    url = 'https://query1.finance.yahoo.com/v1/finance/search'
    
    # 完善请求头,提升请求合法性
    headers = {
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'en-US,en;q=0.9',
        'Referer': 'https://finance.yahoo.com/'
    }

    params = dict(
        q=isin,
        quotesCount=1,
        newsCount=0,
        listsCount=0,
        quotesQueryId='tss_match_phrase_query'
    )

    # 配置重试策略:针对限流、服务器错误自动重试
    session = requests.Session()
    retry = Retry(
        total=3,
        backoff_factor=1,
        status_forcelist=[429, 500, 502, 503, 504]
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('https://', adapter)

    try:
        resp = session.get(url=url, headers=headers, params=params, timeout=10)
        resp.raise_for_status()  # 主动抛出HTTP状态码错误
        data = resp.json()
        if 'quotes' in data and len(data['quotes']) > 0:
            return data['quotes'][0]['symbol']
        return None
    except (requests.exceptions.RequestException, ValueError) as e:
        print(f"请求或解析失败: {str(e)}")
        return None

apple_isin = 'US0378331005'
print(get_symbol_for_isin(apple_isin))
  1. 额外提示
  • Yahoo Finance的非公开API无官方支持,随时可能变更接口规则,长期使用建议切换到公开合规的金融数据API
  • 避免高频连续请求,防止IP被临时封禁

内容的提问来源于stack exchange,提问作者k.dkh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:27:48