Python无Selenium提取指定日期网页全量数据问题求助
问题修复方案
代码无法拉取数据、无法按日期查询的核心原因有3个:
- 请求头缺失
Content-Type: application/json配置,后端无法正确解析传入的JSON格式请求体 - 请求体(payload)缺失接口强制要求的
tradeDate日期筛选参数,且未正确解析接口返回结构:接口返回的实际数据存在data字段下,直接对响应根对象转DataFrame会拿到空值/结构错误 - 未做会话cookie保持,直接发POST请求容易被接口的反爬策略拦截
多日期批量爬取实现代码
import json import pandas as pd import requests import datetime import os from typing import List # 基础配置 save_path = r"C:\Users\Desktop\Python_OP\Data" os.makedirs(save_path, exist_ok=True) endpoint = "https://bricsonline.nseindia.com/bondsnew/rest/public?r=sebiannexure1" # 初始化会话,自动保持cookie,降低被拦截概率 sess = requests.Session() # 先访问站点首页获取合法cookie sess.get( "https://bricsonline.nseindia.com/bondsnew/", headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" }, timeout=10 ) # 统一请求头 req_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/json", "Referer": "https://bricsonline.nseindia.com/bondsnew/" } # 统一表字段 column_names = [ "Deal Type", "ISIN", "Listed / Unlisted Security", "Issuer Name", "Coupon", "Issue Description", "Price", "Yield", "Yield Type", "Outside Yield Range", "Put/Call Date", "Trade Value in Rs. Lacs", "Trade Date & Time", "Settlement Date", "Reported trade/Trade executed on RFQ platform", "Remarks", "Settlement Status", ] def fetch_single_date_data(target_date: datetime.date) -> pd.DataFrame: """ 拉取指定日期的债券数据 :param target_date: 要查询的日期,datetime.date类型 """ # 接口要求日期格式为 日-月-年 date_str = target_date.strftime("%d-%m-%Y") payload = { "columnNames": column_names, "tradeDate": date_str # 传入日期参数 } resp = sess.post( endpoint, data=json.dumps(payload), headers=req_headers, timeout=15 ) resp.raise_for_status() resp_data = resp.json() # 从响应的data字段取实际列表数据 if not resp_data.get("data"): print(f"日期{date_str}无可用数据") return pd.DataFrame(columns=column_names) return pd.DataFrame(resp_data["data"], columns=column_names) if __name__ == "__main__": # -------------------------- # 在这里配置你要爬取的日期列表 # 示例:爬取2024年10月15日到2024年10月20日的数据 # -------------------------- start_date = datetime.date(2024, 10, 15) end_date = datetime.date(2024, 10, 20) target_dates: List[datetime.date] = [] cur_date = start_date while cur_date <= end_date: target_dates.append(cur_date) cur_date += datetime.timedelta(days=1) # 批量爬取+保存 all_data = [] for date in target_dates: print(f"正在拉取{date}数据...") df = fetch_single_date_data(date) if not df.empty: all_data.append(df) # 单日期数据单独存文件 single_file_path = os.path.join(save_path, f"Data_{date.strftime('%d-%m-%Y')}.csv") df.to_csv(single_file_path, index=False, encoding="utf-8-sig") print(f"{date}数据保存完成,共{len(df)}条") # 合并所有日期数据存总文件 if all_data: total_df = pd.concat(all_data, ignore_index=True) total_path = os.path.join(save_path, f"Data_Total_{datetime.datetime.now().strftime('%d-%m-%Y_%H.%M')}.csv") total_df.to_csv(total_path, index=False, encoding="utf-8-sig") print(f"全部数据拉取完成,总条数:{len(total_df)},已保存至{total_path}")
关键使用说明
- 日期传参逻辑:接口要求日期格式必须为
dd-mm-yyyy,代码里通过strftime("%d-%m-%Y")自动转换格式,你只需要在target_dates列表里放入要查询的datetime.date类型日期即可,支持任意指定日期、日期范围批量查询 - 如果运行时返回403错误,只需要手动打开目标站点在浏览器里访问一次,把浏览器请求头里的pageToken值复制到
req_headers里即可,正常情况下用会话保持cookie不需要硬编码pageToken - 代码默认会把每个日期的数据单独存为一个csv,同时合并所有日期的数据存一个总文件,避免数据覆盖
- 非交易日接口会返回空数据,代码会自动跳过不会报错
内容的提问来源于stack exchange,提问作者Tech Bro
相关产品推荐
相关产品推荐

