导读:本期聚焦于关中王创作的《R语言如何抓取巨潮资讯公告并进行上市公司公告文本挖掘与事件驱动分析?》,敬请观看详情。从上市公司公告中自动提取关键事件,是量化研究与基本面分析的重要环节。巨潮资讯作为官方信息披露平台,其公告数据覆盖面广、更新及时,但网页结构动态变化,直接抓取容易遇到反爬和接口限制。本文围绕R语言实现巨潮资讯公告抓取展开,先分析巨潮资讯的查询接口与分页逻辑,再通过httr与jsonlite构造请求、解析JSON数据,批量获取指定股票和日期范围内的公告列表。获得原始文本后,利用jiebaR进行中文分词和关键词提取,识别业绩预增、重大合同、股权变动等事件类型。最后结合事件窗口的收益率统计,演示一个基础的事件驱动策略思路。文章给出了完整可运行的R代码,帮助读者快速搭建自己的公告文本挖掘流程。

巨潮资讯网作为中国证监会指定的上市公司信息披露平台,汇集了沪深京三地上市公司的定期报告、临时公告、IPO文件等海量数据。对于量化研究员和基本面分析者而言,能否高效、结构化地获取这些公告文本,直接影响后续的事件驱动策略、舆情因子构建和风险预警效果。R语言凭借其强大的数据处理生态和统计分析能力,可以较为便捷地完成从公告抓取、文本清洗到事件识别的全流程。本文将围绕这一链路展开,给出可直接落地的R代码方案。

R语言如何抓取巨潮资讯公告并进行上市公司公告文本挖掘与事件驱动分析?

巨潮资讯公告查询接口与抓取思路

巨潮资讯的公告查询页面采用异步加载方式,用户在浏览器中点击查询后,前端会向后端接口发送POST请求,返回JSON格式的公告数据。这意味着绕过复杂的HTML解析,直接模拟该接口请求即可获得结构化数据。请求的核心地址为http://www.cninfo.com.cn/new/hisAnnouncement/query,需要携带股票代码、分页参数、日期范围以及栏目类型等表单字段。其中stock字段格式为“股票代码+市场标识”,例如平安银行的000001,gssz000001pageSize控制每页条数,pageNum为页码,seDate接收起止日期,column用于区分沪深京交易所板块。

在R语言中,可以使用httr包的POST函数发送表单请求,并通过jsonlite包解析返回内容。需要注意的是,巨潮资讯对请求头有一定校验,建议设置User-AgentReferer来模拟真实浏览器行为。下面是一段完整的抓取示例,它请求指定股票在某个日期范围内的前30条公告,并输出标题与PDF下载地址。

library(httr)
library(jsonlite)

base_url <- "http://www.cninfo.com.cn/new/hisAnnouncement/query"
headers <- c(
  "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
  "Referer" = "http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search"
)

query_params <- list(
  stock = "000001,gssz000001",
  tabName = "fulltext",
  pageSize = 30,
  pageNum = 1,
  column = "szse",
  category = "",
  plate = "",
  seDate = "2023-01-01~2023-12-31",
  searchkey = "",
  secid = "",
  sortName = "",
  sortType = "",
  isHLtitle = "true"
)

resp <- POST(base_url, add_headers(.headers = headers), body = query_params, encode = "form")
data <- fromJSON(content(resp, as = "text", encoding = "UTF-8"))
announcements <- data$announcements
print(head(announcements[, c("secName", "announcementTitle", "adjunctUrl")]))

返回结果中的announcements数据框包含公告标题、公司简称、公告时间以及附件下载地址等字段。其中adjunctUrl是PDF文件的相对路径,需要拼接域名前缀http://static.cninfo.com.cn/才能得到完整下载链接。如果只关心公告标题,那么直接对标题进行关键词匹配就能识别事件类型;如果要挖掘公告正文内容,则需要进一步下载PDF并提取文本。

抓取过程中有两个常见问题需要注意。第一是请求频率过高会被暂时封禁IP,建议在批量抓取时加入Sys.sleep(runif(1, 1, 3))随机延迟,降低反爬风险。第二是编码问题,巨潮资讯返回的JSON有时包含中文乱码,使用content(resp, as = "text", encoding = "UTF-8")可以指定编码,保证中文标题正确显示。

公告文本解析与中文文本挖掘

巨潮资讯的公告原文大多以PDF格式提供,R语言中可以使用pdftools包将PDF转换为纯文本。对于扫描件类的老公告,pdftools本身无法直接识别文字,此时可以考虑接入OCR工具,但大部分新公告的PDF都带有可提取的文本层。下载后通过pdf_text函数逐页读取,再将多个页面文本拼接成一个完整字符串,即可进入分词和关键词提取环节。

中文文本挖掘通常需要分词工具,jiebaR是R语言中常用的中文分词包,支持默认词典和用户自定义词典。对于上市公司公告这类专业语料,建议加入“预增”“扭亏为盈”“重大合同”“股权转让”等金融术语,提高分词准确率。分词后可以用freq函数统计词频,并过滤掉数字和常见停用词,筛选出高频关键词作为后续事件识别的候选特征。

library(pdftools)
library(jiebaR)
library(dplyr)

# 下载公告PDF并提取文本
pdf_url <- paste0("http://static.cninfo.com.cn/", announcements$adjunctUrl[1])
pdf_path <- "announcement.pdf"
download.file(pdf_url, pdf_path, mode = "wb")
text <- pdf_text(pdf_path) %>% paste(collapse = "\n")

# 添加自定义词典
engine <- worker(user = "finance_dict.txt")
words <- segment(text, engine)
keywords <- freq(words) %>%
  filter(!grepl("[0-9]+", char)) %>%
  arrange(desc(freq)) %>%
  head(20)
print(keywords)

上述代码中的finance_dict.txt需要提前准备,每一行写入一个自定义词语。如果暂时没有该文件,可以直接使用默认词典,但某些复合词可能被错误切分。例如“业绩预增”可能被切成“业绩”和“预增”两个词,这会影响后续事件的精确匹配。因此建议在实际项目中根据公告标题的高频词不断更新自定义词典。

除了简单词频统计,还可以使用TF-IDF方法提取公告的核心关键词,或者利用词向量模型计算公告之间的语义相似度。不过对于事件驱动策略的初步构建,词频与关键词匹配已经能够覆盖大多数事件类型。需要强调的是,公告标题往往已经浓缩了事件核心信息,如果只需要识别事件类型,优先对标题字段进行文本挖掘即可,无需下载全部PDF正文。

事件驱动分析与基础策略验证

事件驱动策略的核心思想是:当上市公司发布特定类型的公告时,其股价在事件窗口内往往会出现系统性反应。例如业绩预增公告通常带来正面超额收益,而大股东减持公告则可能引发短期下跌。通过自动识别公告事件,可以构建事件库,并计算事件前后的收益率分布,验证事件是否具有统计意义上的异常收益。

在R语言中,可以利用tidyverse套件对公告标题进行关键词匹配,生成事件类型标签。下面代码定义了三类事件及其对应的关键词集合,并使用str_detect对标题进行匹配。如果标题中包含多个关键词,可以通过优先级规则分配事件类型,比如先判断业绩预增,再判断重大合同,最后判断股权变动。

library(tidyverse)

event_keywords <- list(
  "业绩预增" = c("预增", "扭亏为盈", "大幅增长"),
  "重大合同" = c("重大合同", "中标", "合作协议"),
  "股权变动" = c("增持", "减持", "股权转让")
)

announcements <- announcements %>%
  mutate(event_type = case_when(
    str_detect(announcementTitle, paste(event_keywords$业绩预增, collapse = "|")) ~ "业绩预增",
    str_detect(announcementTitle, paste(event_keywords$重大合同, collapse = "|")) ~ "重大合同",
    str_detect(announcementTitle, paste(event_keywords$股权变动, collapse = "|")) ~ "股权变动",
    TRUE ~ "其他"
  ))

event_stats <- announcements %>%
  group_by(event_type) %>%
  summarise(count = n(), .groups = "drop")
print(event_stats)

得到事件类型后,就可以结合股票行情数据计算事件窗口收益。行情数据可以从开源数据源获取,例如使用quantmod包下载历史价格。计算事件窗口收益时,通常以公告发布日为事件日,考察事件日前后5个交易日的累计收益,并与同期大盘指数收益做对比,得到超额收益。如果某一类事件的平均超额收益显著偏离零,说明该事件具有可交易的信息含量。

需要提醒的是,简单事件驱动策略在实际执行中面临多个问题:公告发布时点可能早于事件日,市场可能已经提前反应;不同市场环境下事件效应会发生反转;小市值股票受流动性和涨跌停限制,实际可交易性较差。因此事件驱动策略更适合作为多因子选股的辅助信号,而不是独立交易系统。本文给出的文本挖掘流程为事件研究提供了数据基础,后续的收益分析需要结合更严谨的统计检验和风险调整模型。

批量抓取与稳定性优化

在实际项目中,往往需要批量抓取数百只股票在数年内发布的所有公告。此时单次请求已经无法满足需求,必须编写循环逻辑。可以使用lapplymap函数遍历股票代码列表,在每次请求之间加入随机延迟,并使用tryCatch捕获异常,避免单次失败导致整个抓取任务中断。同时建议将每次返回的公告数据实时写入本地数据库或RDS文件,以便断点续抓。

稳定性优化还包括请求头轮换和代理池的使用。巨潮资讯的反爬策略相对宽松,但持续高频请求仍可能触发IP限制。可以将多个真实浏览器的User-Agent放在一个向量中,每次请求随机选择一个,降低请求特征的一致性。另外,JSON解析失败时不要直接报错退出,而应记录错误日志并重试若干次。R语言中的httr包提供了RETRY函数,可以方便地实现指数退避重试。

另一个容易忽略的细节是公告附件链接的过期问题。巨潮资讯的部分公告PDF链接带有时间戳或会话参数,直接拼接可能无法下载。此时可以先请求公告详情页,解析页面中的真实下载链接。虽然这增加了代码复杂度,但对于需要保存原始公告文本的研究场景来说非常必要。建议将公告元数据和PDF文件分别存储,元数据存入数据框或SQLite数据库,PDF文件按照公告日期和股票代码归档到本地文件夹。

总体而言,R语言在巨潮资讯公告抓取与文本挖掘场景中具备完整的技术链支撑:httr处理网络请求,jsonlite解析结构化数据,pdftools读取文档内容,jiebaR完成中文分词,tidyverse进行数据处理与统计汇总。这套组合无需依赖Python或外部爬虫框架,即可在R环境中完成从数据获取到事件分析的全部工作,适合熟悉R语言的研究者和量化团队快速落地。

R语言巨潮资讯文本挖掘修改时间:2026-08-31 13:56:06

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。