当前位置:首页 > 随笔 > 正文内容

东方财富行情数据采集与解析实战

访客 随笔 2026年7月9日 1

本文介绍如何从东方财富网行情中心获取多板块股票数据,并导出为 Excel 文件。目标页面为沪深京等各大板块的股票列表,数据通过动态接口加载,需借助浏览器开发者工具进行抓包分析。

接口分析与请求构造

通过浏览器开发者工具(F12)观察网络请求,可发现数据由以下接口返回:

https://push2.eastmoney.com/api/qt/clist/get?cb=回调函数&pn=页码&pz=20&po=1&np=1&ut=...&fid=筛选条件&fs=板块代码&fields=字段列表

关键参数说明:

  • pn:页码,从 1 开始递增
  • pz:每页条数,固定 20
  • fidfs:组合用于指定板块
  • fields:返回字段,如 f12(代码)、f14(名称)、f2(最新价)等

JSONP 响应处理

接口返回 JSONP 格式,需提取有效 JSON 内容。以下采用字符串切片方式处理,避免正则转义问题:

import requests

def parse_jsonp(resp_text):
    # 定位第一个左括号位置
    start = resp_text.find('(')
    # 定位末尾右括号位置
    end = resp_text.rfind(')')
    if start == -1 or end == -1:
        raise ValueError("非法的 JSONP 格式")
    # 提取括号内纯 JSON 字符串
    json_str = resp_text[start + 1:end]
    # 处理 null 字面量
    json_str = json_str.replace('null', 'None')
    return eval(json_str)

板块配置与字段映射

定义板块参数映射表,便于批量采集:

BOARD_CONFIG = {
    "沪深京A股": {"fid": "f3", "fs": "m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048"},
    "上证A股": {"fid": "f3", "fs": "m:1+t:2,m:1+t:23"},
    "深证A股": {"fid": "f3", "fs": "m:0+t:6,m:0+t:80"},
    "北证A股": {"fid": "f3", "fs": "m:0+t:81+s:2048"},
    "新股": {"fid": "f26", "fs": "m:0+f:8,m:1+f:8"},
    "创业板": {"fid": "f3", "fs": "m:0+t:80"},
    "科创板": {"fid": "f3", "fs": "m:1+t:23"},
    "沪股通": {"fid": "f26", "fs": "b:BK0707"},
    "深股通": {"fid": "f26", "fs": "b:BK0804"},
    "B股": {"fid": "f3", "fs": "m:0+t:7,m:1+t:3"},
    "风险警示板": {"fid": "f3", "fs": "m:0+f:4,m:1+f:4"},
}

字段与中文含义对照:

FIELD_MAP = {
    "f12": "代码",
    "f14": "名称", 
    "f2": "最新价",
    "f3": "涨跌幅",
    "f4": "涨跌额",
    "f5": "成交量",
    "f6": "成交额",
    "f7": "振幅",
    "f15": "最高",
    "f16": "最低",
    "f17": "今开",
    "f18": "昨收",
    "f10": "量比",
    "f8": "换手率",
    "f9": "市盈率",
    "f23": "市净率",
}

完整采集程序

import requests
import pandas as pd
from time import sleep

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Referer": "https://quote.eastmoney.com/",
}

def fetch_board_data(board_name, config):
    all_records = []
    page_idx = 1
    
    while True:
        # 构造请求 URL
        url = (
            f"https://7.push2.eastmoney.com/api/qt/clist/get?"
            f"cb=jQuery_{board_name}_{page_idx}&pn={page_idx}&pz=20&po=1&np=1&"
            f"ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&"
            f"wbp2u=|0|0|0|web&fid={config['fid']}&fs={config['fs']}&"
            f"fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,"
            f"f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152"
        )
        
        try:
            rsp = requests.get(url, headers=HEADERS, timeout=15)
            rsp.raise_for_status()
        except requests.RequestException as e:
            print(f"{board_name} 第 {page_idx} 页请求异常: {e}")
            break
        
        # 解析 JSONP
        payload = parse_jsonp(rsp.text)
        
        # 判定终止条件:data 为空或不存在
        if not payload.get('data') or not payload['data'].get('diff'):
            print(f"{board_name} 采集完毕,共 {page_idx - 1} 页")
            break
        
        # 提取数据
        for item in payload['data']['diff']:
            row = {v: item.get(k) for k, v in FIELD_MAP.items()}
            all_records.append(row)
        
        print(f"{board_name} 第 {page_idx} 页已采集")
        page_idx += 1
        sleep(0.3)  # 控制请求频率
    
    return all_records

def main():
    for name, cfg in BOARD_CONFIG.items():
        dataset = fetch_board_data(name, cfg)
        if not dataset:
            continue
        
        frame = pd.DataFrame(dataset)
        filename = f"行情_{name}.xlsx"
        frame.to_excel(filename, index=False, engine='openpyxl')
        print(f"已保存: {filename},共 {len(dataset)} 条")

if __name__ == "__main__":
    main()

关键注意点

  • 终止判定:当接口返回的 data 字段为 nulldiff 为空列表时,表示该板块已遍历完毕
  • 频率控制:建议添加延时(如 300ms),避免触发服务端限流
  • 字段缺失:部分股票某些字段可能为空,dict.get() 可安全处理
  • 动态节点:push2 子域名存在多个(如 62、7 等),若请求失败可尝试切换

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

在 iPhone 上下载国外App

地区/国家限制App Store 会根据 Apple ID 的国家或地区限制应用下载。如果你的 Apple ID 绑定的是中国大陆,就可能无法下载 OpenAI 官方的 ChatGPT 应用,因为它在大陆 App Store 不上架。解决办法:换成美国、加拿大、香港等地区的 Apple ID。或者在现有 Apple ID 上更改地区。注册一个国外 Apple ID(推荐)比如注册 美国区 Appl...

Node.js 中的异步编程:回调与 Promise

Node.js 是一个基于 JavaScript 构建的单线程、非阻塞运行环境,它通过异步编程机制来高效处理多个操作。在执行如文件读取、API 请求或数据库查询等任务时,Node.js 不会等待这些操作完成,而是使用回调函数和 Promise 来避免阻塞主线程。 回调方式实现异步 那么当异步操作完成后,Node.js 如何知道接下来要做什么呢?这就要用到 回调函数(callback)。 回调本质上...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。