如何抓取Investing.com上更早的CPI历史财报数据?
解决Investing.com历史数据抓取(含Show more按钮)的问题
问题背景
已实现抓取Investing.com展示的CPI数据表格,但无法获取2020年及更早的数据,原因是网站通过"Show more"按钮加载历史数据,直接静态抓取无法获取深层内容,参考现有方案后适配失败。
修正后的可运行代码
import pandas as pd import requests from io import StringIO # 加载历史数据的AJAX接口 url = "https://it.investing.com/economic-calendar/more-history" # 从目标页面源码提取的正确请求参数 data = { "eventID": "733", "event_attr_ID": "733", "event_timestamp": "", "is_speech": "0", } # 模拟浏览器的完整请求头,避免被拦截 headers = { "x-requested-with": "XMLHttpRequest", "accept": "application/json, text/javascript, */*; q=0.01", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36", "referer": "https://it.investing.com/economic-calendar/cpi-733", "origin": "https://it.investing.com" } # 按90天分段请求,确保覆盖2020全年数据 dates = pd.date_range("2020-01-01", "2020-12-31", freq="90D") all_dfs = [] with requests.session() as s: s.headers.update(headers) # 先访问目标页面获取有效会话Cookie,确保后续请求被认可 s.get("https://it.investing.com/economic-calendar/cpi-733") for d in dates: data["event_timestamp"] = d.strftime("%Y-%m-%d") try: resp = s.post(url, data=data).json() # 解析返回的表格HTML table = "<table>" + resp["historyRows"] + "</table>" df = pd.read_html(StringIO(table))[0] # 匹配列名并移除多余列 df.columns = ["Data di rilascio", "Ora", "Attuale", "Previsto", "Precedente", "_"] df = df.drop(columns=["_"]) all_dfs.append(df) except Exception as e: print(f"请求日期{d}时出错: {e}") continue # 合并数据并整理日期格式 final_df = pd.concat(all_dfs).drop_duplicates() final_df["Data di rilascio"] = pd.to_datetime( final_df["Data di rilascio"].str.rsplit(n=1).str[0], dayfirst=True ) final_df = final_df.sort_values(by="Data di rilascio").reset_index(drop=True) print(final_df) # 可选:保存到CSV文件 # final_df.to_csv("2020_cpi_data.csv", index=False, encoding="utf-8-sig")
关键修改说明
- 修正请求参数:原代码中
eventID设为1错误,实际应与event_attr_ID一致为733(从目标页面源码可提取) - 完善请求头:增加
referer和origin字段,模拟合法的浏览器请求来源,避免被网站拦截 - 会话预处理:先访问目标页面获取有效会话Cookie,确保后续AJAX请求被服务端认可
- 分段请求优化:将日期频率从180D改为90D,避免单次请求返回数据不全
- 异常处理:增加try-except块,防止单个请求失败导致整个程序中断
- 数据清理:移除多余列并去重,确保最终数据整洁
内容的提问来源于stack exchange,提问作者Ricter
相关产品推荐
相关产品推荐

