yahooquery超200条请求报KeyError及HTTP404错误如何解决
问题现象
使用yahooquery库拉取指定板块ticker列表时,单请求数据量在200条以内可正常运行,调高请求count参数后会触发两类报错:
- 抛出
KeyError: 'ms_energy' - 返回HTTP 404 Not Found
复现代码:
def screener(): global ticker_list time.sleep(0.01) s = Screener() # data is a dictionary containing the keys passed to the function data = s.get_screeners('ms_energy', count=500) df = pd.DataFrame(data['ms_energy']['quotes']) df = df.loc[:, "symbol"] s.available_screeners ticker_list = df.values.tolist() return ticker_list screener()
已知配置自定义User-Agent请求头可绕过该类反爬拦截,但yahooquery库的官方文档没有明确说明自定义请求头的配置方式。
解决方法
yahooquery的Screener实例自带session属性,是初始化好的requests会话对象,直接更新该会话的headers即可注入自定义User-Agent,不需要修改库源码。
另外要注意:Yahoo Finance的screener接口本身对单请求返回条数有硬限制,单次请求count参数超过250时即使配置了UA也会被拦截,不要尝试单次拉取500条数据,通过start参数分页拉取更稳定。
调整后可正常运行的代码:
import time import pandas as pd from yahooquery import Screener def screener(): all_quotes = [] s = Screener() # 注入常规浏览器UA,绕过反爬标识检测 s.session.headers.update({ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" }) # 分页拉取,每次请求200条,避免触发单请求条数限制 for offset in range(0, 600, 200): resp = s.get_screeners('ms_energy', count=200, start=offset) # 提前判断返回结构是否合法,避免直接取key触发KeyError if resp.get('ms_energy', {}).get('quotes'): all_quotes.extend(resp['ms_energy']['quotes']) time.sleep(0.3) # 加请求间隔避免触发频率限制 df = pd.DataFrame(all_quotes) # 去重后返回ticker列表 ticker_list = df['symbol'].drop_duplicates().tolist() return ticker_list # 调用测试 print(screener())
额外注意事项
- 如果配置UA后依然返回404,可以更换不同版本的浏览器UA,或者给session配置代理IP
- 不要删除请求间隔,短时间高频调用接口依然会触发IP临时封禁
- 不需要调用
s.available_screeners,该接口会额外发一次请求拖慢速度,对拉取板块数据没有帮助
内容的提问来源于stack exchange,提问作者huifortrack
相关产品推荐
相关产品推荐

