当前位置:   article > 正文

金融数据挖掘(一):A股上市公司2022年年报_a股数据挖掘

a股数据挖掘

A股上市公司年报,是我们分析上市公司财务状况和经营状况,并进行股票估值和行情预测的重要依据。那么,我们应该如何爬取这些上市公司的财报数据,并用于数据分析和可视化呢?今天我们以东方财富网为例,来介绍一下基本的步骤。

一、操作环境

1. 浏览器:Safari浏览器(版本:17.31)

2. Python版本:Python3.12

3. 开发环境:Pycharm 2023.3(Community Edition)

4. 操作系统:MacOS 14.3(Sonoma)

二、网页解析

1. 点击如下网址,进入数据页面

2022年年报业绩大全 _ 数据中心 _ 东方财富网

2. 页面空白处“点击右键”——“检查元素”,进入开发者工具。

    选择”网络“标签页,然后刷新网页,获取所有网页加载项。

 3. 对列表中的所有加载项依次进行预览,寻找数据源地址。

     以本次操作为例,数据源的网址为(数据源网址是动态生成的):

https://datacenter-web.eastmoney.com/api/data/v1/get?callback=jQuery112307880322881038256_1709033016691&sortColumns=UPDATE_DATE%2CSECURITY_CODE&sortTypes=-1%2C-1&pageSize=50&pageNumber=1&reportName=RPT_LICO_FN_CPD&columns=ALL&filter=(REPORTDATE%3D%272022-12-31%27)

4. 分析数据源网址,找出真正的数据源接口

   一般网址的基本结构为:

协议://域名(IP:端口)/资源路径?查询条件(结构:key1=value1&key2=value2)

   据此分析上面的数据源网址,可以发现,真正的数据接口,其实是:

   https://datacenter-web.eastmoney.com/api/data/v1/get

  但是,要想获取到指定数据,“查询条件”部分也是必不可少的。这个我们后面再讲。

5. 分析数据源网址的代码结构,确定爬取方案

   通过“预览”,我们可以发现,数据源网址对应的,其实是一个JSON格式的数据。但这并不是标准的JSON格式数据,还多了一个“jQuery112307880322881038256_1709033016691()”。这个多出来的部分是回调函数,对应数据源网址中的"callback"部分,我们可直接在网址中删除。

 三、编写代码

1. 导入工具包

  1. # coding:utf-8
  2. import requests
  3. import pandas as pd
  4. import json

2. 创建DataFrame表格。注意:变量名要与数据对应

list=pd.DataFrame(columns=['股票代码','股票名称','所在行业','股市类型','交易市场','每股收益','每股净收益','营业总收入','营业收入同比增长','净利润','净利润同比增长','每股净资产','净资产收益率','每股经营现金流量','销售毛利率','利润分配','股息率'])

3. 建立循环,以爬取所有页面的数据。循环范围根据数据的页面数量决定。

4. 使用requests爬取数据

(1)确定爬取数据的url网址,如下:

url='https://datacenter-web.eastmoney.com/api/data/v1/get?sortColumns=UPDATE_DATE%2CSECURITY_CODE&sortTypes=-1%2C-1&pageSize=50&pageNumber='+str(i)+'&reportName=RPT_LICO_FN_CPD&columns=ALL&filter=(REPORTDATE%3D%272022-12-31%27)'

其中”?"之后的”查询条件“部分,分别设为:

sortColumns=UPDATE_DATE%2CSECURITY_CODE    #排序变量#

sortTypes=-1%2C-1    #排序格式#

pageSize=50            #每页的数据量,此处默认为50#  

pageNumber=str(i)    # "i"对应循环数,循环爬取各页数据#

reportName=RPT_LICO_FN_CPD     #报告名#

columns=ALL      #查询所有变量#

filter=(REPORTDATE%3D%272021-12-31%27)     #筛选报告时间,此处默认2022-12-31#

(2)创建表头headers,如下:

  1. header={'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Safari/605.1.15',
  2. 'Cookie': 'st_asi=delete; st_inirUrl=https%3A%2F%2Fbaidu.com%2F; st_psi=20240227192236777-113300301066-4864084221; st_pvi=11934193275781; st_sn=13; st_sp=2024-02-26%2015%3A19%3A30; JSESSIONID=37A0895F7D4E1F2005EF79C5B041FC90; st_si=63431626210633; HAList=ty-1-000001-%u4E0A%u8BC1%u6307%u6570; qgqp_b_id=b06ad5d3eaab94f81f12355ecebb1842'}

cookie可以随意复制一个,不影响最终结果。

(3)爬取网页

  1. money=requests.get(url=url,headers=header)
  2. money.encoding='utf8'

5. 解析爬取的JSON数据

  1. data=json.loads(money.text)
  2. chart=data["result"]['data']

6. 将爬取到的数据依次写入DataFrame表格中

  1. k=0
  2. for j in range(50):
  3. try:
  4. chartj=chart[j]
  5. print(chartj)
  6. code=chartj['SECURITY_CODE']
  7. abbr=chartj['SECURITY_NAME_ABBR']
  8. market=chartj['TRADE_MARKET']
  9. type=chartj['SECURITY_TYPE']
  10. eps=chartj['BASIC_EPS']
  11. epsde=chartj['DEDUCT_BASIC_EPS']
  12. income=chartj['TOTAL_OPERATE_INCOME']
  13. try:
  14. incomegrtht=float(chartj['YSTZ'])/100
  15. except:
  16. incomegrtht = chartj['YSTZ']
  17. profit=chartj['PARENT_NETPROFIT']
  18. try:
  19. profitgrtht=float(chartj['SJLTZ'])/100
  20. except:
  21. profitgrtht = chartj['SJLTZ']
  22. bps=chartj['BPS']
  23. try:
  24. roe=float(chartj['WEIGHTAVG_ROE'])/100
  25. except:
  26. roe=chartj['WEIGHTAVG_ROE']
  27. mgjy=chartj['MGJYXJJE']
  28. try:
  29. xsml=float(chartj['XSMLL'])/100
  30. except:
  31. xsml=chartj['XSMLL']
  32. lrfp=chartj['ASSIGNDSCRPT']
  33. hy=chartj['PUBLISHNAME']
  34. try:
  35. gxl=float(chartj['ZXGXL'])/100
  36. except:
  37. gxl=chartj['ZXGXL']
  38. list.loc[k]=[code,abbr,hy,type,market,eps,epsde,income,incomegrtht,profit,profitgrtht,bps,roe,mgjy,xsml,lrfp,gxl]
  39. k=k+1
  40. except:
  41. continue

其中,k=0需要在整个爬虫代码最前端进行声明。

同时,导入变量数据时,要与开头设定的DataFrame表格的变量顺序一致。

7. 把DataFrame表格保存为excel文件

list.to_excel('list.xlsx',index=False)

四、运行代码

运行代码后,在项目所在目录中会生成表格“list.xlsx”。

代码运行时,一般可见如下警告。它并不会影响最终结果,因此可以不予理会:

FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.

 打开该文件,可以看到爬取的数据如下:

最后,附上完整代码

  1. # coding:utf-8
  2. import requests
  3. import pandas as pd
  4. import json
  5. k=0
  6. list=pd.DataFrame(columns=['股票代码','股票名称','所在行业','股市类型','交易市场','每股收益','每股净收益','营业总收入','营业收入同比增长','净利润','净利润同比增长','每股净资产','净资产收益率','每股经营现金流量','销售毛利率','利润分配','股息率'])
  7. for i in range(1,237):
  8. url='https://datacenter-web.eastmoney.com/api/data/v1/get?sortColumns=UPDATE_DATE%2CSECURITY_CODE&sortTypes=-1%2C-1&pageSize=50&pageNumber='+str(i)+'&reportName=RPT_LICO_FN_CPD&columns=ALL&filter=(REPORTDATE%3D%272022-12-31%27)'
  9. header={'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Safari/605.1.15',
  10. 'Cookie': 'st_asi=delete; st_inirUrl=https%3A%2F%2Fbaidu.com%2F; st_psi=20240227192236777-113300301066-4864084221; st_pvi=11934193275781; st_sn=13; st_sp=2024-02-26%2015%3A19%3A30; JSESSIONID=37A0895F7D4E1F2005EF79C5B041FC90; st_si=63431626210633; HAList=ty-1-000001-%u4E0A%u8BC1%u6307%u6570; qgqp_b_id=b06ad5d3eaab94f81f12355ecebb1842'}
  11. money=requests.get(url=url,headers=header)
  12. money.encoding='utf8'
  13. data=json.loads(money.text)
  14. chart=data["result"]['data']
  15. for j in range(50):
  16. try:
  17. chartj=chart[j]
  18. print(chartj)
  19. code=chartj['SECURITY_CODE']
  20. abbr=chartj['SECURITY_NAME_ABBR']
  21. market=chartj['TRADE_MARKET']
  22. type=chartj['SECURITY_TYPE']
  23. eps=chartj['BASIC_EPS']
  24. epsde=chartj['DEDUCT_BASIC_EPS']
  25. income=chartj['TOTAL_OPERATE_INCOME']
  26. try:
  27. incomegrtht=float(chartj['YSTZ'])/100
  28. except:
  29. incomegrtht = chartj['YSTZ']
  30. profit=chartj['PARENT_NETPROFIT']
  31. try:
  32. profitgrtht=float(chartj['SJLTZ'])/100
  33. except:
  34. profitgrtht = chartj['SJLTZ']
  35. bps=chartj['BPS']
  36. try:
  37. roe=float(chartj['WEIGHTAVG_ROE'])/100
  38. except:
  39. roe=chartj['WEIGHTAVG_ROE']
  40. mgjy=chartj['MGJYXJJE']
  41. try:
  42. xsml=float(chartj['XSMLL'])/100
  43. except:
  44. xsml=chartj['XSMLL']
  45. lrfp=chartj['ASSIGNDSCRPT']
  46. hy=chartj['PUBLISHNAME']
  47. try:
  48. gxl=float(chartj['ZXGXL'])/100
  49. except:
  50. gxl=chartj['ZXGXL']
  51. list.loc[k]=[code,abbr,hy,type,market,eps,epsde,income,incomegrtht,profit,profitgrtht,bps,roe,mgjy,xsml,lrfp,gxl]
  52. k=k+1
  53. except:
  54. continue
  55. list.to_excel('list.xlsx',index=False)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/584700
推荐阅读
相关标签
  

闽ICP备14008679号