打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

目录

  • 1. 背景介绍

  • 2. 爬取 Wind 上市公司年报

    • 2.1 获取年报地址

    • 2.2 下载年报 PDF 文件

  • 3. 爬取 CSMAR 上市公司年报

  • 4. 总结

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

  • 关于我们


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 接口。

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。

连享会 - 效率分析专题,2020年5月29-31日

📙 主讲嘉宾:连玉君 | 鲁晓东 | 张宁

🍏   课程主页:https://gitee.com/arlionn/TE

连享会-效率分析专题视频

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

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

  • 链 接:https://pan.baidu.com/s/1Vr_-YCSJAmyoKvfayTQqpw

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

#导入相应的包
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

免费公开课:

  • 直击面板数据模型 - 连玉君,时长:1小时40分钟
  • Stata 33 讲 - 连玉君, 每讲 15 分钟.
  • 部分直播课 课程资料下载 (PPT,dofiles等)
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
数据控有福了:国内40个免费数据源大放送!
逐渐嚣张,使用python采集CSDN文章数据保存PDF
旧文重发:年报的正确阅读姿势
还敢瞎炒?一记重拳!一群人睡不着了(附最新A股排雷指南)
“会说话的汤姆猫”发布年报预告,业绩大涨的金科文化股价却连跌,背后原因竟然是……
我所知道的金融数据库
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服