# 将"文化娱乐行业.xlsx"转换为"文化娱乐行业.csv"
import pandas as pd
import openpyxl
import re
import os
os.chdir(r'C:\Users\HP\Desktop\金融数据获取参考文件\大作业')
xlsx = '文化娱乐行业.xlsx'
df = pd.read_excel(xlsx)#读取excel表格中的内容
exf = openpyxl.load_workbook(xlsx)
sheet = exf.active #选择"活跃"的表格
C2 = sheet['C2']
C = sheet['C']
links = [c.value for c in C]
links_1 = links[1:-1]
links_2 = ''.join(links_1)
p = re.compile('"(.*?)","(.*?)"')
list_of_tuple = p.findall(links_2)
df2 = pd.DataFrame({'link': [t[0] for t in list_of_tuple],
'f_name': [t[1] for t in list_of_tuple]})
print(df2)
df2.to_csv('文化娱乐行业.csv')
link f_name 0 http://news.windin.com/ns/bulletin.php?code=16... 当代文体:2020年年度报告(修订版) 1 http://news.windin.com/ns/bulletin.php?code=91... 美盛文化:2020年年度报告(更新后) 2 http://news.windin.com/ns/bulletin.php?code=9A... 美盛文化:2020年年度报告摘要(更新后) 3 http://news.windin.com/ns/bulletin.php?code=E5... 欢瑞世纪:2020年年度报告(更新后) 4 http://news.windin.com/ns/bulletin.php?code=DD... ST三五:2020年年度报告(更新后) .. ... ... 278 http://news.windin.com/ns/bulletin.php?code=B4... 中青宝:2019年年度报告 279 http://news.windin.com/ns/bulletin.php?code=AD... 中青宝:2019年年度报告摘要 280 http://news.windin.com/ns/bulletin.php?code=7B... 横店影视:2019年年度报告 281 http://news.windin.com/ns/bulletin.php?code=8A... 横店影视:2019年年度报告摘要 282 http://news.windin.com/ns/bulletin.php?code=E0... 金利科技:2016年年度报告 [283 rows x 2 columns]
# 对“文化娱乐行业.csv”中f_name列进行重命名并进行筛选,保留所需要的年报内容
# 对f_name列进行匹配重命名
import re
import pandas as pd
import os
df = pd.read_csv("文化娱乐行业.csv",engine = "python",encoding = "utf-8")
p = re.compile("(?<=\d{4})(年度年报)|(年报)|(年年报)")
f_names = [p.sub("年年度报告",f) for f in df.f_name]
df["f_name"] = f_names;del p,f_names
print(df)
Unnamed: 0 link \ 0 0 http://news.windin.com/ns/bulletin.php?code=16... 1 1 http://news.windin.com/ns/bulletin.php?code=91... 2 2 http://news.windin.com/ns/bulletin.php?code=9A... 3 3 http://news.windin.com/ns/bulletin.php?code=E5... 4 4 http://news.windin.com/ns/bulletin.php?code=DD... .. ... ... 278 278 http://news.windin.com/ns/bulletin.php?code=B4... 279 279 http://news.windin.com/ns/bulletin.php?code=AD... 280 280 http://news.windin.com/ns/bulletin.php?code=7B... 281 281 http://news.windin.com/ns/bulletin.php?code=8A... 282 282 http://news.windin.com/ns/bulletin.php?code=E0... f_name 0 当代文体:2020年年度报告(修订版) 1 美盛文化:2020年年度报告(更新后) 2 美盛文化:2020年年度报告摘要(更新后) 3 欢瑞世纪:2020年年度报告(更新后) 4 ST三五:2020年年度报告(更新后) .. ... 278 中青宝:2019年年度报告 279 中青宝:2019年年度报告摘要 280 横店影视:2019年年度报告 281 横店影视:2019年年度报告摘要 282 金利科技:2016年年度报告 [283 rows x 3 columns]
# 定义"filter_links"函数用于对表格f_name一列进行筛选,保留所需要的年报
def filter_links(words,df,include=True):
ls=[]
for word in words:
if include:
ls.append([word in f for f in df.f_name])
else:
ls.append([word not in f for f in df.f_name])
index = []
for r in range(len(df)):
flag = not include
for c in range(len(words)):
if include:
flag = flag or ls[c][r]
else:
flag = flag and ls[c][r]
index.append(flag)
df2 = df[index]
return(df2)
df_all = filter_links(["摘要","述职报告","社会责任","审计","财务","风险","债券",],df,include= False) #false为剔除的部分
df_orig = filter_links(["(","("],df_all,include = False)#剔除带括号的年报 只保留没括号的年报
df_updt = filter_links(["(","("],df_all,include = True)#带括号的年报
print(df_orig)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-fd5ccca1dafa> in <module> 18 df2 = df[index] 19 return(df2) ---> 20 df_all = filter_links(["摘要","述职报告","社会责任","审计","财务","风险","债券",],df,include= False) #false为剔除的部分 21 df_orig = filter_links(["(","("],df_all,include = False)#剔除带括号的年报 只保留没括号的年报 22 df_updt = filter_links(["(","("],df_all,include = True)#带括号的年报 NameError: name 'df' is not defined
# 定义"sub_with_update"函数,通过该函数对f_name列进行整理,以公司简称分类
def sub_with_update(df_updt,df_orig):
df_newest = df_orig.copy()
index_orig=[]
index_updt=[]
for i,f in enumerate(df_orig.f_name):
for j,fn in enumerate(df_updt.f_name):
if f in fn:
index_orig.append(i)
index_updt.append(j)
for n in range(len(index_orig)):
i = index_orig[n]
j = index_updt[n]
df_newest.iloc[i,-2] = df_updt.iloc[j,-2]
return(df_newest)
df_newest = sub_with_update(df_updt,df_orig)
df_newest.sort_values(by = ["f_name"],inplace=True,ignore_index=True)
df_newest["公司简称"] = [f[:4] for f in df_newest.f_name]
print(df_newest)
Unnamed: 0 link \ 0 32 http://news.windin.com/ns/bulletin.php?code=0A... 1 140 http://news.windin.com/ns/bulletin.php?code=6A... 2 44 http://news.windin.com/ns/bulletin.php?code=C3... 3 20 http://news.windin.com/ns/bulletin.php?code=E9... 4 46 http://news.windin.com/ns/bulletin.php?code=57... .. ... ... 118 234 http://news.windin.com/ns/bulletin.php?code=90... 119 96 http://news.windin.com/ns/bulletin.php?code=E5... 120 226 http://news.windin.com/ns/bulletin.php?code=23... 121 134 http://news.windin.com/ns/bulletin.php?code=1E... 122 202 http://news.windin.com/ns/bulletin.php?code=49... f_name 公司简称 0 *ST中南:2020年年度报告 *ST中 1 *ST大晟:2020年年度报告 *ST大 2 *ST天娱:2020年年度报告 *ST天 3 *ST天润:2020年年度报告 *ST天 4 *ST当代:2020年年度报告 *ST当 .. ... ... 118 顺网科技:2019年年度报告 顺网科技 119 顺网科技:2020年年度报告 顺网科技 120 鹿港文化:2019年年度报告 鹿港文化 121 鹿港文化:2020年年度报告 鹿港文化 122 鼎龙文化:2019年年度报告 鼎龙文化 [123 rows x 4 columns]
# 根据排列情况,提取年报数量最多的十家公司,并将链接存储于"10companies"文件夹中
counts = df_newest["公司简称"].value_counts()
ten_company = []
for cn in counts.index[:10]:
ten_company.append(filter_links([cn],df_newest))
if not os.path.exists("10companies"):
os.makedirs("10companies")
for df_com in ten_company:
cn = df_com["公司简称"].iloc[0]
df_com.to_csv("10companies/%s.csv" % cn)
ten_csv = os.listdir("10companies")
# 根据所形成的"10companies"文件夹,对内部的csv文件进行拆分,形成下载pdf年报的链接
import re
import os
import requests
import pandas as pd
import time
#利用for循环对文件夹中十个csv文件分别处理获取链接
for info in os.listdir('10companies'):
domain = os.path.abspath(r'10companies') #获取文件夹的路径
info = os.path.join(domain,info) #将路径与文件名结合起来就是每个文件的完整路径
df = pd.read_csv(info)
links = df["link"];f_names = df["f_name"]
def get_PDF_url(url):
r = requests.get(url); r.encoding = 'utf-8'; html = r.text
r.close() # 已获取html内容,结束connection
p = re.compile('<a href=(.*?)\s.*?>(.*?)</a>', re.DOTALL)
a = p.search(html) # 因第一个<a>即是目标标签,故用search
if a is None:
Warning('没有找到下载链接。请手动检查链接:%s' % url)
return()
else:
href = a.group(1); fname = a.group(2).strip()
href = r.url[:26] + href # 形成完整的链接
return((href,fname))
hrefs = []; fnames = []
for link in links:
href,fname = get_PDF_url(link)
hrefs.append(href)
fnames.append(fname)
time.sleep(0)
df_final_links = pd.DataFrame({'href': hrefs,
'f_name': fnames})
ste = info[-8:-4]#将各个公司的名称赋予ste变量
df_final_links.to_csv("final_links_"+ste+".csv")#将不同公司的年报链接分别储存在不同的csv文件
#运行选出的公司有一家公司通过代码无法获得年报链接的csv 故手动删除
# 通过提取下载后csv文件里的链接,下载各家公司各个年份的年报pdf文件
import os
import requests
import pandas as pd
import time
for info in os.listdir('10companies'):#通过for循环对不同csv文件分别进行处理
domain = os.path.abspath(r'10companies') #获取文件夹的路径
info = os.path.join(domain,info) #将路径与文件名结合起来就是每个文件的完整路径
df = pd.read_csv(info)
ste = info[-8:-4]
df_final_links = pd.read_csv("final_links_"+ste+".csv")
hrefs = df_final_links["href"]
f_names = df_final_links["f_name"]
for i in range(len(hrefs)):#对每个csv文件中已生成的链接通过for循环进行下载
href = hrefs[i];f_name = f_names[i]
r = requests.get(href,allow_redirects=True)
open('%s'%f_name,'wb').write(r.content)
time.sleep(0)
r.close()
# 为了后续操作简便,已将下载好的pdf文件放到不同的文件夹,并进行相应命名
# 通过正则匹配定位年报中主要会计数据——当年的营业收入,提取放入DataFrame
import fitz # pip install pymupdf
import re
import pandas as pd
import os
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
df = pd.DataFrame()
i = 0
for info in os.listdir('10companies'):
domain = os.path.abspath(r'10companies') #获取文件夹的路径
info = os.path.join(domain,info)
ste = info[-8:-4]#将公司名称赋给st3
filenames = os.listdir(ste)#获取各个公司文件夹中pdf文件的名称
sale = []
for pdf in filenames:
pdf = "\\"+pdf
x = "C:\\Users\\HP\\Desktop\\金融数据获取参考文件\\大作业\\"+ste+pdf
#形成路径链接
def getText(pdf):#定义函数获取文本
text = ''
doc = fitz.open(pdf)
for page in doc:
text += page.getText()
doc.close()
text = text.replace(" "," \n")
text = text.replace("\n\n","\n")
return(text)
def get_content(pdf):
text = getText(pdf)
p = re.compile('(?<=\\n)\D、\s*\D*?主要\D*?数据\D*?\s*(?=\\n)(.*?)经营活动产生的',re.DOTALL)#定位各个年报固定位置的内容
content = p.search(text).group(0)
return(content)
def parse_data_line(pdf):
content = get_content(pdf)
subp = "([0-9,.%\- ]*?)\n"
psub = "%s%s%s%s" % (subp,subp,subp,subp)
p =re.compile("(?<=\\n)营业(\D*?\n)+%s" % psub)#定义营业收入那一行的内容
lines = p.search(content)
lines = lines[0]#形成列表内容
return(lines)
sale_gain = parse_data_line(x)
sale_gain = sale_gain.split("\n")#将列表里的字符串以换行符进行分割,形成新的列表
sale_gain = sale_gain[1]#取列表中第二个字符串,即营业收入
sale.append(sale_gain)#将营业收入放入新的列表
df.insert(i, ste, sale)#以列为单位加入表格
i=i+1
print(df)
df.to_csv("9companies")#将循环后生成的DataFrame表格形成一个新的csv文件
Deprecation: 'getText' removed from class 'Page' after v1.19.0 - use 'get_text'.
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-15-f170e5378e2d> in <module> 15 info = os.path.join(domain,info) 16 ste = info[-8:-4]#将公司名称赋给st3 ---> 17 filenames = os.listdir(ste)#获取各个公司文件夹中pdf文件的名称 18 sale = [] 19 for pdf in filenames: FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'nies'
# 通过表格制作营业收入的对比图
# 以行为单位取营业收入为列表,并将列表中的字符串类型转为浮点型
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd
import csv
from matplotlib.pyplot import MultipleLocator
import numpy as np
csv_data1 = pd.read_csv("9companies")
csv_df1 = pd.DataFrame(csv_data1)
csv_df_new1 = csv_df1.iloc[:7,1:11]#得到包含所有公司不同年份营业收入的表格
list_row = csv_df_new1.values.tolist()#以行为单位取成列表
list_name = list(csv_df_new1)#取行业名称
columns = csv_df_new1.columns
list_columns = []
for c in columns:
d = csv_df_new1[c].values.tolist()
list_columns.append(d)#以列为单位取成列表
for i in range(len(list_row)):
print(list_row[i])
print("\n")
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import pandas as pd
import csv
from matplotlib.pyplot import MultipleLocator
import numpy as np
csv_data1 = pd.read_csv("9companies")
csv_df1 = pd.DataFrame(csv_data1)
csv_df_new1 = csv_df1.iloc[:7,1:11]#得到包含所有公司不同年份营业收入的表格
list_row = csv_df_new1.values.tolist()#以行为单位取成列表
list_name = list(csv_df_new1)#取行业名称
columns = csv_df_new1.columns
list_columns = []
for c in columns:
d = csv_df_new1[c].values.tolist()
list_columns.append(d)#以列为单位取成列表
print(list_name)
for i in range(len(list_row)):
print(list_row[i])
print("\n")
['14,689,715,6', '2,475,616,071.21', '540,047,298.34 ', '3,220,501,920.91 ', '1,023,947,055.09 ', '660,724,957.07 ', '483,662,652.50 ', '1,830,611,721.72 ', '1,572,332,757.99 '] ['14,982,965,023.78 ', '2,637,922,427.09', '184,935,603.34 ', '4,703,137,714.04 ', '696,747,830.31 ', '895,876,744.19 ', '456,643,081.69 ', '1,807,222,57', '1,044,126,473.90 '] ['世纪华通', '宝通科技', '欢瑞世纪', '游族网络', '电魂网络', '盛天网络', '迅游科技', '金科文化', '顺网科技'] ['14,689,715,6', '2,475,616,071.21', '540,047,298.34 ', '3,220,501,920.91 ', '1,023,947,055.09 ', '660,724,957.07 ', '483,662,652.50 ', '1,830,611,721.72 ', '1,572,332,757.99 '] ['14,982,965,023.78 ', '2,637,922,427.09', '184,935,603.34 ', '4,703,137,714.04 ', '696,747,830.31 ', '895,876,744.19 ', '456,643,081.69 ', '1,807,222,57', '1,044,126,473.90 ']
# 定义change_type的函数,将营业收入由字符串类型转变为浮点型,并保留两位小数
def change_type(list_x):
list_want=[]
for i in range(len(list_x)):
x_a = []
for j in range(len(list_x[1])):
a_a = list_x[i][j]
a_b = a_a.replace(",","")#将字符串中的,替换为空格
a_c = float(a_b)
a_d = a_c / 10**8#将数值缩小为亿分之一,便于在后续图标上展示
a_e = round(a_d,2)#保留两位小数
x_a.append(a_e)
list_want.append(x_a)
return(list_want)
list_row_1 = change_type(list_row)
list_columns_1 = change_type(list_columns)
for i in range(len(list_row_1)):
print(list_row_1[i])
for i in range(len(list_columns_1)):
print(list_columns_1[i])
[1.47, 24.76, 5.4, 32.21, 10.24, 6.61, 4.84, 18.31, 15.72] [149.83, 26.38, 1.85, 47.03, 6.97, 8.96, 4.57, 1.81, 10.44] [1.47, 149.83] [24.76, 26.38] [5.4, 1.85] [32.21, 47.03] [10.24, 6.97] [6.61, 8.96] [4.84, 4.57] [18.31, 1.81] [15.72, 10.44]
# 制图:
#纵向对比图由于同一个公司一年的营业收入有调整前后两个数值导致绘图较乱 暂未找到有效解决办法
#横向制图 用于制作不同公司同一年份(2019——2020)营业收入的对比即横向对比(条形图)
list_name_1 = []
for i in range(len(list_name)):#保留公司名称的前两个字
c_a = list_name[i]
c_b = c_a[0:2]
list_name_1.append(c_b)
def y_ticks(list_row,name_list):
num_list_1 = list_row
rects = plt.barh(range(len(list_row)),num_list_1,color='rgby')
N = 9
index = np.arange(N)
plt.yticks(index,list_name_1,fontproperties = zhfont1)
plt.title(name_list+"不同公司营业收入对比",fontproperties = zhfont1)
plt.xlabel("营业收入(亿元)",fontproperties = zhfont1)
plt.ylabel("公司名称",fontproperties = zhfont1)
for rect in rects:
w=rect.get_width()
plt.text(w,rect.get_y()+rect.get_height()/2,w,size =10,ha='left',va='center')
plt.savefig(name_list +".png",dpi = 600)
plt.show()
for i in range(len(list_row)):
y_ticks(list_row_1[i], name_list[i])