4. 公告新闻数据获取
事件抽取与事件研究的第一步不是建模,而是把“事件”从原始信息流中稳定地拿回来。上市公司公告、交易所新闻与财经媒体构成了三类互补的数据源:公告是法定披露、结构相对规范、权威性最高;交易所新闻带有监管与市场提示属性;财经媒体则时效快、覆盖面广,但噪声与重复也最多。本节围绕这三类来源,讲清数据来源、采集方法与合规边界。
一、核心原理:三类数据源的分层结构
理解数据获取,关键是理解它们的“生成—发布—传播”链路。上市公司公告由公司通过交易所信息披露系统提交,经交易所审核后发布,具有明确的公告编号、标题、类型与时间戳;交易所新闻由交易所或监管机构发布,常涉及监管问询、纪律处分、交易提示;财经媒体内容则由记者、编辑或自动化系统生产,转载、改写、标题党现象普遍。三者的权威性、结构化程度与时效性并不一致,采集策略也应分层。
二、方法流程:从来源到可用数据的采集链路
无论哪类来源,采集链路都可以抽象为“发现—抓取—解析—清洗—存储”五步。发现阶段要确定入口:公告可用交易所披露页或巨潮资讯的按日期、按公司检索;交易所新闻可用官网栏目页或 RSS;财经媒体可用栏目页、搜索页或 API。抓取阶段要处理分页、动态渲染与反爬;解析阶段要把 HTML/PDF 转成结构化字段;清洗阶段要统一时间格式、去除转载重复、补全股票代码;存储阶段建议保留原始快照与解析结果两套数据。
下面是一个最小可用的公告列表抓取示例,重点在于保留原始链接与发布时间,便于后续回溯:
import requests, time, hashlib, json
from bs4 import BeautifulSoup
HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; ResearchBot/1.0)"}
BASE = "https://www.cninfo.com.cn/new/hisAnnouncement/query"
def fetch_announcements(page=1, page_size=30):
payload = {
"pageNum": page,
"pageSize": page_size,
"column": "szse",
"tabName": "fulltext",
"plate": "",
"stock": "",
"searchkey": "",
"secid": "",
"category": "",
"trade": "",
"seDate": "2024-01-01~2024-01-31",
"sortName": "",
"sortType": "",
"isHLtitle": "true"
}
r = requests.post(BASE, data=payload, headers=HEADERS, timeout=15)
r.raise_for_status()
return r.json().get("announcements", [])
def normalize(item):
return {
"ann_id": item.get("announcementId"),
"title": item.get("announcementTitle"),
"sec_code": item.get("secCode"),
"sec_name": item.get("secName"),
"time": item.get("announcementTime"),
"url": "https://static.cninfo.com.cn/" + item.get("adjunctUrl", ""),
"hash": hashlib.md5((item.get("announcementTitle","") + str(item.get("announcementTime"))).encode()).hexdigest()
}
records = []
for p in range(1, 4):
for it in fetch_announcements(p):
records.append(normalize(it))
time.sleep(1.2)
with open("announcements.jsonl", "w", encoding="utf-8") as f:
for r in records:
f.write(json.dumps(r, ensure_ascii=False) + "\n")
print("saved", len(records))
财经媒体采集通常更复杂,因为页面结构变化频繁。建议优先使用官方 API 或 RSS;若必须解析 HTML,应把“列表页字段”和“详情页正文”分开处理,并对正文做去广告、去推荐位、去版权声明的清洗。
三、案例/场景:一次“业绩预告”事件的采集复盘
假设我们要研究某公司发布“业绩预告”后三日的市场反应。公告侧,我们从巨潮按股票代码与日期区间检索,拿到公告标题、发布时间与 PDF 链接;交易所新闻侧,检查是否有问询或关注函;媒体侧,抓取主流财经媒体在公告后 24 小时内的报道。实际执行中常见的情况是:公告 16:30 发布,媒体 16:45 转载,交易所新闻次日才出现。若只按“新闻发布时间”对齐,事件窗口会整体后移,导致研究结论偏差。因此,事件时间应以“首次权威披露时间”为准,媒体时间作为传播强度变量。
四、误区与合规注意事项
第一个误区是“抓到就算数”。公告 PDF 中的表格、附件与正文往往包含关键信息,只抓标题会漏掉业绩区间、交易金额等要素。第二个误区是忽视重复:同一公告可能被多家媒体改写,若不去重,事件会被重复计数。第三个误区是时间字段混用:公告时间、采集时间、媒体发布时间含义不同,必须分开存储。
合规方面,需重点关注以下几点:
- 遵守 robots.txt 与网站服务条款,不绕过登录、验证码或付费墙;
- 控制请求频率,设置合理间隔与并发上限,避免对目标站点造成压力;
- 不采集、不传播内幕信息或未公开重大信息,不将采集数据用于交易操纵;
- 尊重著作权,媒体正文仅用于研究分析,不对外全文转载;
- 保存采集日志与原始快照,便于审计与结果复现。
| 数据源 | 典型入口 | 关键字段 | 主要风险 | 建议频率 |
|---|---|---|---|---|
| 上市公司公告 | 交易所披露系统、巨潮资讯 | 公告编号、标题、类型、时间、PDF | PDF 解析难、附件遗漏 | 每日增量 + 历史回补 |
| 交易所新闻 | 交易所官网栏目、RSS | 标题、栏目、发布时间、正文 | 栏目改版、更新不规律 | 每日 2–4 次 |
| 财经媒体 | 门户财经、财经App、公众号 | 标题、正文、作者、发布时间 | 重复转载、标题党、反爬 | 按需 + 事件触发 |
把来源分层、把时间对齐、把合规前置,公告新闻数据获取才能成为事件抽取与事件研究的可靠底座,而不是后续误差的来源。