钟艳玲的实验报告

目录

1.下载年报点击查看报告

2.提取营业收入,基本每每股收益和公司信息点击查看报告

3.按公司绘图和按年度绘图点击查看报告

4.绘图结果分析点击跳转

5.实验心得点击跳转

注:实验报告使用jupyter notebook编写,代码运行结果及截图请点击目录123中的“点击查看报告”,(绘图部分报告可能要加载一段时间,请耐心等待)。在此页面放置总代码和绘图结果及分析,和实验心得。

代码 PART1

下载年报


  import pandas as pd
  import re
  from selenium import webdriver
  from selenium.webdriver.common.by import By
  from selenium.webdriver.common.keys import Keys
  from selenium.webdriver.common.action_chains import ActionChains
  import time
  import os
  import requests

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告")#更改工作目录
  df=pd.read_excel(r"Company.xlsx",converters={u"code":str})#导入要分析的公司
  Company_sz = df.iloc[:22,1] #需要研究的深圳证券交易所上市公司的名单
  Company_sh = df.iloc[22:,0] #需要I上海证券交易所上市的公司名单

  """下载所需公司的年报代码html格式"""

  def Inputtime(start,end):#定义输入开始和截至时间的函数
      START = browser.find_element(By.CLASS_NAME,"input-left")
      END = browser.find_element(By.CLASS_NAME,"input-right")
      START.send_keys(start)
      END.send_keys(end+Keys.RETURN)

  def Clear(): #定义清除所选内容的函数
      browser.find_element(By.CLASS_NAME,"btn-clearall").click()

  def Inputcode(name):#输入公司的名称
      In = browser.find_element(By.ID,"input_code")
      In.send_keys(name+Keys.RETURN)

  def Choose_an():#选择年度报告
      browser.find_element(By.LINK_TEXT,"请选择公告类别").click()
      browser.find_element(By.LINK_TEXT,"年度报告").click()

  def Save(filename,content):
      f = open(filename+'.html','w',encoding='utf-8')
      f.write(content)
      f.close()

  browser = webdriver.Firefox()

  browser.get("http://www.szse.cn/disclosure/listed/fixed/index.html")
  time.sleep(5)
  End = time.strftime('%Y-%m-%d', time.localtime())
  Inputtime('2012-10-01',End)
  for company in Company_sz.values: #保存深圳证券交易所上市公司年报html格式
      time.sleep(1)
      Choose_an()#选择年度报告
      Inputcode(company)#输入公司名称
      time.sleep(2)#延迟2秒执行
      html = browser.find_element(By.ID,"disclosure-table")
      time.sleep(5)
      innerHTML = html.get_attribute("innerHTML")
      Save(company,innerHTML)
      Clear()

  """解析深圳证券交易所html文件"""
  class DisclosureTable():
      '''
      解析深交所定期报告页搜索表格
      '''
      def __init__(self, innerHTML):
          self.html = innerHTML
          self.prefix = 'https://disc.szse.cn/download'
          self.prefix_href = 'https://www.szse.cn/'
          #
          p_a = re.compile('(.*?)', re.DOTALL)
          p_span = re.compile('(.*?)', re.DOTALL)
          self.get_code = lambda txt: p_a.search(txt).group(1).strip()
          self.get_time = lambda txt: p_span.search(txt).group(1).strip()
          #
          self.txt_to_df()

      def txt_to_df(self):
          # html table text to DataFrame
          html = self.html
          p = re.compile('(.*?)', re.DOTALL)
          trs = p.findall(html)

          p2 = re.compile('(.*?)', re.DOTALL)
          tds = [p2.findall(tr) for tr in trs[1:]]

          df = pd.DataFrame({'证券代码': [td[0] for td in tds],
                             '简称': [td[1] for td in tds],
                             '公告标题': [td[2] for td in tds],
                             '公告时间': [td[3] for td in tds]})
          self.df_txt = df

      def get_link(self, txt):
          p_txt = '(.*?)'
          p = re.compile(p_txt, re.DOTALL)
          matchObj = p.search(txt)
          attachpath = matchObj.group(1).strip()
          href       = matchObj.group(2).strip()
          title      = matchObj.group(3).strip()
          return([attachpath, href, title])

      def get_data(self):
          get_code = self.get_code
          get_time = self.get_time
          get_link = self.get_link
          #
          df = self.df_txt
          codes = [get_code(td) for td in df['证券代码']]
          short_names = [get_code(td) for td in df['简称']]
          ahts = [get_link(td) for td in df['公告标题']]
          times = [get_time(td) for td in df['公告时间']]
          #
          prefix = self.prefix
          prefix_href = self.prefix
          df = pd.DataFrame({'证券代码': codes,
                             '简称': short_names,
                             '公告标题': [aht[2] for aht in ahts],
                             'attachpath': [prefix + aht[0] for aht in ahts],
                             'href': [prefix_href + aht[1] for aht in ahts],
                             '公告时间': times
              })
          self.df_data = df
          return(df)

  def Readhtml(filename):
      f = open(filename+'.html', encoding='utf-8')
      html = f.read()
      f.close()
      return html

  def Clean(df):#清除“摘要”型、“(已取消)”型文件
      d = []
      for index, row in df.iterrows():
          ggbt = row[2]
          a = re.search("摘要|取消", ggbt)
          if a != None:
              d.append(index)
      df1 = df.drop(d).reset_index(drop = True)
      return df1
  def Loadpdf(df):#用于下载文件
      d1 = {}
      for index, row in df.iterrows():
          d1[row[2]] = row[3]
      for key, value in d1.items():
          f = requests.get(value)
          fo = open (key+".pdf", "wb")
          fo.write(f.content)

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\html\html_sz")
  for company in Company_sz.values: #下载深圳证券交易所的年报
      html = Readhtml(company)
      dt = DisclosureTable(html)
      dt1 = dt.get_data()
      df = Clean(dt1)
      df.to_csv("../../df/"+company+".csv",encoding="utf-8-sig")#将csv文件保存到df目录下
      os.makedirs("../../nb_sz/"+company,exist_ok=True)#将年报保存到该文件夹
      os.chdir("../../nb_sz/"+company)
      Loadpdf(df)
      os.chdir("../../html/html_sz")#回到保存html的文件夹
      print(company,"公司年报已保存完毕")

  #####深圳公司年报下载完毕,开始下载上海证券交易所年报

  def Time_start():#定义一个公式选择2013-01-01到2016-01-01的日期
      web.find_element(By.XPATH,"/html/body/div[8]/div/div[1]/div/div[5]/div[2]/input").click()

      web.find_element(By.CSS_SELECTOR, ".input_focus > .form-control").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 .laydate-prev-y").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(14)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 tr:nth-child(1) > td:nth-child(3)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 span:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 tr:nth-child(1) > td:nth-child(6)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-btns-confirm").click()


  def time_median():#定义一个公式选择2016-01-01到2019-01-01的日期
      web.find_element(By.XPATH,"/html/body/div[8]/div/div[1]/div/div[5]/div[2]/input").click()
      web.find_element(By.CSS_SELECTOR, ".input_focus > .form-control").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 tr:nth-child(1) > td:nth-child(6)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 span:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(5)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 tr:nth-child(1) > td:nth-child(3)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-btns-confirm").click()

  def time_m2():  #时间设置为2019-1-1至2022-1-1日
      web.find_element(By.XPATH,"/html/body/div[8]/div/div[1]/div/div[5]/div[2]/input").click()
      web.find_element(By.CSS_SELECTOR, ".input_focus > .form-control").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(5)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 tr:nth-child(1) > td:nth-child(3)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-1 tr:nth-child(1) > td:nth-child(7)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-btns-confirm").click()

  def time_end():  #爬取2022-1-1至今年报
      web.find_element(By.XPATH,"/html/body/div[8]/div/div[1]/div/div[5]/div[2]/input").click()
      web.find_element(By.CSS_SELECTOR, ".input_focus > .form-control").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 span:nth-child(2)").click()
      web.find_element(By.CSS_SELECTOR, ".layui-laydate-list > li:nth-child(1)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-main-list-0 tr:nth-child(1) > td:nth-child(7)").click()
      web.find_element(By.CSS_SELECTOR, ".laydate-btns-confirm").click()


  def Inputname(name):
      In = web.find_element(By.ID, "inputCode").send_keys(name)
      en = web.find_element(By.ID,"inputCode").send_keys(Keys.ENTER)

  def Choose():#选择年度报告
      web.find_element(By.CSS_SELECTOR, ".sse_outerItem:nth-child(4) .filter-option-inner-inner").click()
      web.find_element(By.LINK_TEXT, "年报").click()

  def Saveadd(filename,content):
      f = open(filename+'.html','a',encoding='utf-8')
      f.write(content)
      f.close()

  def Clearall():#2013-1-1至2019-1-1清除所有内容的xpath路径
      web.find_element(By.XPATH, ".bi-chevron-double-down").click()
      web.find_element(By.XPATH, "/html/body/div[8]/div/div[1]/div/div[1]/ul/li[5]/a/span").click()

  def Clearall2():#2019-1-1自以后的清除所有内容的xpath路径
      web.find_element(By.XPATH, "/html/body/div[8]/div/div[1]/div/div[1]/span/i").click()
      web.find_element(By.XPATH, "/html/body/div[8]/div/div[1]/div/div[1]/ul/li[5]/a/span").click()


  web = webdriver.Firefox()
  time.sleep(4)
  url = "http://www.sse.com.cn/disclosure/listedinfo/regular/"
  web.get(url)

  p = re.compile("暂无数据")
  for code in Company_sh.values:   #下载2013-1-1至2016-1-1数据
      Inputname(code)
      time.sleep(1)
      Choose()
      time.sleep(3)
      Time_start()
      time.sleep(4)
      html = web.find_element(By.XPATH,"/html/body/div[8]/div/div[2]/div/div[1]/div[1]")
      innerHTML = html.get_attribute("innerHTML")
      kong = p.findall(innerHTML)
      if kong ==[]:
          Saveadd(code,innerHTML)
      Clearall() #重新进入,清除所有数据

  for code in Company_sh.values:    #下载2016-1-1至2019-1-1数据
      Inputname(code)
      time.sleep(1)
      Choose()
      time.sleep(3)
      time_median()
      time.sleep(4)
      html = web.find_element(By.XPATH,"/html/body/div[8]/div/div[2]/div/div[1]/div[1]")
      innerHTML = html.get_attribute("innerHTML")
      kong = p.findall(innerHTML)
      if kong ==[]:
          Saveadd(code,innerHTML)
      Clearall()

  for code in Company_sh.values:    #下载2019-1-1至2022-1-1数据
      Inputname(code)
      time.sleep(1)
      Choose()
      time.sleep(3)
      time_m2()
      time.sleep(4)
      html = web.find_element(By.XPATH,"/html/body/div[8]/div/div[2]/div/div[1]/div[1]")
      innerHTML = html.get_attribute("innerHTML")
      kong = p.findall(innerHTML)
      if kong ==[]:
          Saveadd(code,innerHTML)
      Clearall2()

  for code in Company_sh.values:    #下载2022-1-1至今数据
      Inputname(code)
      time.sleep(1)
      Choose()
      time.sleep(3)
      time_end()
      time.sleep(4)
      html = web.find_element(By.XPATH,"/html/body/div[8]/div/div[2]/div/div[1]/div[1]")
      innerHTML = html.get_attribute("innerHTML")
      kong = p.findall(innerHTML)
      if kong ==[]:
          Saveadd(code,innerHTML)
      Clearall2()

  def Clearblank(lst): #清除空列表
      chart=[]
      for ls in lst:
          if ls !=[]:
              chart.append(ls)
      return chart

  class Prase_sh():
      '''
      解析上交所定期报告页搜索表格
      '''
      def __init__(self, innerHTML):
          self.html= innerHTML
          self.prefix_href = 'http://static.sse.com.cn/'
          # p_a = re.compile('(.*?)', re.DOTALL)
          p_span = re.compile('(.*?)', re.DOTALL)
          self.gain_cn = lambda txt: p_span.search(txt).group(1)
          # 定义一个函数获得证券的代码和简称
          self.gain_df()

      def gain_df(self):
          html = self.html
          p=re.compile("(.*?)")
          p1=re.compile("(.*?)")
          trs =p.findall(html)
          tds = [p1.findall(tr) for tr in trs]
          tds = Clearblank(tds)
          df = pd.DataFrame({'证券代码': [td[0] for td in tds],
                         '简称': [td[1] for td in tds],
                         '公告标题': [td[2] for td in tds],
                         '公告时间': [td[3] for td in tds]})
          self.df_txt = df

      # tds = gain_df(txt)

      def gain_link(self,txt):
          p_a = re.compile('(.*?)')
          matchObj = p_a.search(txt)
          href= matchObj.group(1).strip()
          title = matchObj.group(2).strip()
          return([href, title])

      def gain_data(self):
          gain_link = self.gain_link
          gain_cn = self.gain_cn

          df = self.df_txt

          codes = [gain_cn(dt) for dt in df["证券代码"]]
          short_names = [gain_cn(dt) for dt in df["简称"]]
          ahts =[gain_link(dt) for dt in df["公告标题"]]
          times = [time for time in df["公告时间"]]
          prefix_href = self.prefix_href

          df = pd.DataFrame({"证券代码":codes,
                             "公司简称":short_names,
                             "公告标题":[aht[1] for aht in ahts],
                             "href":[prefix_href+aht[0]for aht in ahts],
                             "公告时间":times})
          self.df_data = df
          return df

  """由于上海证券交易所的年度报告命名年与年之间差别大,因此自己定义新的命名格式"""
  def Short_Name(df):#获得上海证券交易所公司的简称
      for i in df["公司简称"]:
          i=i.replace("*","")
          if i !="-":
              sn=i
      return sn

  def Loadpdf_sh(df):#用于下载文件
      d1 = {}
      df["公告时间"] = pd.to_datetime(df["公告时间"])
      name = Short_Name(df)
      for index, row in df.iterrows():
          na = name+str(row[4].year-1)+"年年度报告"
          d1[na] = row[3]
      for key, value in d1.items():
          f = requests.get(value)
          fo = open (key+".pdf", "wb")
          fo.write(f.content)

  def filter_links(words,df,include=True):
      ls=[]
      for word in words:
          if include:
              ls.append([word in f for f in df["公告标题"]])
          else:
              ls.append([word not in f for f in df["公告标题"]])
      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)
      df= df[index]
      return(df)

  def new_df(df_orig,df_updt):#保留修订年报,删除同年的其他年报
      kk=[]
      df_orig = df_orig.reset_index()
      df_updt = df_updt.reset_index()
      df_orig =df_orig.iloc[:,1:]
      df_updt = df_updt.iloc[:,1:]
      for date in df_updt["公告时间"]:
          year1 = date[:4]
          for  index,row in df_orig.iterrows():
              year2 = row[4][:4]
              if year2 == year1:
                  kk.append(index)
      df_orig = df_orig.drop(kk)
      df = pd.concat([df_orig,df_updt],axis=0)
      df=df.reset_index()
      df = df.iloc[:,1:]
      return df

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\html\html_sh")
  for company in Company_sh.values:#下载上海证券交易所年报的循环
      txt =Readhtml(company)
      mm = Prase_sh(txt)
      data=mm.gain_data()
      df_all = filter_links(["摘要","社会责任","审计","财务","风险","债券","图文","董事","意见","监事"],data,include= False)
      df_orig = filter_links(["(","("],df_all,include = False)

      df_updt = filter_links(["(","("],df_all,include = True)
      df1 = new_df(df_orig,df_updt)#保留修订年报,删除同年的其他年报
      name = Short_Name(df1)
      df1.to_csv("../../df/df_sh/"+name+".csv",encoding="utf-8-sig")#保存df文件
      os.makedirs("../../nb_sh/"+name,exist_ok=True)#创建保存年报的文件夹
      os.chdir("../../nb_sh/"+name)#更改当前的工作目录
      Loadpdf_sh(df1)#下载年报
      os.chdir("../../html/html_sh")#回到保存了html文件的文件夹
      print(company,"公司年报已保存完毕")

代码PART2

提取营业收入,基本每股收益和公司信息


  import pandas as pd
  import fitz
  import re
  import os

  def Short_Name(df):#获得上海证券交易所公司的简称
      for i in df["公司简称"]:
          i=i.replace("*","")
          if i !="-":
              sn=i
      return sn
  # # 提取深圳证券交易所上市公司的"营业收入","基本每股收益","公司网址","公司地址"
  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告")
  Company=pd.read_excel('Company.xlsx').iloc[:,1:] #读取保存的公司名文件
  company=Company.iloc[:,0].tolist()#转为列表

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\df\df_sz")#更改路径到储存年报的df文件夹下
  t=0
  for com in company[:22]:#前22个公司的年报发布在深圳证券交易所
      t+=1
      com = com.replace('*','')
      df = pd.read_csv(com+'.csv',converters={'证券代码':str})  #读取存有公告名称的csv文件用来循环访问pdf年报
      df = df.sort_index(ascending=False)
      final = pd.DataFrame(index=range(2012,2022),columns=['营业收入(元)','基本每股收益(元/股)']) #创建一个空的dataframe用于后面保存数据
      final.index.name='年份'
      code = str(df.iloc[0,1])
      name = df.iloc[-1,2].replace(' ','')

      for i in range(len(df)): #循环访问每年的年报
          title=df.iloc[i,3]
          doc = fitz.open('../../nb_sz/%s/%s.pdf'%(com,title))#打开储存在nb_sz文件夹的年报
          text=''
          for j in range(15): #需要提取的指标在前15页之前的页码,因此读取每份年报前15页的数据
              page = doc[j]
              text += page.get_text()
          p_year=re.compile('.*?(\d{4}) .*?年度报告.*?') #捕获目前在匹配的年报年份
          year = int(p_year.findall(text)[0])
              #设置需要匹配的四种数据的pattern
          text=text.replace(".\n",".")
          p_rev = re.compile(r'(?<=\n)营业总?收入\(?(?\w?)?\)?[\x7f]?\s?\n?([\d+,.]*)\s?\n?')
          p_eps = re.compile('(?<=\n)基本每股收益\s*(元/?/?\n?股)[\x7f]?\s?\n?([-\d+,.]*)\s?\n?')
          p_site = re.compile('(?<=\n)\w*办公地址:?\s?\n?(.*?)\s?(?=\n)',re.DOTALL)
          p_web =re.compile('(?<=\n)公司\w*网址:?\s?\n?([a-zA-Z./\-:]*)\s?(?=\n)',re.DOTALL)
          text=text.replace(".\n",".")#替换掉里面的换行符
          revenue=float(p_rev.search(text).group(1).replace(',',''))  #将匹配到的营业收入的千分位去掉并转为浮点数
          eps=p_eps.search(text).group(1)
          final.loc[year,'营业收入(元)']=revenue  #把营业收入和每股收益写进最开始创建的dataframe
          final.loc[year,'基本每股收益(元/股)']=eps
          final.to_csv('../../营业收入/sz/%s.csv' %com,encoding='utf-8-sig')  #将各公司数据存储到本地文件
      site=p_site.search(text).group(1) #匹配办公地址和网网址,取最近一年的
      web=p_web.search(text).group(1)
      f = open('../../营业收入/sz/【%s】.csv'%com,'a',encoding='utf-8-sig') #把股票简称,代码,办公地址和网址写入文件末尾
      content='股票简称,%s\n股票代码,%s\n办公地址,%s\n公司网址,%s'%(name,code,site,web)
      f.write(content)
      f.close()
      print(name+'数据已保存完毕'+'(',t,'/',len(company[:22]),')')

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告")
  Company=pd.read_excel('Company.xlsx').iloc[:,1:] #读取上一步保存的公司名文件
  company=Company.iloc[:,0].tolist()#转为列表

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\df\df_sh")
  t=0
  for com in company[22:]:
      t+=1
      com = com.replace('*','')
      df = pd.read_csv(com+'.csv',converters={'证券代码':str})  #读取存有公告名称的csv文件用来循环访问pdf年报
      df = df.sort_index(ascending=False)
      final = pd.DataFrame(index=range(2012,2022),columns=['营业收入(元)','基本每股收益(元/股)']) #创建一个空的dataframe用于后面保存数据
      final.index.name='年份'
      code = str(df.iloc[0,1])
      name = Short_Name(df).replace(' ','')

      for i in range(len(df)): #循环访问每年的年报
          title=name+str(2021-i)+"年年度报告"
          doc = fitz.open('../../nb_sh/%s/%s.pdf'%(com,title))
          text=''
          for j in range(15): #读取每份年报前15页的数据
              page = doc[j]
              text += page.get_text()
          p_year=re.compile('.*?\n?(20\d{2})\s?.*?\n?年\n?度\n?报\n?告\n?.*?') #捕获目前在匹配的年报年份
          year = int(p_year.findall(text)[0])
              #设置需要匹配的四种数据的pattern

          p_rev = re.compile(r'(?<=\n)营业总?收入\s?\(?(?\w?)?\)?[\x7f]?\s?\n+([\d+,.]*)\s?\n?')
          p_eps = re.compile('(?<=\n)基本每股收益(元/?\s?╱?\s?/?\n?股)[\x7f]?\s?\n?([-\d+,.]*)\s?\n?')
          p_site = re.compile('(?<=\n)\w*办公地址:?\s?\n?(.*?)\s?(?=\n)',re.DOTALL)
          p_web =re.compile('(?<=\n)公司\w*网址\s?:?\s?\n?([a-zA-Z./\-:]*)\s?(?=\n)',re.DOTALL)
          revenue=float(p_rev.search(text).group(1).replace(',',''))  #将匹配到的营业收入的千分位去掉并转为浮点数
          eps=p_eps.search(text).group(1)
          final.loc[year,'营业收入(元)']=revenue  #把营业收入和每股收益写进最开始创建的dataframe
          final.loc[year,'基本每股收益(元/股)']=eps
          final.to_csv('../../营业收入/sh/%s.csv' %com,encoding='utf-8-sig')  #将各公司数据存储到本地测csv文件
      site=p_site.search(text).group(1) #匹配办公地址和网址,取最近一年。
      web=p_web.search(text).group(1)
      f = open('../../营业收入/sh/【%s】.csv'%com,'a',encoding='utf-8-sig') #把股票简称,代码,办公地址和网址写入文件
      content='股票简称,%s\n股票代码,%s\n办公地址,%s\n公司网址,%s'%(name,code,site,web)
      f.write(content)
      f.close()
      print(name+'数据已保存完毕'+'(',t,'/',len(company[22:]),')')
  

代码 PART3

按公司绘图和按年度绘图


  import pandas as pd
  import os
  import matplotlib.pyplot as plt
  import matplotlib.font_manager as fm
  plt.rcParams['font.sans-serif']=['SimHei']  #确保显示中文
  plt.rcParams['axes.unicode_minus'] = False  #确保显示负数的参数设置

  """#获得深圳证券交易所上市公司的营业总收入"""

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\营业收入\sz")
  filenames = os.listdir()
  df_income = pd.DataFrame(index=["总营业收入"])#统计所有上市公司的总营业收入
  lst = []#统计营业收入数据有10年的公司
  for na_me in filenames:
      df = pd.read_csv(na_me,index_col=0,sep=",")
      df = df.dropna(axis=0)
      lenth = len(df)
      if lenth == 10:
          print(na_me,"的营业收入数据有10组")
          lst.append(na_me[:-4])#注意lst =lst.append()返回的是None
          s =0
          for i in df["营业收入(元)"]:
              s+=int(i)
          df_income[na_me[:-4]]=s
  df_income_sz = df_income.T    #dataFrame的转置

  """#获得上海证券交易所上市公司的营业总收入"""

  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\营业收入\sh")
  filenames = os.listdir()
  df_income = pd.DataFrame(index=["总营业收入"])#统计所有上市公司的总营业收入
  lst = []#统计营业收入数据有10年的公司
  for na_me in filenames:
      df = pd.read_table(na_me,index_col=0,sep=",")
      df = df.dropna(axis=0)
      lenth = len(df)
      if lenth == 10:
          print(na_me,"的营业收入数据有10组")
          lst.append(na_me[:-4])#注意lst =lst.append()返回的是None
          s =0
          for i in df["营业收入(元)"]:
              s+=int(i)
              df_income[na_me[:-4]]=s
  df_income_sh = df_income.T

  """#合并上海证券交易所上市公司和深圳证券交易所上市公司的数据"""
  df_total = pd.concat([df_income_sh,df_income_sz],axis=0)
  """#排序提取营业收入前十的公司"""
  df_total = df_total.sort_values(by="总营业收入",axis=0,ascending =False)#排序完成
  df_total = df_total.iloc[:10,] #对这10家公司的营业收入和每股收益进行绘图

  #设置字体
  fname = "C:\Windows\Fonts\simkai.TTF"#楷体字体
  plt.rcParams['figure.dpi']=600 #调整像素
  zhfont1 = fm.FontProperties(fname=fname)

  #对每一家公司分别画营业收入和基本每股收益的子图
  os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\营业收入\绘图\公司分析")
  filenames = os.listdir()
  for na_me in filenames:
      df = pd.read_table(na_me,index_col=0,sep=",")
      plt.figure(figsize=(12,10))
      plt.subplot(211)
      plt.title(na_me[:-4], fontproperties=zhfont1,fontsize=15)
      plt.plot(df["营业收入(元)"],"ob-",label=na_me[:-4]+u"营业收入图",lw=1.5)
      plt.xticks(fontsize=13)
      plt.xlabel(u'日期',fontproperties=zhfont1,fontsize=13)
      plt.yticks(fontsize=13)
      plt.ylabel(u"元",fontproperties=zhfont1,fontsize=13)
      plt.legend(loc="best",fontsize=13)

      plt.subplot(212)
      plt.plot(df["基本每股收益(元/股)"],'or-',label=na_me[:-4]+u"每股收益图",lw=1.5)
      plt.xticks(fontsize=13)
      plt.xlabel(u"日期",fontproperties=zhfont1,fontsize=13)
      plt.yticks(fontsize=13)
      plt.ylabel(u"元",fontproperties=zhfont1,fontsize=13)
      plt.legend(loc="best",fontsize=13)


  # 时间变化趋势图
  ##按每一年度,对行业内公司的营业收入,基本每股收益绘制对比图
  #首先先处理数据,将10个公司的数据按年份整合
  filenames = os.listdir()
  for i in range(10):
      lst=[] #用来生成列名
      globals()["df_"+str(i+2012)] = pd.DataFrame()
      for na_me in filenames:
          lst.append(na_me[:-4])
          df = pd.read_table(na_me,index_col=0,sep=",")
          df1=df.iloc[i,]
          globals()["df_"+str(i+2012)] = globals()["df_"+str(i+2012)].append(df1,ignore_index=True)
      globals()["df_"+str(i+2012)]= globals()["df_"+str(i+2012)].T
      globals()["df_"+str(i+2012)].columns=lst
      globals()["df_"+str(i+2012)]= globals()["df_"+str(i+2012)].T
      globals()["df_"+str(i+2012)].to_csv( r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\营业收入\绘图\年份分析\df_"+str(i+2012)+".csv",encoding="utf-8-sig")


  #将df2012-df2021文件保存到了年份分析文件夹,便于后面循环画图

os.chdir(r"C:\Users\冰雪飘\Documents\python files\pachong\爬取年报_实验报告\营业收入\绘图\年份分析")
filenames = os.listdir()
df_income=pd.DataFrame()
df_eps = pd.DataFrame()
for na_me in filenames:#将dataframe合并
    df = pd.read_table(na_me,index_col=0,sep=",")
    df_income = pd.concat([df_income,df.iloc[:,1]],axis=1)
    df_eps = pd.concat([df_eps,df.iloc[:,0]],axis=1)
df_income.columns=range(2012,2022)
df_eps.columns=range(2012,2022)

df_income_1=df_income.T.head(5)
df_income_2=df_income.T.tail(5)

ax1=df_income_1.plot(kind="bar",figsize=(18,12),fontsize=18,alpha=0.7,grid=False)
ax1.legend(loc='best',prop={'family':'simsun', 'size': 14},framealpha=0.5)
ax1.set_xlabel('年份',loc='left', fontproperties=zhfont1,fontsize=18)
ax1.set_ylabel('营业收入(元)', fontproperties=zhfont1,fontsize=18)
ax1.set_title('行业内横向对比营业收入(2012-2016)', fontproperties=zhfont1,fontsize=20)

ax2=df_income_2.plot(kind="bar",figsize=(18,12),fontsize=18,alpha=0.7,grid=False)
ax2.legend(loc='best',prop={'family':'simsun', 'size': 14},framealpha=0.5)
ax2.set_xlabel('年份',loc='left', fontproperties=zhfont1,fontsize=18)
ax2.set_ylabel('营业收入(元)', fontproperties=zhfont1,fontsize=18)
ax2.set_title('行业内横向对比营业收入(2017-2021)', fontproperties=zhfont1,fontsize=20)

df_eps_1=df_eps.T.head(5)
df_eps_2=df_eps.T.tail(5)

ax1=df_eps_1.plot(kind="bar",figsize=(18,12),fontsize=18,alpha=0.7,grid=False)
ax1.legend(loc='best',prop={'family':'simsun', 'size': 14},framealpha=0.5)
ax1.set_xlabel('年份',loc='left', fontproperties=zhfont1,fontsize=18)
ax1.set_ylabel('基本每股收益(元/股)', fontproperties=zhfont1,fontsize=18)
ax1.set_title('行业内横向对比基本每股收益(2012-2016)', fontproperties=zhfont1,fontsize=20)


ax2=df_eps_2.plot(kind="bar",figsize=(18,12),fontsize=18,alpha=0.7,grid=False)
ax2.legend(loc='best',prop={'family':'simsun', 'size': 14},framealpha=0.5)
ax2.set_xlabel('年份',loc='left', fontproperties=zhfont1,fontsize=18)
ax2.set_ylabel('基本每股收益(元/股)', fontproperties=zhfont1,fontsize=18)
ax2.set_title('行业内横向对比基本每股收益(2017-2021)', fontproperties=zhfont1,fontsize=20)


绘图结果 PART 1

各公司纵向对比图

结果截图 结果截图 结果截图 结果截图 结果截图 结果截图 结果截图 结果截图 结果截图 结果截图

绘图结果 PART 2

各年度横向对比图

营业收入
结果截图 结果截图
基本每股收益
结果截图 结果截图

绘图结果分析

公司分析(总营业收入前四)

阮华集团作为纺织服装服饰业的龙头企业,近10年来的总营业收入位居第一位,尤其是2018年之前,营业收入都在22亿元以上,在2016年营业收入达到顶峰。 阮华集团营业收入在2018年之后开始走弱,原因是政府补助减少,其中主要是一次性的投资创新奖励及搬迁补偿款减少。 在2016年之前,阮华集团的基本每股收益持续上涨,在2016年之后基本每股收益不断下跌,2019年基本每股收益跌破0,变成负数,直到2020开始,基本每股收益才开始上涨 但仍然还是保持在负值的水平,可能有望在2022年突破负值

海澜之家作为纺织服装服饰业的黑马企业,近10年来的总营业收入位居第二位,公司的营业收入从2012年-2019年逐年成上涨趋势,到2019年营业收入达到一个顶点,后有所回落 但整体保持在18亿元以上,企业发展势头强劲。海澜之间的基本每股收益与营业收入的走势大致相符,在2018年之前成上涨趋势,2019年有所回落,2020年随营业收入的下降也下跌 到一个低点,2021年的基本每股收益上涨了,总体还是保持在0.4元/股的水平上,是一个比较好的投资企业

作为近10年总营业收入第三的雅戈尔企业,发展就没有那么有规律,公司的营业收入在2012年,2017年,2018年在一个相对低的水平上,其他年份上公司的营业收入都处于一个较高的水平上。 雅戈尔基本每股收益在这10年间的波动也比较大,在2015年达到一个高峰,2017年处于低谷,但总体来看,基本每股收益都是正值,且正常来说企业的每股收益都在0.5元/股以上。

森马集团是近10年来营业收入排名第四的企业,近10年的发展非常的迅速,在2019年之前,公司的营业收入逐年上涨,在2019年达到最高点,之后的营业收入也一直保持在较高的水平上。 森马集团的基本每股收益在2015你啊之前一直保持在1.0元/股之上,在2015你之后,基本每股收益波动幅度缩小,整体在0.4元/股以上

年份分析

从图中我们可以看到,阮华集团的营业收入一直都在纺织服装服饰业处于不可忽视的地位,2018年之前的营业收入一直是第一,远超其他企业,2018年之后,海澜之家和森马服饰发展迅速,超过了 阮华集团的营业收入,逐渐成为行业内的翘楚。

雅戈尔的营业收入也在纺织业服装服饰业中处于中上的地位,近10年的波动幅度不会很大。

另外6家公司在这10年内的发展较为平稳。

回到目录

实验心得

通过做这次实验报告,加深了我对服装行业的理解和认识,但最重要的是见识到python的巨大作用。以前对python的理解和认知都还停留在理论的阶段,知道某个对象 可能有这样的方法,但是为什么要有这样的方法,这样的方法用来干什么,并不了解。通过做这次的实验报告,调用了大量的模块,编写代码,加深了对各种对象功能和方法的理解。

通过做这次实验报告,感悟到python基础和记忆力实在是非常重要。在这次实验过程中,我的进度非常的慢,花了大量的时间,但是很难得到正确的结果。我觉得一个重要的原因就是基础 不扎实,比如说pandas模块的dataframe有哪些方法和功能,dataframe的建立和设置等等,总是一些基础的东西要调试好几遍,才能得到正确的结果。这就导致我的效率非常的低。在未来的学习中,我要更加注意这方面,打好基础。

最后是感谢於心怡同学,通过学习她的实验报告中提取营业收入部分的代码,修改正则表达式,就可以完美的匹配我所要解析的公司年报,得到想要的结果。 还要感谢吴老师对我在实验过程中的指导,每次问老师问题都可以得到很好的反馈。

回到目录