随着大数据概念和技术的迅速发展,传统金融概念与新兴技术结合形成了金融科技的概念。一部分学者认为企业层面的金融科技发展水平可以由企业披露年报中有关金融科技的技术词频进行衡量。本文讲解了技术层面实现从东方财富网爬取企业pdf格式年报,并将pdf格式文档批量转换为word或txt格式,最后统计每个文档中关于金融科技的词频形成一张样本*时间的面板数据。
年报pdf下载
-
批量下载年报的url地址
首先在东方财富网年报披露板块爬取各个公司所发年报的pdf文档所存储的url地址。from selenium import webdriver from selenium.common.exceptions import NoSuchElementException import random import time import csv import os os.chdir('C:/Users/王彤/Desktop/毕业论文/数据') class NianbaoSpider(): def __init__(self): self.start_url = 'http://xinsanban.eastmoney.com/Article/NoticeList' self.browser = webdriver.Chrome() self.browser.implicitly_wait(30) #self.num = input('请输入想要开始爬取的页数:') def get_data(self,num): self.browser.get(self.start_url) #选择公告 self.browser.find_element_by_xpath('/html/body/div[1]/div[3]/ul[2]/li[7]/a').click() #点击定期报告 self.browser.find_element_by_xpath('//*[@id="sNType"]/option[2]').click() #输入搜索关键词“年度报告” self.browser.find_element_by_xpath('//*[@id="txtKey"]').send_keys('年度报告') #点击查询 self.browser.find_element_by_xpath('//*[@id="btnNSearch"]').click() #从某一页页开始 time.sleep(20) # num = input('请输入想要开始爬取的页码数:') self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/input').send_keys(num) self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/span[3]').click() def get_content(self): tr_list = self.browser.find_elements_by_xpath('//*[@id="J-ajax-main"]/div/table/tbody/tr') url_dict = {} url_list = [] for tr in tr_list: url_dict['title'] = tr.find_element_by_xpath('./td[5]/a[1]').get_attribute('title') url_dict['link'] = tr.find_element_by_xpath('./td[5]/a[2]').get_attribute('href') # print(url_dict) if url_dict['title'].find('摘要') == -1: #print(url_dict.values()) url_list.append(tuple(url_dict.values())) #将符合要求的字典的值传入一个元组,在添加到列表,要不然字典会被最后的值覆盖 print(url_list) self.save_content(url_list) def save_content(self,url_list): with open('nianbao.csv','a',encoding='gbk',newline='') as f: writer = csv.writer(f) writer.writerows(url_list) def download_nianbao(self,num): self.get_data(num) for i in range(40): num += i # 给点时间,页面结构加载完成 time.sleep(random.uniform(4,6)) self.get_content() if self.browser.page_source.find('下一页') != -1: print('第%s页爬取完成'%num) if self.browser.page_source.find('上一页') == -1: # button = self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/a[6]') # self.browser.execute_script("arguments[0].click();", button) self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/a[6]').click() else: # button = self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/a[8]') # self.browser.execute_script("arguments[0].click();", button) self.browser.find_element_by_xpath('//*[@id="J-ajax-main"]/div/div[1]/a[8]').click() else: break def main(self,num): #self.dowmload_content(num) self.download_nianbao(num) # if __name__ == '__main__': # start = time.time() # spider = NianbaoSpider() # spider.main(1) # end = time.time() # print('程序执行时间%.2f' % (end - start))
在这一部分,实际操作中遇到东方财富网站反爬措施,网页动态加载并且限制一个ip访问次数,经常会遇到程序运行一段时间因为返回内容为空报错,处理方式是:简单的记录报错时爬取了多少页多次运行程序。将上述代码放到一个nianbao_download.py文件,再使用以下代码进行运行程序。程序保存年报名称和url到一个csv文件。
from nianbao_download import NianbaoSpider import time import random for i in range(8776,9000,40): print('开始第%s个页面循环'%i) #time.sleep(random.uniform(5,8)) NianbaoSpider().download_nianbao(i)
-
根据url地址爬取pdf文档
中心思想是:读取保存url的文档,直接requests请求url地址可以拿到全部内容并以二进制格式保存为pdf文档,将每家公司的文档保存到一个单独文件夹。import requests import os import pandas as pd import re os.chdir('C:/Users/王彤/Desktop/毕业论文/初期数据') df = pd.read_csv('./nianbao.csv',encoding='gbk') df = df.iloc[:17500] url_list = list(df['url']) title_list = list(df['name']) def write_html(html,path): # name = title + '.pdf' with open(path, 'wb') as f: f.write(html.content) f.close() failed_dict = {} failed_list = [] for multi in zip(url_list,title_list): try: html = requests.get(multi[0]) a_list = re.split(':|:',multi[1]) if not os.path.exists('./%s'%a_list[0]): os.mkdir('./%s'%a_list[0]) path = './%s/%s'%(a_list[0],a_list[1]) + '.pdf' write_html(html,path) except Exception as e: print('%s下载失败'%multi[1]) failed_dict['%s'%multi[1]] = multi[0]
pdf转换为txt文档
上一部分主要是下载了目标公司目标年份所有年报pdf文档,这一部分的工作主要是pdf转换为word或txt文本格式。
-
pdf转换为word——精细版
import pdfplumber import os import time # 使用os模块的walk函数,搜索出指定目录下的全部PDF文件 # 获取同一目录下的所有PDF文件的绝对路径 def getFileName(filedir): file_list = [os.path.join(root, filespath) \ for root, dirs, files in os.walk(filedir) \ for filespath in files \ if str(filespath).endswith('pdf') ] return file_list if file_list else [] def Pdf2Doc(pdf_file,docx_file): with pdfplumber.open(pdf_file) as pdf: pages = pdf.pages for p in pages: text = p.extract_text() with open(docx_file,'a',encoding='utf-8') as f: try: f.write(text) except Exception as e: continue # 主函数 def main(): time1 = time.time() file_dir = input("输入需要转换PDF的文件夹地址:") # 存放PDF的原文件夹 output_dir = input("输入保存Word的文件夹地址:") # 存放word的新文件夹 pdf_fileName_list = getFileName(file_dir) for pdf_file in pdf_fileName_list: print("路径:%s" % pdf_file) docx_file = pdf_file.split('.pdf')[0]+".txt" output_path1 = pdf_file.split('\\')[-2] output_path1 = os.path.join(output_dir,output_path1) docx_file = os.path.join(output_path1,docx_file.split('\\')[-1]) if os.path.exists(output_path1) == False: os.mkdir(output_path1) print('path:',docx_file) Pdf2Doc(pdf_file, docx_file) time2 = time.time() print('转换PDF文件耗时:%s s.' %(time2 - time1)) main()
-
pdf转换为txt文档——精简版
# -*- coding:utf-8*- import os import time from pdf2docx import Converter # 使用os模块的walk函数,搜索出指定目录下的全部PDF文件 # 获取同一目录下的所有PDF文件的绝对路径 def getFileName(filedir): file_list = [os.path.join(root, filespath) \ for root, dirs, files in os.walk(filedir) \ for filespath in files \ if str(filespath).endswith('pdf') ] return file_list if file_list else [] def Pdf2Doc(pdf_file,docx_file): # pdf_file = 'ContentServer (1).pdf' # docx_file = 'ContentServer (1).docx' # convert pdf to docx cv = Converter(pdf_file) cv.convert(docx_file, start=0, end=None) cv.close() # 主函数 def main(): time1 = time.time() file_dir = input("输入需要转换PDF的文件夹地址:") # 存放PDF的原文件夹 output_dir = input("输入保存Word的文件夹地址:") # 存放word的新文件夹 pdf_fileName_list = getFileName(file_dir) for pdf_file in pdf_fileName_list: print("路径:%s" % pdf_file) docx_file = pdf_file.split('.pdf')[0]+".docx" output_path1 = pdf_file.split('\\')[-2] output_path1 = os.path.join(output_dir,output_path1) docx_file = os.path.join(output_path1,docx_file.split('\\')[-1]) if os.path.exists(output_path1) == False: os.mkdir(output_path1) print('path:',docx_file) Pdf2Doc(pdf_file, docx_file) time2 = time.time() print('转换PDF文件耗时:%s s.' %(time2 - time1)) main()
词频统计
首先建立一个尽可能全面包含金融科技技术的词库,使用jieba库进行分词,统计每个词出现的频率并且对每一条记录添加公司和时间字段。
import jieba
import pandas as pd
import os
os.chdir('C:/Users/王彤/Desktop/毕业论文')
#统计词频的函数
def get_TF(path,document):
jieba.load_userdict("./词库.txt")
content = open('./文本数据/{}/{}'.format(path,document),encoding='utf-8').read()
words_list = jieba.lcut(content)
#使用pandas统计并降序排列
df = pd.DataFrame(words_list,columns=['word'])
df1 = df.groupby(['word']).size().sort_values(ascending=False)
with open(r'C:\Users\王彤\Desktop\毕业论文\金融科技词库.txt',encoding='utf-8') as f:
word_list = f.readlines()
#遍历列表,替换列表每个元素的字符\n
word_list = [x.replace('\n','') for x in word_list]
sample = df1[df1.index.isin(word_list)]
df2 = pd.DataFrame(sample)
result = df2.T
result['company'] = path
result['year'] = document[:4]
return result
运行代码循环统计词频。
a = os.listdir('./文本数据')
result = pd.read_excel('./词频统计.xlsx') #标题行(主要是包含所有金融科技相关的词)
for i in a:
b = os.listdir('./文本数据/%s'%i)
for j in b:
result1 = get_TF(i,j)
result = pd.concat([result,result1],axis=0,join='outer')
result.to_excel('词频统计结果.xlsx')