ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

akshare实战:一键获取所有A股基础信息并落库

akshare实战:一键获取所有A股基础信息并落库 简介这份压缩包为A股投资者与分析人员提供了一份沪深两市三千余只股票基础信息的数据库及配套代码涵盖股票代码、名称、所属市场、财务指标、市值、市盈率、市净率、流通股本、分红记录等核心字段便于开展批量筛选与统计分析。资源共48个文件、5.2MB以XML数据文件、C#源码、DLL库、配置文件及工程说明文档为主可借助源码快速解析和扩展数据字段适合有Python或C#基础、希望本地化处理股票数据的初级到中级学习者。已有1712人学习下载。通过解析其中数据与脚本可快速搭建本地A股信息查询库理解交易所基础数据结构也能将数据导出为DataFrame结合Pandas进行清洗、可视化与简单选股分析为投资研究提供数据支撑。需要留意基础信息反映的是历史静态指标实际决策还需结合政策、行业趋势及风险控制。1. 项目背景与整体思路拆解刚拿到“获取所有A股股票基础信息.rar”这个东西的时候我第一反应是这大概率不是一份简单的下载好的数据表而是把“怎么拿数据”这套流程连同结果一起打包了。在很多量化社群、数据交流群里经常有人花大把时间在数据源上纠结——用哪个库、要不要token、字段全不全、更新频率够不够。其实这类需求特别典型你要的不只是某一只股票的K线而是全市场5000多只股票的代码、名称、行业、市值、市盈率这批“户口本”一样的基础信息。有了这个底子后面的行情抓取、因子计算、策略回测才有依附。我拿到这个项目后先做的事情是拆解需求要覆盖全部A股沪深主板、创业板、科创板、北交所都算上字段要包含代码、简称、上市日期、所处行业、总股本、流通股本、总市值、流通市值、市盈率、市净率这些核心项输出形态要方便后续程序读取无论是写进SQLite还是转成CSV都能直接复用。如果你自己也收藏过类似的压缩包会发现里面通常就是一个Python脚本加一个数据文件或者一份说明文档。但问题在于不同时间下载的包脚本依赖的接口版本很可能已经变了直接跑会报错。所以我这篇博文打算把这一套从头到尾讲透你能照着抄也能理解里面每一步在干什么。这套方案选型时我走过一些弯路最后定下来的是用akshare作为主数据源辅以pandas做清洗落地到SQLite数据库同时导出CSV备份。选akshare而不是别的库原因后面我会细讲但简单说三点免费、无需注册token、覆盖面广。对于抱着“我就想拿一份干净的全量列表”这个目标的人来说没有比它更顺手的了。适合来看这篇内容的人我猜大概是这几类刚开始接触量化但被数据预处理劝退的新手已经在用量化框架但觉得自带的股票池更新太慢、想自己维护一份底层数据的以及做财务分析、行业研究时需要按行业或板块批量筛选个股的朋友。无论你属于哪一类这篇文章都能帮你把“获取全市场基础信息”这条路趟平。2. 数据源选型对比与关键字段解析2.1 为什么开源库首选akshare市面上的免费A股数据接口我基本都试过一遍各自脾气摸得比较清楚。tushare是老牌选手但Pro版的多个核心接口有积分门槛新注册用户拿不到完整的stock_basic数据积分攒起来很磨人baostock数据稳定但是字段相对偏K线基础信息类的覆盖不够全efinance、adata这些后来者也都在进步但文档完善度和社区活跃度参差不齐。综合下来akshare的“零门槛”属性是最适合新手和需要快速拿结果的场景的。这里有个选择逻辑可以分享选数据源不是看谁功能最多而是看你在“获取基础信息”这一步上愿意投入多少摩擦成本。如果你愿意注册、攒积分、申请权限那tushare的质量确实不错但如果你今天拿到这个项目希望一个小时内就把全市场股票清单握在手里那akshare就是最优解。而且akshare的数据源是公开财经网站接口挂了通常过几个小时就会修社区反馈也及时长期维护成本其实比很多人想象中低。2.2 一份完整的A股基础信息表应该包含哪些字段基础信息不等于“越多越好”字段选多了反而冗余选少了后面用起来又得回头补。我实际操作下来下面这张字段清单是性价比最高的一组覆盖了从代码识别到基本面快照的绝大多数场景字段名含义用途示例code股票代码去重、关联行情name股票简称可视化、筛选industry所属行业行业分组统计list_date上市日期次新股筛选total_share总股本股计算市值float_share流通股本股区分流通盘大小total_mv总市值元规模因子过滤float_mv流通市值元流动性判断pe市盈率动态估值初筛pb市净率估值辅助market所属板块区分沪深北你可能注意到我没有把“52周最高/最低”或者“均价”这类行情类字段放进来。原因很简单基础信息表追求的是低频稳定行情数据本来就应该走日频增量更新的通道混在一起会让整张表的更新逻辑变得混乱。这是我踩过坑之后得出的教训——一开始图省事把一堆行情字段塞进基础表结果每天跑批时接口报错就得全表重建得不偿失。2.3 板块拆分与代码规律的隐性价值A股代码本身是有规律可循的这个规律在你清洗和验证数据时特别有用。沪市主板以600、601、603、605开头深市主板是000、001、002中小板并入后创业板是300、301科创板是688、689北交所是8开头和4开头例如83、87、43等。拿到全量数据后我会先用代码规则做一轮交叉验证看有没有明显异常的代码混进来。这块还有个容易忽略的点北交所股票在很多第三方接口里默认不包含如果你只用常规的stock_zh_a_spot_em接口可能拿不全北交所的票。要做全市场覆盖就得额外拉取北交所清单再合并。我后面给的完整代码里就把这一步做进去了这样你拿到手的才是真正意义上的“所有A股”。3. 完整实操流程与代码实现3.1 环境准备与依赖安装项目操作环境是Python 3.9以上我本机用的是3.10实测没问题。安装依赖用pip一把梭就行核心库就三个pip install akshare pandas sqlalchemy openpyxlsqlalchemy是拿来连SQLite的openpyxl是后面导出Excel用的如果不需要Excel可以跳过。akshare的依赖比较多首次安装可能需要一两分钟耐心等就好。如果你之前装过akshare建议先升级到最新版因为这类爬虫类数据接口改动比较频繁旧版本可能因为网页结构调整而报错pip install akshare --upgrade3.2 获取全市场实时快照含主力接口核心接口是stock_zh_a_spot_em()它返回的是东方财富全A股的实时快照包含但不限于最新价、涨跌幅、总市值、市盈率这些字段。这个接口一次调用就能拿到5000多只股票的数据非常符合“全量获取”的需求。直接贴我的核心代码这是经过多次调整后的稳定版import akshare as ak import pandas as pd def fetch_all_a_spot(): df ak.stock_zh_a_spot_em() # 字段裁剪只保留基础信息相关列 keep_cols { 代码: code, 名称: name, 最新价: price, 总市值: total_mv, 流通市值: float_mv, 市盈率-动态: pe, 市净率: pb, } df df.rename(columnskeep_cols) df df[list(keep_cols.values())].copy() # 去除退市整理期等无用记录 df df[~df[code].astype(str).str.startswith(退)] return df if __name__ __main__: data fetch_all_a_spot() print(data.shape) print(data.head())这一步跑完后你手上就已经有了全市场股票的价格和市值快照。但我必须提醒一点这个接口拿不到“上市日期”和“所属行业”。如果你只需要市值、市盈率层面的基础信息到这里已经够了但如果需要更完整的“户口本”继续往下看我补了一个增强方案。3.3 补充行业与上市日期字段的增强方案行业和上市日期这两个字段对于做行业轮动、次新股分析的朋友来说是刚需。之前图省事想靠一个接口全搞定后来发现最稳的做法是分步骤拼装def fetch_industry_and_listdate(): # 获取全部A股个股信息逐个请求较慢但字段全 code_list ak.stock_info_a_code_name() code_list.columns [code, name] # 使用股票列表去一个一个取个股基本面指标 info_list [] for code in code_list[code][:5]: # 先测试5个确认没问题再全量跑 try: info ak.stock_individual_info_em(symbolcode) info_dict dict(zip(info[item], info[value])) info_list.append({ code: code, industry: info_dict.get(行业, ), list_date: str(info_dict.get(上市时间, ))[:10], }) except Exception as e: print(f{code} 获取失败: {e}) continue return pd.DataFrame(info_list)这里有个不得不说的性能问题stock_individual_info_em是一次请求一只股票全市场5000多只要跑很久而且很容易触发对方的风控。所以我实际使用时的策略是这个增强脚本只在首次建库或者每月更新一次时跑日常的日频更新只用3.2里那个快照接口。行业字段如果对实时性要求不高完全不需要天天刷。如果你的网络环境或者时间不允许全量逐只请求还有一个折中办法用ak.stock_board_industry_name_em()拿到行业列表再用ak.stock_board_industry_cons_em(symbol行业名)倒推出每只股票属于哪个行业。这种“以板块反查个股”的方式请求次数少很多但是代码稍复杂一点适合对代码结构有信心的朋友。3.4 数据落地SQLite存储与CSV备份数据拿到手只是第一步怎么存决定了你后续调用的便利性。我个人的习惯是SQLite为主、CSV为辅。SQLite的好处是查询方便可以直接用SQL做条件过滤CSV的好处是方便分享和备份放进你的.rar包里也不占多大空间。完整的存储代码如下from sqlalchemy import create_engine engine create_engine(sqlite:///a_stock_basic.db) def save_to_db(df, table_namestock_basic): df.to_sql(table_name, engine, if_existsreplace, indexFalse) print(f已写入 {table_name} 表共 {len(df)} 条记录) # 执行 spot_df fetch_all_a_spot() spot_df.to_csv(a_spot_snapshot.csv, indexFalse, encodingutf-8-sig) save_to_db(spot_df, stock_spot_snapshot)关于编码这里多说一句导出的CSV如果直接用utf-8在Windows上用Excel打开会乱码。必须用utf-8-sig加BOM头或者直接导出成Excel格式才能避免“打开全是乱码”的尴尬。这是很多人第一次实操最容易踩的坑别问我怎么知道的。4. 常见问题与实战排坑记录4.1 接口返回空数据或报错akshare偶尔会因为目标网站改版导致解析失败常见报错是KeyError或者AttributeError。遇到这种情况最直接的办法就是升级akshare到最新版然后再重新跑。如果升级后还报错去GitHub的Issues区看一眼通常热点问题当天就会有解决方案。另外一个技巧是设置重试机制。接口请求偶尔会因为网络波动返回空DataFrame盲目重跑容易浪费时间。我习惯在调用外面套一个简单的重试逻辑import time def call_with_retry(func, retries3, delay2): for i in range(retries): try: df func() if df is not None and not df.empty: return df except Exception as e: print(f第{i1}次请求失败: {e}) time.sleep(delay) raise RuntimeError(多次重试后仍失败请检查网络或接口版本)提示不要用太短的delay比如0.1秒这种很容易触发对方网站的反爬限制。2秒起步比较稳妥。4.2 全市场股票数量对不上有的朋友跑完后发现股票数量只有4000多只而不是想象中5000多只。大概率是北交所的票没算进去。stock_zh_a_spot_em()这个接口在多数时间会包含北交所但如果版本差异或者数据源调整可能导致北交所缺失。解决办法是先单独拉北交所的列表def fetch_bse_list(): df ak.stock_info_bj_name_code() df.columns [code, name] return df然后跟主表做一次外连接合并补齐缺失的北交所代码。合并的时候注意代码格式统一北交所代码有6位比如830799不要在前面补零。还有一部分数量的差异来自于“停牌股”和“退市整理股”。不同接口对这类股票的处理策略不一样有些会直接过滤掉。如果你的使用场景需要包含停牌股票比如做全市场选股建议把这个因素考虑进去最好做一次与历史代码表的对比。4.3 内存不足或程序卡死如果你不是在服务器上跑而是在一台只有8G内存的笔记本上运行全量拉取时可能会卡顿。主要原因是akshare返回的DataFrame包含了大量冗余列在全市场5000多只、几十个字段的规模下内存占用会被放大。优化手段有两个一是尽早裁剪字段只保留自己需要的列二是用迭代式处理不要把全量数据一次性塞进内存。还有一个小技巧拿到DataFrame后立刻del df或者做一次垃圾回收gc.collect()为后续操作腾出空间。4.4 每日定时的自动化更新方案拿到一次数据只是开始真正有实战价值的数据源必须保持更新。我自己的方案是用系统自带的定时任务每天收盘后跑一次快照脚本# update_daily.py import schedule import time def job(): df fetch_all_a_spot() save_to_db(df, stock_spot_snapshot) print(f更新完成: {pd.Timestamp.now()}) schedule.every().day.at(15:30).do(job) while True: schedule.run_pending() time.sleep(60)Windows下可以配合“任务计划程序”来实现开机启动和自动运行Linux直接用crontab一行搞定。这样你手里那份基础信息就一直是最新状态不需要每次手动跑脚本。注意定时任务首次运行前一定要先手动跑通一次确认环境和网络都没问题。不然定时任务报错排查起来比手动跑一遍还费事。5. 项目的扩展方向与进阶玩法有了干净的全市场基础信息表后续能做的事就多了。我挑三个自己实际做过的方向说说思路想深入的朋友可以顺着这些脉络继续挖。第一技术指标叠加。把基础信息表作为主表关联日线行情数据可以做出“全市场低估值高股息”的初筛策略。比如用stock_zh_a_hist接口批量拉取候选池里的历史日线再计算均线偏离度、RSI等因子把基础信息和行情因子组合成一个宽表做出来的选股池在实盘模拟中表现很稳定。这个方向适合刚入门的量化爱好者。第二行业轮动分析。利用基础表中的行业字段结合每日行情快照中的涨跌幅可以统计每日每个行业的整体涨跌幅、资金流向。我最开始就是靠这个数据观察行业间的轮动节奏后来用简单的动量因子做回测效果中规中矩但对理解市场结构帮助很大。如果你不想写代码把这份数据导出Excel后用透视表也能分析。第三事件驱动型研究。比如统计不同上市日期区间的股票数量变化分析注册制改革前后的扩容节奏或者按板块拆分对比科技类板块和其他板块的估值水平差异。这类研究不需要复杂的模型但前提是你有一份字段丰富、覆盖完整的基础表这篇项目正好能满足。我个人实际操作中的感受是数据基础打牢了后面任何策略想法都能快速用数据去验证而不会被“先找数据”这件事卡住。最后再分享一个小技巧如果你打算长期维护这份基础信息表建议每次更新时不要直接覆盖旧表而是用if_existsappend加上时间戳列把历史快照也保存下来。这样以后想做“历史上某一天的股票状态还原”时直接查库就行不用重新去数据源拉历史数据很多基础信息类接口根本不提供历史版本。这个习惯帮我省了不止一次从头跑数据的功夫。本文还有配套的精品资源点击获取
返回列表