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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:24:39