Python:爬取上市公司公告-Wind-CSMAR

发布时间:2020-04-30 阅读 1255

Stata 连享会   主页 || 视频 || 推文

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

课程详情 https://gitee.com/arlionn/Course   |   lianxh.cn

课程主页 https://gitee.com/arlionn/Course

作者: 秦利宾 (厦门大学)
邮箱: qlb150@163.com

目录


1. 背景介绍

目前,上市公司公告主要从巨潮网、上交所以及深交所等网站获取。爬取的步骤分为以下两步,一是获取公告地址,二是通过公告地址下载 PDF 文件。通常来说,获取公告地址比较麻烦。本文将根据 WindCSMAR 数据库的公告信息简化获取公告地址过程,并下载 PDF 文件,这里以年报为例。

2. 爬取 Wind 上市公司年报

2.1 获取年报地址

首先,打开 Wind 终端,按照公司公告->年度报告->高级检索的步骤检索上市公司年报信息。

年报检索

其次,点击导出列表,将检索到的年报信息导出到 Excel 文件。需要注意的是,Wind 最多导出 9999 条记录。实际操作中,可以通过在检索中设置时间区间分批导出。

下载年报信息

最后,公告标题在 Excel 中是以超链接形式存在,通过 Excel 中的函数 FORMULATEXT() 可以将超链接分解成链接和文本两部分。进一步,可以通过调用 Python 进行拆分,提取公告地址链接。

获取年报地址
def address(str):    #定义提取公告地址函数
    return str.split('"')[1]
data["公告地址"] = data["公告地址"].apply(address)

2.2 下载年报 PDF 文件

打开年报地址,可以看到年报页面是由年报 PDF 超链接和年报内容两部分组成。其中,PDF 超链接可以通过 Xpath正则表达式 获取。

年报地址内容
#利用Xpath提取年报PDF链接
def pdf_url(url):
   html = requests.get(url).text #获取网页源代码
   tree = etree.HTML(html)  #解析网页
   url = tree.xpath("//div[2]/a/@href") #获取PDF链接
   return "http://news.windin.com/ns/" + url[0]
data["PDF地址"] = data["公告地址"].apply(pdf_url)
#利用正则表达式提取年报PDF链接
def pdf_url(url):
    html = requests.get(url).text
    url = re.findall("(?<=href=).*(?=class)", html) #?<= 正则肯定式向后看 ?= 正则肯定式向前看   
    return "http://news.windin.com/ns/" + url[0] 
data["PDF地址"] = data["公告地址"].apply(pdf_url)

根据提取到的年报 PDF 链接下载文件。

for index, row in data.iterrows():
    name = row["证券代码"][:6] + "_" + row["公告日期"] + ".pdf" #文件名称
    url = row["PDF地址"]      #pdf地址
    times = 1                 #失败后,重新获取次数
    while times <= 3:         #3次都失败后跳出循环
        try:
            urlretrieve(url, filename =  r"./PDF/" + name) #下载pdf
            print(f"成功下载{name}!")
            break
        except:
            times += 1 
            print(f"休息5秒!再试第{times}次!")
            time.sleep(5)
print("成功下载所有PDF文件!")

3. 爬取 CSMAR 上市公司年报

首先,打开 CSMAR 数据库,按照市场咨询系列->公告->公告分类关联表和公告证券关联表步骤,下载上市公司公告信息。其中,年报正文分类编码为 01030101

CSMAR 公告信息

其次,根据公告分类关联表和公告证券关联表共同字段,合并两个表。

data1 = pd.read_excel("ANN_Classify.xlsx")[2:] #剔除前两行中文标题和单位
data2 = pd.read_excel("ANN_Security.xlsx")[2:]
data = pd.merge(data1, data2, on = ["AnnouncementID", "DeclareDate", "FullDeclareDate", "Title"])
分类和证券关联表合并

最后,生成年报 PDF 链接,并下载。

#巨潮咨询网年报链接形式
#http://static.cninfo.com.cn/finalpage/2020-04-14/1207489969.PDF
#生成年报PDF链接
data["pdf_url"] = "http://static.cninfo.com.cn/finalpage/" + data["DeclareDate"] + "/" + data["AnnouncementID"] + ".PDF"
#根据PDF链接下载
for index, row in data.iterrows(): 
    name = row["Symbol"] + "_" + row["DeclareDate"] + ".pdf" #文件名称
    print(name)
    url = row["pdf_url"]       #pdf地址
    times = 1                  #失败后,重新获取次数
    while times <= 3:         #3次都失败后跳出循环
        try:
            urlretrieve(url, filename =  r"./PDF/" + name)
            print(f"成功下载{name}!")
            break
        except:
            times += 1 
            print(f"休息5秒!再试第{times}次!")
            time.sleep(5)
print("成功下载所有PDF文件!")

4. 总结

通过数据库提供的公告信息,可以大大简化爬取公告难度。同时,相较于 CSMAR 而言,Wind 提供的公告信息更加详尽。

当然,爬取公告只是文本分析的开始,后续还有很多工作要做,如提取文本、分词、词频统计、关键词提取、情感分析、以及文本相似度计算等。

其中,从 PDF 中提取信息就是一项繁杂的工作。我们应该尽力去找那些以 网页形式 展示公告内容的网站,如 Wind网易财经等,其次可以考虑用专门的 PDF转换软件API 接口将 PDF 转换为TXT

最后,可考虑 Pythonpdfminer3kpdfplumber 等包,并且 pdfplumber 可以很好提取表格数据。

关于图片文字识别,可以参考 百度AI 提供的文字识别 API 接口。

5. 附:文中涉及的主要 Python 代码

完整 .py 文件​,可以到百度云盘下载:

  • 链 接:https://pan.baidu.com/s/1Vr_-YCSJAmyoKvfayTQqpw
  • 提取码:u7ku

如下是文中使用的主要代码:

#导入相应的包
import os      
import pandas as pd 
import requests
import re
from lxml import etree #解析网页
from urllib.request import urlretrieve #下载网络文件到本地
import time 

#设置地址
os.chdir(r"D:\爬取上市公告") #修改为自己文件路径
os.getcwd()

#爬取上市公司年报_Wind
data = pd.read_excel("公司公告.xlsx")[:-1] #读入数据,并删除最后一行(最后一行为空值)
def address(str):            #定义提取公告地址函数
    return str.split('"')[1]
data["公告地址"] = data["公告地址"].apply(address)
def pdf_url(url): #利用Xpath提取年报PDF链接
    html = requests.get(url).text
    tree = etree.HTML(html)  #解析网页
    url = tree.xpath("//div[2]/a/@href") #获取PDF链接
    return "http://news.windin.com/ns/" + url[0]
data["PDF地址"] = data["公告地址"].apply(pdf_url)
for index, row in data.iterrows(): #下载年报
    name = row["证券代码"][:6] + "_" + row["公告日期"] + ".pdf" #文件名称
    url = row["PDF地址"] #pdf地址
    times = 1                  #失败后,重新获取次数
    while times <= 3:          #3次都失败后跳出循环
        try:
            urlretrieve(url, filename =  r"./PDF/" + name)
            print(f"成功下载{name}!")
            break
        except:
            times += 1 
            print(f"休息5秒!再试第{times}次!")
            time.sleep(5)
print("成功下载所有PDF文件!")


#爬取上市公司年报_CSMAR

data1 = pd.read_excel("ANN_Classify.xlsx")[2:] #剔除前两行中文标题和单位
data2 = pd.read_excel("ANN_Security.xlsx")[2:]
data = pd.merge(data1, data2, on = ["AnnouncementID", "DeclareDate", "FullDeclareDate", "Title"])
data["pdf_url"] = "http://static.cninfo.com.cn/finalpage/" + data["DeclareDate"] + "/" + data["AnnouncementID"] + ".PDF" #根据巨潮资讯网年报链接形式,生产PDF年报链接
for index, row in data.iterrows():  #下载前年报
    name = row["Symbol"] + "_" + row["DeclareDate"] + ".pdf" #文件名称
    print(name)
    url = row["pdf_url"]       #pdf地址
    times = 1                  #失败后,重新获取次数
    while times <= 3:          #3次都失败后跳出循环
        try:
            urlretrieve(url, filename =  r"./PDF/" + name)
            print(f"成功下载{name}!")
            break
        except:
            times += 1 
            print(f"休息5秒!再试第{times}次!")
            time.sleep(5)
print("成功下载所有PDF文件!")  

相关课程

连享会-直播课 上线了!
http://lianxh.duanshu.com

免费公开课:


课程一览

支持回看,所有课程可以随时购买观看。

专题 嘉宾 直播/回看视频
Stata暑期班 连玉君
江艇
线上直播 9 天
2020.7.28-8.7
效率分析-专题 连玉君
鲁晓东
张 宁
视频-TFP-SFA-DEA
已上线,3天
文本分析/爬虫 游万海
司继春
视频-文本分析与爬虫
已上线,4天
空间计量系列 范巧 空间全局模型, 空间权重矩阵
空间动态面板, 空间DID
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
直击面板数据模型 [免费公开课,2小时]

Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。


关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。直播间 有很多视频课程,可以随时观看。
  • 连享会-主页知乎专栏,300+ 推文,实证分析不再抓狂。
  • 公众号推文分类: 计量专题 | 分类推文 | 资源工具。推文分成 内生性 | 空间计量 | 时序面板 | 结果输出 | 交乘调节 五类,主流方法介绍一目了然:DID, RDD, IV, GMM, FE, Probit 等。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:
    • 课程, 直播, 视频, 客服, 模型设定, 研究设计, 暑期班
    • stata, plus,Profile, 手册, SJ, 外部命令, profile, mata, 绘图, 编程, 数据, 可视化
    • DID,RDD, PSM,IV,DID, DDD, 合成控制法,内生性, 事件研究, 交乘, 平方项, 缺失值, 离群值, 缩尾, R2, 乱码, 结果
    • Probit, Logit, tobit, MLE, GMM, DEA, Bootstrap, bs, MC, TFP, 面板, 直击面板数据, 动态面板, VAR, 生存分析, 分位数
    • 空间, 空间计量, 连老师, 直播, 爬虫, 文本, 正则, python
    • Markdown, Markdown幻灯片, marp, 工具, 软件, Sai2, gInk, Annotator, 手写批注, 盈余管理, 特斯拉, 甲壳虫, 论文重现, 易懂教程, 码云, 教程, 知乎

连享会主页  lianxh.cn
连享会主页 lianxh.cn

连享会小程序:扫一扫,看推文,看视频……


扫码加入连享会微信群,提问交流更方便

✏ 连享会学习群-常见问题解答汇总:
https://gitee.com/arlionn/WD