Loading...
墨滴

Wyl

2021/04/23  阅读:160  主题:兰青

文本分析 | 年报关键词频统计

前言

上篇文章《【爬虫】30行代码轻松爬取全部A股公司年报》介绍了如何爬取2003-2019年A股全部年报,但是爬取的年报都是PDF格式,不能直接用于文本分析,需要先转换为TXT格式。因此,今天学习了一下如何运用Python将PDF转换为TXT,并在此基础上统计年报相关主题关键词词频

基本思路

1.获取年报PDF文档

2.利用PDFminer3k模块来抽取PDF内容并写入TXT文件

3.读取TXT文件,统计关键词词频并写入Excel文件

PDF转TXT

导入Python第三方库

import pandas as pd
import os
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import *
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage,PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

获取年报基本数据

这里有疑惑的读者请查看上篇文章《【爬虫】30行代码轻松爬取全部A股公司年报》

def get_data(iloc):
    rawdata['year'] = rawdata['rep_period'].dt.year
    firm = rawdata.at[iloc,'security_name'].replace("*",""# 去掉*ST的*号
    code = rawdata.at[iloc,'security_code']
    year = rawdata.at[iloc,'year']
    return firm,code,year

获取年报PDF文档路径

def load_pdf(code, firm,year):
    file_path = 'F:\\python\\推文例子\\年报关键词抓取'  # 自行修改
    file_name = "{}-{}-{}年年度报告".format(code,firm,year)
    pdf_path = os.path.join(file_path,file_name)
    return pdf_path

解析PDF文件,转为TXT格式

主要参考几位博主的做法,见文末参考资料链接

def parsePDF(pdf_path,txt_path):
    # 以二进制读模式打开pdf文档
    fp = open(pdf_path,'rb')

    # 用文件对象来创建一个pdf文档分析器
    parser = PDFParser(fp)

    # pdf文档的对象,与分析器连接起来
    doc = PDFDocument(parser=parser)
    parser.set_document(doc=doc)

    # 如果是加密pdf,则输入密码,新版好像没有这个属性
    # doc._initialize_password()

    # 创建pdf资源管理器 来管理共享资源
    resource = PDFResourceManager()

    # 参数分析器
    laparam=LAParams()

    # 创建一个聚合器
    device = PDFPageAggregator(resource,laparams=laparam)

    # 创建pdf页面解释器
    interpreter = PDFPageInterpreter(resource,device)
    
    # 用来计数页面,图片,曲线,figure,水平文本框等对象的数量
    num_page, num_image, num_curve, num_figure, num_TextBoxHorizontal = 00000

    # 获取页面的集合
    for page in PDFPage.get_pages(fp):
        num_page += 1  # 页面增一
        # 使用页面解释器来读取
        interpreter.process_page(page)

        # 使用聚合器来获取内容
        layout = device.get_result()
        # 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等 想要获取文本就获得对象的text属性,
        for x in layout:
            if isinstance(x,LTImage):  # 图片对象
                num_image += 1
            if isinstance(x,LTCurve):  # 曲线对象
                num_curve += 1
            if isinstance(x,LTFigure):  # figure对象
                num_figure += 1
            if isinstance(x, LTTextBoxHorizontal):  # 获取文本内容
                num_TextBoxHorizontal += 1  # 水平文本框对象增一
                    # 保存文本内容
                with open(txt_path, 'a',encoding='UTF-8',errors='ignore'as f:
                    results = x.get_text()
                    print(results,end='')
                    f.write(results + '\n')
        print('对象数量:\n','页面数:%s\n'%num_page,'图片数:%s\n'%num_image,'曲线数:%s\n'%num_curve,'水平文本框:%s\n'%num_TextBoxHorizontal)

主程序

作为示例,为了节约时间,本例只转换格力电器2010-2019年年报,请读者自行更换参数

if __name__ == "__main__":
    rawdata = pd.read_excel(r'F:\python\推文例子\年报关键词抓取\上市公司年报数据_2001_2019.xlsx', sheet_name = 0)
    for iloc in range(4170,4180):
        firm, code, year = get_data(iloc)
        pdf_path = load_pdf(code, firm, year) + ".pdf"
        txt_path = load_pdf(code, firm, year) + ".txt"
        print(pdf_path)
        parsePDF(pdf_path, txt_path)

运行结果

年报PDF转换TXT
年报PDF转换TXT

关键词词频统计

导入Python第三方库

import xlwt  

统计词频

# 加载txt列表寻找关键词并保存到excel
def matchKeyWords(txt_folder, keyWords):
    files = os.listdir(txt_folder)
    words_num = []  # 保存所有文件词频
    for file in files:
        word_freq = {}  # 单词出现频率次:word:num
        if os.path.splitext(file)[-1] == ".txt":
            txt_path = os.path.join(txt_folder, file)
            with open(txt_path, "r", encoding='utf-8', errors='ignore')as fp:
                text = fp.readlines()
                for word in keyWords:
                    num = 0
                    for line in text:
                        num += line.count(word)
                    word_freq[word] = num
                stock_code = file.split("-")[0]
                stock_name = file.split("-")[1]
                year = file.split("-")[2][0:4]
                words_num.append((word_freq, stock_code, stock_name,year))
    
    book=xlwt.Workbook(encoding='utf-8',style_compression=0)

    sheet=book.add_sheet('年报关键词词频统计',cell_overwrite_ok=True)
    sheet.write(0,0,'股票代码')
    sheet.write(0,1,'股票名称')
    sheet.write(0,2,'年份')
    sheet.write(0,3,'绿色')
    sheet.write(0,4,'节能环保')
    sheet.write(0,5,'保护环境')
    sheet.write(0,6,'减排')
    sheet.write(0,7,'节能')
    sheet.write(0,8,'节约')

    for index, one in enumerate(words_num):
        word_f = one[0]
        stock_code = one[1]
        stock_name = one[2]
        year = one[3]
        for ind, word in enumerate(keyWords):
            sheet.write(index + 1, ind + 3, str(word_f[word]))
        sheet.write(index + 10, stock_code)
        sheet.write(index + 11, stock_name)
        sheet.write(index + 12, year)
        
    book.save(r'F:\python\推文例子\年报关键词抓取\年报关键词词频统计.xls')

txt_folder = 'F:\\python\\推文例子\\年报关键词抓取'
keywords = ['绿色','节能环保','保护环境','减排','节能','节约']
matchKeyWords(txt_folder, keywords)

运行结果

关键词统计
关键词统计

小结

写了几篇文章下来,发现原来分享也是学习的一种动力所在。这篇文章的学习笔记是在一位粉丝的不断请教下激励自己完成的,如果放在平时应该会一直拖延下去。另外,需要指出的是,本文的操作过程仅作为示例,诸多细节需要进一步考虑,比如本文的PDF解析可能还不是很精确,会给后续的文本分析造成较为严重的后果,欢迎读者指出更为精确的PDF解析方法

知乎与公号:乌龙PySta(ID:wylcfy2014)
不定期推送:Python+Stata | 文本分析+机器学习 | 财务+会计

参考资料

[1] https://blog.csdn.net/zyc121561/article/details/80144825

[2] https://blog.csdn.net/Li_Jiaqian/article/details/80312103

[3] https://blog.csdn.net/weixin_43257951/article/details/84258861

Wyl

2021/04/23  阅读:160  主题:兰青

作者介绍

Wyl

厦门大学