Documents

上市公司年报/研报抓取

Try it

上市公司年报/研报自动抓取。覆盖巨潮资讯、东方财富等数据源,支持按公司代码/名称/年份/行业批量下载 PDF。内置反爬绕过、PDF 解析。

What it does

**目标**:通过自然语言指令,自动从东方财富、巨潮资讯、上交所、深交所等权威财经网站获取上市公司年报、季报、研报等 PDF 文档。 **核心能力**:智能数据源路由 + 反爬绕过 + 登录模拟 + 批量下载 + PDF 解析

The skill document

上市公司年报/研报抓取 Skill

目标:通过自然语言指令,自动从东方财富、巨潮资讯、上交所、深交所等权威财经网站获取上市公司年报、季报、研报等 PDF 文档。 核心能力:智能数据源路由 + 反爬绕过 + 登录模拟 + 批量下载 + PDF 解析


架构总览

用户指令 → 参数解析 → 数据源路由 → 抓取执行 → 反爬/登录处理 → 下载存储 → (可选) PDF解析 → 结果交付

依赖模块(复用现有技能)

依赖用途Skill/工具
smart-search公司代码/名称查询、公告页面定位skills/smart-search
scrapling反爬绕过(隐身/动态模式)skills/scrapling-web-scraper
Crawl4AI深度页面抓取 + 结构化提取skills/crawl4ai
Firecrawl搜索 + 单页抓取降级skills/firecrawl-cli
web_fetchAgent 内置抓取降级内置工具
Playwright登录态模拟、动态内容等待已安装
PyMuPDFPDF 解析/文本提取已安装
requests原始 HTTP 请求、PDF 下载Python 标准库

已验证的 API(2026-06-18 实测通过)

巨潮资讯 — 年报/公告 PDF

  • 搜索 API: POST http://www.cninfo.com.cn/new/hisAnnouncement/query
    • 需要 stock 参数格式:{code},{orgId},orgId 格式 gssz{code}(深)/ gssh{code}(沪)
    • seDate 需覆盖发布窗口:{year}-01-01~{year+1}-06-30
    • searchkey 精准匹配:{year}年年度报告
  • PDF 直链: http://static.cninfo.com.cn/{adjunctUrl}
  • 反爬: UA 轮换 + 1-3s 随机延迟,无需登录

东方财富 — 行业/个股研报

  • 列表 API: GET https://reportapi.eastmoney.com/report/list
    • qType: 0=个股研报, 1=行业研报, 2=策略报告, 3=宏观研究, 4=券商晨会
    • industryCode: 行业分类 ID(旅游及景区=1272, 酒店餐饮=1271)
    • code: 股票代码(个股研报时用)
    • beginTime/endTime: 日期范围
    • 返回 JSONP 格式,需剥离 callback 包装
  • PDF 直链: https://pdf.dfcfw.com/pdf/H3_{infoCode}_1.pdf
    • 无需登录,直接 GET 即可下载
    • 需检查 content-type 是否为 application/pdf,防止 404 返回 HTML
  • 详情页: https://data.eastmoney.com/report/info/{infoCode}.html
  • 反爬: 列表 API 无需登录、无反爬;PDF 直链也无需登录。页面抓取需 Playwright(JS 渲染)

行业代码参考

行业代码行业名称行业代码行业名称
1272旅游及景区1271酒店餐饮
420航空机场1268互联网电商
1287工业金属1238IT服务Ⅱ
422物流1221数字媒体

支持的数据源(已验证 ✅ 未验证 ❌)

数据源年报季报研报反爬强度需要登录
巨潮资讯 (cninfo.com.cn)✅✅❌中否
东方财富 (eastmoney.com)✅✅✅低(列表API)/高(页面)否(列表+PDF)/部分(页面)
上交所 (sse.com.cn)❌❌❌低否
深交所 (szse.cn)❌❌❌低否
慧博投研 (hibor.com)❌❌❌高✅
萝卜投研 (robo.datayes.com)❌❌❌中部分

实测验证记录(2026-06-18)

✅ 验证通过:巨潮资讯 + 万科A 历年年报

  • 下载 6 份年报 PDF(2019-2024),全部可正常解析
  • 关键发现:stock 参数需 {code},{orgId} 格式(如 000002,gssz0000002)
  • seDate 需覆盖次年发布窗口(如 2024 年报在 2025 年 4 月发布)
  • category 参数过滤过严,改用 searchkey 精准匹配更可靠
  • 文件:downloads/000002_万科A/annual/ 共 66 MB

✅ 验证通过:东方财富 + 旅游行业研报

  • 列表 API 无需登录,直接 GET 返回 JSONP 格式数据
  • PDF 直链 pdf.dfcfw.com/pdf/H3_{infoCode}_1.pdf 无需登录直接下载
  • 下载 5 份 PDF,4 份成功(1 份 PDF URL 无效→需加 404 校验重试)
  • 携程集团研报 61 页 / 10.7 MB,内容完整可解析
  • industryCode 参数:旅游及景区=1272, 酒店餐饮=1271
  • 文件:downloads/旅游行业研报_PDF/ 共 14 MB

使用方法

自然语言指令

# 按公司下载
"下载腾讯2025年年报PDF"
"下载贵州茅台2023-2025年所有年报"
"下载平安银行最新季度报告"

# 按行业/批量下载
"下载所有银行板块公司的2024年年报"
"下载沪深300成分股2024年年报(限前10家)"

# 研报抓取
"下载茅台的券商研报,最近3个月"
"抓取东方财富上宁德时代的所有研报"

# 解析提取
"下载腾讯2024年年报并提取财务数据"
"抓取茅台年报PDF,提取营收和净利润"

脚本调用

# 基本下载(巨潮资讯优先)
python3 scripts/financial_report_fetcher.py --stock "000858" --year 2024

# 多公司批量下载
python3 scripts/financial_report_fetcher.py --stocks "000858,600519,000001" --years "2023,2024"

# 指定数据源
python3 scripts/financial_report_fetcher.py --stock "0700.HK" --source eastmoney

# 下载报告类型(年报/季报/半年报/研报)
python3 scripts/financial_report_fetcher.py --stock "600519" --type "annual" --years "2022,2023,2024"

# 仅搜索不下载
python3 scripts/financial_report_fetcher.py --stock "600519" --dry-run

# 下载后解析PDF
python3 scripts/financial_report_fetcher.py --stock "600519" --year 2024 --parse-pdf

# 研报模式
python3 scripts/financial_report_fetcher.py --research --stock "000858" --months 3

核心流程

Phase 1: 参数解析

将自然语言指令转换为结构化参数:

{
    "stocks": ["000858", "600519"],    # 股票代码
    "years": ["2023", "2024"],          # 年份范围
    "report_types": ["annual"],         # annual|semi-annual|quarterly|research
    "source": "auto",                   # auto|cninfo|eastmoney|sse|szse|hibor
    "action": "download",               # download|search|parse
    "parse_fields": [],                 # 需要提取的PDF字段
    "output_dir": "./downloads/",       # 输出目录
    "max_concurrent": 3,                # 并发数
}

Phase 2: 数据源路由(智能降级)

1. cninfo(巨潮资讯)    ← 法定披露平台,覆盖最全,无登录要求
   ↓ 失败或无结果
2. sse.com.cn(上交所)   ← 上交所上市公司
   ↓ 失败或无结果
3. szse.cn(深交所)      ← 深交所上市公司
   ↓ 失败或无结果
4. eastmoney(东方财富)  ← 研报+年报,部分需登录
   ↓ 失败或无结果
5. hibor(慧博投研)      ← 研报为主,需登录

Phase 3: 抓取执行(按数据源)

3A. 巨潮资讯(首选,无需登录)

API 接口:

import requests

# 搜索公告
search_url = "http://www.cninfo.com.cn/new/hisAnnouncement/query"
payload = {
    "stock": "000858",              # 股票代码
    "tabName": "fulltext",
    "pageSize": 30,
    "pageNum": 1,
    "column": "szse",               # szse/sse
    "category": "category_ndbg_szsh",  # 年报: category_ndbg_szsh
    "seDate": "2024-01-01~2024-12-31",
    "searchkey": "年度报告"
}
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Referer": "http://www.cninfo.com.cn/new/disclosure",
    "Content-Type": "application/x-www-form-urlencoded"
}

resp = requests.post(search_url, data=payload, headers=headers)
announcements = resp.json()["announcements"]

# 下载 PDF
for ann in announcements:
    adjunct_url = ann["adjunctUrl"]  # 如: finalpage/2025-04-01/123456.PDF
    pdf_url = f"http://static.cninfo.com.cn/{adjunct_url}"
    pdf_resp = requests.get(pdf_url, headers=headers)
    with open(f"downloads/{ann['secCode']}_{ann['announcementTitle']}.pdf", "wb") as f:
        f.write(pdf_resp.content)

报告类型 category 映射:

  • 年报: category_ndbg_szsh
  • 半年报: category_bndbg_szsh
  • 季报: category_jdbg_szsh
  • 招股书: category_first_szsh

反爬策略:

  • 每次请求间隔 1-3 秒随机延迟
  • 轮换 User-Agent(5 组常见 UA)
  • 使用 Referer 伪装
  • 批量下载时并发 ≤ 3
  • 如返回 403,启用 Scrapling stealth 模式

3B. 上交所 SSE

API 接口:

# 搜索公告
search_url = "http://query.sse.com.cn/sseQuery/commonQuery.do"
params = {
    "jsonCallBack": "jsonpCallback",
    "isPagination": "true",
    "stockCode": "600519",
    "companyCode": "",
    "pageHelp.pageSize": 25,
    "pageHelp.pageNo": 1,
    "pageHelp.beginPage": 1,
    "product": "600519",
    "bulletintype": "periodic",    # 定期报告
    "filetype": "PDF",
    "sqlId": "common_ssepany_disclosure_info_product_bulletin_index",
    "_": int(time.time() * 1000)
}
headers = {
    "Referer": "http://www.sse.com.cn/disclosure/listedinfo/announcement/",
    "User-Agent": "..."
}

3C. 深交所 SZSE

API 接口:

# 搜索公告
search_url = "https://disc.szse.cn/api/disc/info/ann/twoCategory"
params = {
    "random": str(time.time()),
    "seDate": "",
    "channelCode": "listedNotice",
    "bigCategoryId": "category_ndbg_szsh",  # 年报
    "subBigCategoryId": "",
    "stock": "000858",
    "pageNum": 1,
    "pageSize": 30
}

3D. 东方财富(研报 + 年报)

挑战:部分页面需登录,有反爬机制。

解决方案:

# 方式1:直接 API(无需登录)
research_url = "https://np-anotice-stock.eastmoney.com/api/security/ann"
# 类似 cninfo 的 POST 请求

# 方式2:Scrapling stealth 模式(需要登录/有反爬时)
from scrapling.fetchers import StealthyFetcher
page = StealthyFetcher.fetch(
    "https://data.eastmoney.com/report/{stock_code}.html",
    headless=True,
    solve_cloudflare=False,
    timeout=30
)

# 方式3:Playwright 登录态(慧博等需登录平台)
# 见下方"登录态管理"部分

东方财富研报页面解析:

# 研报列表页
url = f"https://data.eastmoney.com/report/{stock_code}.html"
# CSS 选择器提取研报标题、日期、机构、PDF链接
selectors = {
    "title": ".report-title a::text",
    "date": ".report-date::text",
    "org": ".org-name::text",
    "pdf_link": "a[href*='.pdf']::attr(href)"
}

3E. 慧博投研(需登录,研报为主)

登录态管理:

from playwright.sync_api import sync_playwright

def login_hibor(username: str, password: str, storage_state: str = "hibor_state.json"):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        context = browser.new_context(storage_state=storage_state if os.path.exists(storage_state) else None)
        
        if not os.path.exists(storage_state):
            page = context.new_page()
            page.goto("https://www.hibor.com.cn/login")
            page.fill("#username", username)
            page.fill("#password", password)
            page.click("button[type='submit']")
            page.wait_for_url("**/user/**", timeout=10000)
            context.storage_state(path=storage_state)
        
        return context

Phase 4: 反爬/登录策略矩阵

挑战应对方案工具
User-Agent 检测轮换 UA 池(5-10组)requests + 自定义 headers
IP 频率限制随机延迟 1-3s + 并发≤3time.sleep(random)
Cloudflare 验证Scrapling stealth 模式scrapling
动态加载(JS)Crawl4AI / Playwrightcrawl4ai / playwright
需要登录Playwright 登录态持久化playwright + storage_state
验证码人工介入提示 + Playwright 截图等待输入playwright
Cookie 过期自动检测 + 重新登录playwright

Phase 5: 下载与存储

downloads/
├── {公司代码}/
│   ├── annual/
│   │   ├── 2024_{股票简称}_年报.pdf
│   │   └── 2023_{股票简称}_年报.pdf
│   ├── semi-annual/
│   ├── quarterly/
│   └── research/
│       ├── 2026-06_{机构}_{标题}.pdf
│       └── ...
├── metadata.json          # 下载元数据记录
└── download_log.md        # 本次下载摘要

metadata.json 格式:

{
    "downloads": [
        {
            "stock_code": "600519",
            "stock_name": "贵州茅台",
            "report_type": "annual",
            "year": "2024",
            "source": "cninfo",
            "file_path": "downloads/600519/annual/2024_贵州茅台_年报.pdf",
            "title": "贵州茅台2024年年度报告",
            "announcement_id": "12345678",
            "download_time": "2026-06-18T10:00:00+08:00",
            "file_size_mb": 5.2
        }
    ]
}

Phase 6: PDF 解析(可选)

import fitz  # PyMuPDF

def extract_financial_data(pdf_path: str, fields: list = None) -> dict:
    """从年报PDF中提取关键财务数据"""
    doc = fitz.open(pdf_path)
    text = ""
    for page in doc:
        text += page.get_text()
    doc.close()
    
    # 关键词定位提取
    data = {}
    patterns = {
        "营收": r"营业收入[::]\s*([\d,\.]+)\s*元",
        "净利润": r"归属于.*?[::]\s*([\d,\.]+)\s*元",
        "总资产": r"资产总计[::]\s*([\d,\.]+)\s*元",
        "每股收益": r"基本每股收益[::]\s*([\d,\.]+)\s*元",
        "ROE": r"加权平均净资产收益率[::]\s*([\d,\.]+)%",
    }
    for key, pattern in patterns.items():
        match = re.search(pattern, text)
        if match:
            data[key] = match.group(1)
    return data

错误处理

ERROR_CODES = {
    "CNINFO_403": "巨潮反爬触发,切换 Scrapling stealth 模式重试",
    "CNINFO_EMPTY": "未找到相关年报,检查股票代码/年份是否正确",
    "EASTMONEY_LOGIN": "东方财富需要登录,请配置 cookies 或使用 Playwright 登录",
    "PDF_DOWNLOAD_FAIL": "PDF 下载失败,尝试备用数据源",
    "STOCK_NOT_FOUND": "未找到该公司,使用 smart-search 确认股票代码",
    "RATE_LIMIT": "请求过于频繁,等待 10 秒后重试",
}

Agent 集成工作流

用户: "下载贵州茅台2024年年报"
    ↓
1. 解析 → stock_code=600519, year=2024, type=annual
2. 首选巨潮资讯:
   a. POST hisAnnouncement/query 搜索
   b. 返回结果 → 提取 PDF URL
   c. GET PDF → 保存
3. 巨潮失败 → 尝试上交所
4. 上交所失败 → 尝试东方财富
5. 所有数据源失败 → 报错告知用户

用户: "下载并分析腾讯2024年报的营收结构"
    ↓
1. 下载 PDF(港股→优先东方财富/港交所)
2. PyMuPDF 提取文本
3. 关键词定位"营业收入"+"分部收入"
4. 返回结构化数据

快速开始

# 1. 安装依赖(已有大部分)
pip3 install requests playwright PyMuPDF

# 2. 安装浏览器(如果未安装)
python3 -m playwright install chromium

# 3. 运行测试
python3 scripts/financial_report_fetcher.py --stock "600519" --year 2024 --dry-run

注意事项

  1. 合规使用:仅下载公开披露的年报/研报,不用于商业再分发
  2. 频率控制:巨潮资讯建议 ≤10 次/分钟,东方财富 ≤5 次/分钟
  3. 登录态安全:cookies 和 storage_state 文件不提交到代码库
  4. 数据源时效性:年报披露有固定时间窗口(每年 1-4 月年报,7-8 月半年报)
  5. 港股/美股:需要额外数据源(HKEX披露易、SEC EDGAR)
  6. 反爬升级:如果巨潮 API 返回结构变化,需要更新 payload 参数

TODO / 扩展方向

  • 增加 HKEX 披露易支持(港股年报)
  • 增加 SEC EDGAR 支持(美股 10-K/10-Q)
  • 增加研报 AI 摘要(用 LLM 自动总结研报观点)
  • 增加财报数据对比(多年度趋势分析)
  • 增加飞书多维表格存储(自动同步下载记录)
  • 增加定时任务(财报季自动监控披露)

创建于:2026-06-18 by 小七 版本:0.1.0(方案设计)

Related skills

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai22 installs8 stars

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

More from tuobadaidai

Browse all skills

Convert fuzzy organizational problems into structured diagnostic reports with graded recommendations.

by tuobadaidai34 installs1 stars

Convert vague strategic questions into structured analysis with framework selection, audit gates, and explicit trade-offs.

by tuobadaidai15 installs

Grade AI-era candidates on a six-dimension L1–L4 scale from resumes and interview notes.

by tuobadaidai22 installs

工资数据审核系统,基于确定性规则引擎 + Python 脚本执行。 全量对齐《工资审核标准流程 SOP》6 步流程。v7.2 修复P0阻断bug:_get_pay_month() 支持 中文格式("2026年4月"/"2026年04月"/"202604"),RL-003/RL-007 排除逻辑完全生效。 v7.1...

by tuobadaidai30 installs

谛听培训专家。培训需求分析、培训方案设计、效果评估、能力建设。Use when 培训需求分析、培训方案设计、培训效果评估、能力建设体系、管理者赋能、新员工培训、领导力培训、技能培训体系、培训预算规划。不适用于薪酬结构、劳动法合规、绩效考核等非培训类问题。

by tuobadaidai21 installs

创建高质量 Skill 的技能。当用户说"创建技能""新建 Skill""把这个流程变成技能""做一个 XX 的 skill""帮我写个技能"时触发。不适用于使用已有技能执行任务——那是 use_skill 的工作。

by tuobadaidai17 installs1 stars