利用python分析pdf数据,分析上市公司财报

import re
import os.path
import matplotlib
import matplotlib.pyplot as plt
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
from IPython.display import display, HTML
from pandas import DataFrame
# from adjustText import adjust_text # 解析PDF文本,并保存到TXT文件中
def parse(pdf_path):
TEXT = ''
fp = open(pdf_path, 'rb')
# 用文件对象创建一个PDF文档分析器
parser = PDFParser(fp)
# 创建一个PDF文档
doc = PDFDocument()
# 连接分析器,与文档对象
parser.set_document(doc)
doc.set_parser(parser) # 提供初始化密码,如果没有密码,就创建一个空的字符串
doc.initialize() # 检测文档是否提供txt转换,不提供就忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 创建PDF,资源管理器,来共享资源
rsrcmgr = PDFResourceManager()
# 创建一个PDF设备对象
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
# 创建一个PDF解释其对象
interpreter = PDFPageInterpreter(rsrcmgr, device) # 循环遍历列表,每次处理一个page内容
# doc.get_pages() 获取page列表
startIndex = 0
isEnd = False for page in doc.get_pages():
interpreter.process_page(page)
# 接受该页面的LTPage对象
layout = device.get_result()
# 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象
# 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等
# 想要获取文本就获得对象的text属性, for x in layout:
if(isinstance(x, LTTextBoxHorizontal)):
text = x.get_text()
if(text.find('公司简介和主要财务指标')) > 0:
startIndex += 1
if(startIndex == 2):
TEXT += text if(text.find('主要会计数据和财务指标')) > 0:
isEnd = True
if(isEnd):
break return TEXT dir_path = os.path.abspath('.') + '\\pdf_files'
files = os.listdir(dir_path)
# print(files) pdfList = []
for file in files:
pdf_path = dir_path + '\\' + file
pdfList.append(parse(pdf_path)) comInfoList = [] for pdf in pdfList:
comInfo = {}
r = r'(?<=股票简称)\s*[^\n]+'
comInfo['股票简称'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=股票代码)\s*[^\n]+'
comInfo['股票代码'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=公司的法定代表人)\s*[^\n]+'
comInfo['公司的法定代表人'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=办公地址)\s*[^\n]+'
comInfo['办公地址'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=公司国际互联网网址)\s*[^\n]+'
comInfo['公司网址'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=电子信箱)\s*[^\n]+'
comInfo['电子信箱'] = re.findall(r, pdf)[0].strip() if re.search(r, pdf) else '' r = r'(?<=营业收入(元))\s*(([^\n]+\n){4})' m = re.findall(r, pdf)[0]
s = ''.join(m).replace(' ', '').split('\n') comInfo['2019年营业收入元'] = s[0]
comInfo['2018年营业收入元'] = s[1]
comInfo['2017年营业收入元'] = s[3] comInfoList.append(comInfo) # print(comInfoList)
data = {'股票简称': [], '股票代码': [], '公司的法定代表人': [], '办公地址': [], '公司网址': [], '电子信箱': []}
data2 = {'股票简称': [], '股票代码': [], '2019': [], '2018': [], '2017': []} for comInfo in comInfoList:
data['股票简称'].append(comInfo['股票简称'])
data['股票代码'].append(comInfo['股票代码'])
data['公司的法定代表人'].append(comInfo['公司的法定代表人'])
data['办公地址'].append(comInfo['办公地址'])
data['公司网址'].append(comInfo['公司网址'])
data['电子信箱'].append(comInfo['电子信箱']) data2['股票简称'].append(comInfo['股票简称'])
data2['股票代码'].append(comInfo['股票代码'])
data2['2019'].append(comInfo['2019年营业收入元'])
data2['2018'].append(comInfo['2018年营业收入元'])
data2['2017'].append(comInfo['2017年营业收入元']) print('1. 提取:股票简称、股票代码、公司的法定代表人、办公地址、公司网址、电子信箱')
df = DataFrame(data)
display(HTML(df.to_html())) print('2. 提取:主要会计数据和财务指标——第01-10位:最近三年营业收入(元)')
df2 = DataFrame(data2)
display(HTML(df2.to_html())) print('3. 所有同学,画一张或几张图,呈现一些规律')
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文 x = ['2017', '2018', '2019'] # texts = []
for comInfo in comInfoList:
y = [round(float(comInfo['2017年营业收入元'].replace(',', ''))/1000000, 2), round(float(comInfo['2018年营业收入元'].replace(',', ''))/1000000, 2), round(float(comInfo['2019年营业收入元'].replace(',', ''))/1000000, 2)]
plt.plot(x, y, label=comInfo['股票简称'])
for xx, yy in zip(x, y):
plt.text(xx, yy + 1, str(yy), ha='center', va='bottom', fontsize=10)
# texts.append(str(yy)) # new_texts = [plt.text(x_, y_, text, fontsize=10) for x_, y_, text in zip(x, y, texts)]
# adjust_text(new_texts, only_move={'text': 'x'}, arrowprops=dict(arrowstyle='-', color='grey'), save_steps=True) plt.xlabel("年份")
plt.ylabel("营业收入(百万元)")
plt.title("2017-2019各公司营业收入趋势图")
plt.legend(loc="upper left") plt.show() x = data['股票简称']
ys = []
for comInfo in comInfoList:
y = []
y.append(round(float(comInfo['2017年营业收入元'].replace(',', ''))/1000000, 2))
y.append(round(float(comInfo['2018年营业收入元'].replace(',', ''))/1000000, 2))
y.append(round(float(comInfo['2019年营业收入元'].replace(',', ''))/1000000, 2))
ys.append(y) chart = DataFrame(
data=ys,
index=x, columns=[2017, 2018, 2019]) chart.plot(kind='bar') plt.title("各公司营业收入2017-2019年度对比图")
plt.ylabel("营业收入(百万元)")
plt.legend()
plt.xticks(rotation=45) plt.show() print('4. 基于所画图,做一些文字解读')
利用python分析pdf数据,分析上市公司财报的更多相关文章
- 利用python将excel数据解析成json格式
利用python将excel数据解析成json格式 转成json方便项目中用post请求推送数据自定义数据,也方便测试: import xlrdimport jsonimport requests d ...
- 利用python进行微信好友分析
欢迎python爱好者加入:学习交流群 667279387 本文主要利用python对个人微信好友进行分析并把结果输出到一个html文档当中,主要用到的python包为itchat,pandas,py ...
- 利用Python读取外部数据文件
不论是数据分析,数据可视化,还是数据挖掘,一切的一切全都是以数据作为最基础的元素.利用Python进行数据分析,同样最重要的一步就是如何将数据导入到Python中,然后才可以实现后面的数据分析.数 ...
- 利用python设计PDF报告,jinja2,whtmltopdf,matplotlib,pandas
转自:https://foofish.net/python-crawler-html2pdf.html 工具准备 弄清楚了网站的基本结构后就可以开始准备爬虫所依赖的工具包了.requests.beau ...
- 利用Python将PDF文档转为MP3音频
1. 转语音工具 微信读书有一个功能,可以将书里的文字转换为音频,而且声音优化的不错,比传统的机械朗读听起来舒服很多. 记得之前看到过Python有一个工具包,可以将文字转换为语音,支持英文和中文,而 ...
- 利用Python进行数据分析——数据规整化:清理、转换、合并、重塑(七)(1)
数据分析和建模方面的大量编程工作都是用在数据准备上的:载入.清理.转换以及重塑.有时候,存放在文件或数据库中的数据并不能满足你的数据处理应用的要求.很多人都选择使用通用编程语言(如Python.Per ...
- 利用python基于微博数据打造一颗“心”
一年一度的虐狗节将至,朋友圈各种晒,晒自拍,晒娃,晒美食,秀恩爱的.程序员在晒什么,程序员在加班.但是礼物还是少不了的,送什么好?作为程序员,我准备了一份特别的礼物,用以往发的微博数据打造一颗&quo ...
- 利用python将excel数据导入mySQL
主要用到的库有xlrd和pymysql, 注意pymysql不支持python3 篇幅有限,只针对主要操作进行说明 连接数据库 首先pymysql需要连接数据库,我这里连接的是本地数据库(数据库叫ld ...
- 利用Python读取json数据并求数据平均值
要做的事情:一共十二个月的json数据(即12个json文件),json数据的一个单元如下所示.读取这些数据,并求取各个(100多个)城市年.季度平均值. { "time_point&quo ...
- 一例tornado框架下利用python panda对数据进行crud操作
get提交部分 <script> /* $("#postbtn").click(function () { $.ajax({ url:'/loaddata', data ...
随机推荐
- [C++核心编程] 2、引用
文章目录 2 引用 2.1 引用的基本使用 2.2 引用注意事项 2.3 引用做函数参数 2.4 引用做函数返回值 2.5 引用的本质 2.6 常量引用 2 引用 2.1 引用的基本使用 **作用: ...
- 一文梳理z-index和层叠上下文
前言 最近参与某前端项目架构改造,发现项目中滥用z-index,设置的值有几十种并且不统一.在对项目的z-index进行梳理和统一过程中也深入学习了一下z-index,并撰写成文,希望也能帮助到陌生的 ...
- 工作中,我们经常用到哪些SQL语句呢?
目录 一.DDL部分(create.drop.alter) 1.1 create 语句上 1.2 drop 语句 1.3 alter 语句 二.DML(数据操纵语言)和DQL(数据查询语言) 2.1 ...
- Pwn系列之Protostar靶场 Stack3题解
(gdb) disass main Dump of assembler code for function main: 0x08048438 <main+0>: push ebp 0x08 ...
- Vue2积分商城项目
一.清空项目非必要文件和用户片段,路径提示的配置 views 下面的文件只保留 Home.vue ,其余删除,删除 components/HelloWorld.vue,并且 Home.vue 中不再引 ...
- 2022-09-03:n块石头放置在二维平面中的一些整数坐标点上 每个坐标点上最多只能有一块石头 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。 给你一个长度为 n 的数组
2022-09-03:n块石头放置在二维平面中的一些整数坐标点上 每个坐标点上最多只能有一块石头 如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头. 给你一个长度为 n 的数组 ...
- Could not resolve com.android.tools.lint:lint-kotlin:26.2.0.
好久没有使用weexplus publish android 打包apk, 今一运行失败了,提示Could not resolve com.android.tools.lint:lint-kotlin ...
- adb查看端口号,杀进程
1.先查看端口号占用的进程 netstat -ano | findstr 8000 2.在杀掉我们查出的进程15812 3.再次查看8000端口号的进程
- Python基础 - 解释性语言和编译性语言
什么是机器语言 计算机是不能理解高级语言,当然也就不能直接执行高级语言了.计算机只能直接理解机器语言,所以任何语言,都必须将其翻译成机器语言,计算机才能运行高级语言编写的程序. 如何把我们写的代码 ...
- 【论文阅读】Uformer:A General U-Shaped Transformer for Image Restoration
前言 博客主页:睡晚不猿序程 首发时间:2023.6.8 最近更新时间:2023.6.8 本文由 睡晚不猿序程 原创 作者是蒻蒟本蒟,如果文章里有任何错误或者表述不清,请 tt 我,万分感谢!orz ...