python在财务中的应用实训报告-实践应用|PyQt5制作雪球网股票数据爬虫工具
importrequests
fromfake_useragentimportUserAgent
url= 'https://xueqiu.com'
session= requests. Session
headers= { "User-Agent": UserAgent( verify_ssl= False). random}
session. get( url, headers= headers)
#获取当前的Cookie
Cookie= dict( session. cookies)5.2基础参数
基础参数是用于财务数据请求时原始网址构成参数选择,我们在可视化操作工具中需要对财务数据类型进行选择,因此这里需要构建财务数据类型字典。
#原始网址
original_url= 'https://xueqiu.com'
#财务数据类型字典
dataType= { '全选': 'all',
'主要指标': 'indicator',
'利润表': 'income',
'资产负债表': 'balance',
'现金流量表': 'cash_flow'}
6
获取获取各证券市场上市名录
这其实就是一个简单的网络爬虫及数据格式调整的过程,实现代码如下:
1importrequests
2importpandas aspd
3importjson
4fromfake_useragent importUserAgent
5#请求头设置
6headers = { "User-Agent": UserAgent(verify_ssl= False).random}
7#股票清单列表地址解析(通过设置参数size为9999可以只使用1个静态地址,全部股票数量不足5000)
8url = 'https://xueqiu.com/service/v5/stock/screener/quote/list?page=1&size=9999&order=desc&orderby=percent&order_by=percent&market=CN&type=sh_sz'
9#请求原始数据
10response = requests.get(url,headers = headers)
11#获取股票列表数据
12df = response.text
13#数据格式转化
14data = json.loads(df)
15#获取所需要的股票代码及股票名称数据
16data = data[ 'data'][ 'list']
17#将数据转化为dataframe格式,并进行相关调整
18data = pd.DataFrame(data)
19data = data[[ 'symbol', 'name']]
20data[ 'name'] = data[ 'symbol']+ ' '+data[ 'name']
21data.sort_values(by = [ 'symbol'],inplace= True)
22data = data.set_index(data[ 'symbol'])[ 'name']
23#将股票列表转化为字典,键为股票代码,值为股票代码和股票名称的组合
24ipoCodecn = data.to_dict
A股股票代码及公司名称字典如下:
7
获取上市公司财务数据并导出
根据在可视化操作界面选择的 财务报告时间区间、财务报告数据类型、所选证券市场类型以及所输入的股票代码后,需要先根据这些参数组成我们需要进行数据请求的网址,然后进行数据请求。
由于请求后的数据是json格式,因此可以直接进行转化为dataframe类型,然后进行导出。在数据导出的时候,我们需要判断该数据文件是否存在,如果存在则追加,如果不存在则新建。
7.1获取上市公司财务数据
通过选定的参数生成财务数据网址,然后根据是否全选决定后续数据请求的操作,因此可以拆分为获取数据网址和请求详情数据两部分。
7.1.1获取数据网址
数据网址是根据证券市场类型、财务数据类型、股票代码、单页数量及起始时间戳决定,而这些参数都是通过可视化操作界面进行设置。
证券市场类型 控件 是 radioButton,可以通过 ischecked方法判断是否选中,然后用if-else进行参数设定;
财务数据类型 和 股票代码 因为支持 全选,需要先进行全选判定(全选条件下是需要循环获取数据网址,否则是单一获取即可),因此这部分需要再做拆分;
单页数量 考虑到每年有4份财务报告,因此这里默认为年份差*4;
时间戳 是 根据起始时间中的 结束时间 计算得出,由于可视化界面输入的 是 整数年份,我们可以通过 mktime方法获取时间戳。
1defGet_url(self,name,ipo_code):
2#获取开始结束时间戳(开始和结束时间手动输入)
3inputstartTime = str(self.start_dateEdit.date.toPyDate.year)
4inputendTime = str(self.end_dateEdit.date.toPyDate.year)
5endTime = f' {inputendTime}-12-31 00:00:00'
6timeArray = time.strptime(endTime, "%Y-%m-%d %H:%M:%S")
7
8#获取指定的数据类型及股票代码
9filename = ipo_code
10data_type =dataType[name]
11#计算需要采集的数据量(一年以四个算)
12count_num = (int(inputendTime) - int(inputstartTime) + 1) * 4
13start_time = f' {int(time.mktime(timeArray))}001'
14
15#证券市场类型
16if(self.radioButtonCN.isChecked):
17ABtype = 'cn'
18num = 3
19elif(self.radioButtonUS.isChecked):
20ABtype = 'us'
21num = 6
22elif(self.radioButtonHK.isChecked):
23ABtype = 'hk'
24num = 6
25else:
26ABtype = 'cn'
27num = 3
28
29#基础网站
30base_url = f'https://stock.xueqiu.com/v5/stock/finance/ {ABtype}'
31
32#组合url地址
33url = f' {base_url}/ {data_type}.json?symbol= {ipo_code}&type=all&is_detail=true&count= {count_num}×tamp= {start_time}'
34
35returnurl,num
7.1.2请求详情数据
需要根据用户输入决定数据采集方式,代码中主要是根据用户输入做判断然后再进行详情数据请求。
1#根据用户输入决定数据采集方式
2defGet_data(self):
3#name为财务报告数据类型(全选或单个)
4name = self.Typelist_comboBox.currentText
5#股票代码(全选或单个)
6ipo_code = self.lineEditCode.text
7#判断证券市场类型
8if(self.radioButtonCN.isChecked):
9ipoCodex=ipoCodecn
10elif(self.radioButtonUS.isChecked):
11ipoCodex=ipoCodeus
12elif(self.radioButtonHK.isChecked):
13ipoCodex=ipoCodehk
14else:
15ipoCodex=ipoCodecn
16#根据财务报告数据类型和股票代码类型决定数据采集的方式
17ifname == '全选'andipo_code == '全选':
18foripo_code inlist(ipoCodex.keys):
19forname inlist(dataType.keys)[ 1:]:
20self.re_data(name,ipo_code)
21elifname == '全选'andipo_code != '全选':
22forname inlist(dataType.keys)[ 1:]:
23self.re_data(name,ipo_code)
24elifipo_code == '全选'andname != '全选':
25foripo_code inlist(ipoCodex.keys):
26self.re_data(name,ipo_code)
27else:
28self.re_data(name,ipo_code)
29
30#数据采集,需要调用数据网址(Get.url(name,ipo_code)
31defre_data(self,name,ipo_code):
32name = name
33#获取url和num(url为详情数据网址,num是详情数据中根据不同证券市场类型决定的需要提取的数据起始位置)
34url,num = self.Get_url(name,ipo_code)
35#请求头
36headers = { "User-Agent": UserAgent(verify_ssl= False).random}
37#请求数据
38df = requests.get(url,headers = headers,cookies = cookies)
39
40df = df.text
41try:
42data = json.loads(df)
43pd_df = pd.DataFrame(data[ 'data'][ 'list'])
44to_xlsx(num,pd_df)
45exceptKeyError:
46log = '该股票此类型报告不存在,请重新选择股票代码或数据类型'
47self.rizhi_textBrowser.append(log)
7.2财务数据处理并导出
单纯的数据导出是比较简单的操作,直接 to_excel即可。但是考虑到同一个上市公司的财务数据类型有四种,我们希望都保存在同一个文件下,且对于同类型的数据可能存在分批导出的情况希望能追加。因此,需要进行特殊的处理,用 pd.ExcelWriter方法操作。
1#数据处理并导出
2defto_xlsx(self,num,data):
3pd_df = data
4#获取可视化操作界面输入的导出文件保存文件夹目录
5filepath = self.filepath_lineEdit.text
6#获取文件名
7filename = ipoCode[ipo_code]
8#组合成文件详情(地址+文件名+文件类型)
9path = f' {filepath}{filename}.xlsx'
10#获取原始数据列字段
11cols = pd_df.columns.tolist
12#创建空dataframe类型用于存储
13data = pd.DataFrame
14#创建报告名称字段
15data[ '报告名称'] = pd_df[ 'report_name']
16#由于不同证券市场类型下各股票财务报告详情页数据从不同的列才是需要的数据,因此需要用num作为起点
17fori inrange(num,len(cols)):
18col = cols[i]
19try:
20#每列数据中是列表形式,第一个是值,第二个是同比
21data[col] = pd_df[col].apply( lambdax:x[ 0])
22# data[f'{col}_同比'] = pd_df[col].apply(lambda x:x[1])
23exceptTypeError:
24pass
25data = data.set_index( '报告名称')
26log = f' {filename}的 {name}数据已经爬取成功'
27self.rizhi_textBrowser.append(log)
28#由于存储的数据行索引为数据指标,所以需要对采集的数据进行转T处理
29dataT = data.T
30dataT.rename(index = eval( f'_ {name}'),inplace= True)
31#以下为判断数据报告文件是否存在,若存在则追加,不存在则重新创建
32try:
33ifos.path.exists(path):
34#读取文件全部页签
35df_dic = pd.read_excel(path, None)
36ifname notinlist(df_dic.keys):
37log = f' {filename}的 {name}数据页签不存在,创建新页签'
38self.rizhi_textBrowser.append(log)
39#追加新的页签
40withpd.ExcelWriter(path,mode= 'a') aswriter:
41book = load_workbook(path)
42writer.book = book
43dataT.to_excel(writer,sheet_name=name)
44writer.save
45else:
46log = f' {filename}的 {name}数据页签已存在,合并中'
47self.rizhi_textBrowser.append(log)
48df = pd.read_excel(path,sheet_name = name,index_col= 0)
49d_ = list(set(list(dataT.columns)) - set(list(df.columns)))
50#使用merge进行数据合并
51dataT = pd.merge(df,dataT[d_],how= 'outer',left_index= True,right_index= True)
52dataT.sort_index(axis= 1,ascending= False,inplace= True)
53#页签中追加数据不影响其他页签
54withpd.ExcelWriter(path,engine= 'openpyxl') aswriter:
55book = load_workbook(path)
56writer.book = book
57idx = writer.book.sheetnames.index(name)
58#删除同名的,然后重新创建一个同名的
59writer.book.remove(writer.book.worksheets[idx])
60writer.book.create_sheet(name, idx)
61writer.sheets = {ws.title:ws forws inwriter.book.worksheets}
62
63dataT.to_excel(writer,sheet_name=name,startcol= 0)
64writer.save
65else:
66dataT.to_excel(path,sheet_name=name)
67
68log = f' {filename}的 {name}数据已经保存成功'
69self.rizhi_textBrowser.append(log)
70
71exceptFileNotFoundError:
72log = '未设置存储目录或存储目录不存在,请重新选择文件夹'
73self.rizhi_textBrowser.append(log)
由于源代码内容较多,就不全量展示了,可在公众号回复“ 雪球”可获取源代码文件呢
参考资料:
Python Qt GUI与数据可视化编程
https://requests.readthedocs.io/zh_CN/latest/user/advanced.html#session-objects
近期九大热门:
由 菜鸟学Python原班人马打造的公众号: 程序员GitHub
接下来我们将会在该公众号上,为大家分享 GitHub 上优质的开源神器,程序员圈的趣事,坚持每天一篇原创文章的输出,感兴趣的小伙伴可以关注一下哈!返回搜狐,查看更多
python在财务中的应用实训报告-实践应用|PyQt5制作雪球网股票数据爬虫工具相关推荐
- python在财务中的应用实训报告-DATATOM | 大数据实训
真实实战环境 DSight提供独立的实验环境集群,交互式的实验任务.实时的实验指导.项目的上机操作.配套的教学视频.实时的数据监控等,能够保证学生灵活.快速地掌握专业核心技术及项目开发能力. 丰富课程 ...
- 建模实训报告总结_建筑模型制作实训报告总结
一.实践目的 本次实践是建筑学专业的综合性实践教学环节,旨在培我们的实际动手能力.其主要任务是使我们理解模型制作在作品设计中的重要性,掌握模型制作的基本工具.方法和过程,锻炼我们的动手实践能力,完善我 ...
- 计算机硬软件故障实训报告,计算机维护维修实训报告.docx
实训报告 -I- 沈阳工程学院计算机组装调试及工具软件实训报告 计算机维护与维修实训任务书 一.实训目的 计算机组装及工具软件实训是一门计算机技术的实践性教学课程,通过计算机 组装调试及工具软件实训可 ...
- html网页制作实习,我的网页制作实训报告
我的网页制作实训报告 我的网页制作实训报告 实验过程 1.资料的搜集,网页制作实习报告. 2.熟悉制作软件. 3.构建站点框架. 打开dremweaver后第一步便是新建站点 4设计主页及二级页面. ...
- 基于javaweb的仓库管理系统(java+springboot+layui+html+thymeleaf+mysql+实训报告)
基于javaweb的仓库管理系统(java+springboot+layui+html+thymeleaf+mysql+实训报告) 运行环境 Java≥8.MySQL≥5.7 开发工具 eclipse ...
- python实验过程心得体会_web实训心得体会
篇一:JAVAWEB实训心得体会 jsp+servlet+mysql 论坛 项目实训总结 实训人: 程路峰 学号:11103303 通过为期10天的实训,我学习了很多关于java web的知识.在老师 ...
- python飞机大战实训报告200_飞机大战实训报告.doc
您所在位置:网站首页 > 海量文档  > 行业资料 > 航空/航天 飞机大战实训报告.doc22页 本文档一共被下载: ...
- python实训报告万能模板_(完整word版)实训报告万能模板
实训报告万能模板 "纸上得来终觉浅,绝知此事要躬行 ! "在这短短的时间里,让 我深深的感觉到自己在实际应用中所学专业知识的匮乏. 让我真真领 悟到"学无止境" ...
- python实训报告5000字_测量实训报告范文5000字
测量实训报告范文 纸上得来终觉浅, 绝知此事要躬行, 书本上知识只有在实践中才能被 检验,方知不足,实践是检验真理的唯一标准,在这次实习中,让我 学到了许多,也认识到自身的不足! 首先, 实习的过程让 ...
最新文章
- 零知识证明实践教程,第二部分
- 第六章 ppp协议实验
- 【JAVA】使用IntelliJ IDEA创建Java控制台工程
- debug 标志位说明
- 把一张合成图分拆出各个小图
- tomcat的安装及配置
- A4纸尺寸 web打印报告
- GitHub标星7700:Python从新手到大师,只要100天
- PYTORCH 定义模型
- decimal保留千分位
- 数据库优化java设计模式架构 策略 责任链
- ue4序列帧ui_UE4动画序列帧通知机制(二)
- windows 下安装redis
- 《数据库实验》实验五:数据库编程
- 子列和列_最大连续子列和问题 JAVA实现
- 三维模型(X,Y,Z)坐标,UV坐标
- iOS开发Xcode8需要注意的那些坑
- 如何设置虚拟机访问外网
- 旁观OpenGL里的透视投影矩阵
- html图片后边自动底部对齐,css实现图片与文字底边对齐
热门文章
- influxDB和grafana
- 【嵌入式开发】用 VLC 显示 树莓派摄像头 H264 裸流
- SPOJ - LIS2 Another Longest Increasing Subsequence Problem
- xshell 上传 下载文件
- 0,1,2,3,2,1,0,1,2,3,2,1,0,...
- apcloud混合式开发app学习笔记
- title: bat批处理简介:Windows自动化之道
- python中requests.session的妙用
- PCL中异常处理机制
- MySQL-查询数据(SELECT)