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. 基於所畫圖,做一些文字解讀')