Python-Flask实现基金自选网站

news/2024/5/20 15:31:04/文章来源:https://blog.csdn.net/findhappy117/article/details/88388766

代码地址如下:
http://www.demodashi.com/demo/14734.html

项目介绍

本项目的基金数据来自天天基金网,但该网站用户体验较差,内容冗余,故自己实现一个轻量级网站,从8个指标维度对股票基金和债券基金进行挑选,可对进行收益进行排序,并且可查看基金的同类排名与历史涨跌幅,方便快捷的筛选选出优质基金进行投资,最大化收益率。

网站已部署在 http://134.175.24.108:52571 可点击链接查看效果,为了不影响其他用户的体验,部署的网站只显示前100只基金的数据,删除和自选的操作使用了本地存储,存在浏览器端。下载的代码压缩包中包含了本地存储和服务端存储两种版本。

项目截图如下:

项目文件结构

fund     # 代码文件夹
├── exclude.txt              # 已删除基金列表
├── own.txt                   # 自选基金列表
├── requirements.txt     # python第三方库依赖文件
├── fund.py                   # 服务端文件
├── static                      # 静态文件夹
│   ├── highstock.js
│   ├── index.css
│   ├── index.js
│   └── jj.png
└── templates              # 模板文件夹,存放html页面└── index.html

此外还有一个fund_local文件夹,结构与fund文件夹一致,其中的代码为本地存储版本,使用localStorage

项目运行

  1. 安装python
  2. 安装python第三方依赖库,项目文件夹中有依赖文件 pip install -r requirements.txt,依赖的库主要有flask,flask-bootstrap,pandas,gevent,requests。
  3. 运行 python fund.py,成功运行会输出 Listening at http://localhost:52571
  4. 访问 http://localhost:52571

代码实现

使用flask框架,网站前端框架使用bootstrap,表格控件为bootstrap-table,趋势图为highstock,文章最后有用到几个框架的文档网址,可自行阅读。

后端实现

首先进行初始化

def __init__(self, fund_type, num=100):self.app = Flask(__name__)self.num = num             # 基金数量self.last_time = 0         # 最后一次更新时间self.app.debug = Trueself.fund_type = fund_type # 基金类型,(股票,债券或者混合型)self.GetExcludeAndOwn()    # 获取已删除和自选的基金列表self.GetData()             # 获取数据Bootstrap(self.app)        # 初始化bootstrap

初始化完成之后

    # 读取文件,获取删除的基金和自选的基金def GetExcludeAndOwn(self):with open("exclude.txt", "a+") as fs:self.exclude = map(lambda x: x.strip(), fs.readlines())self.exclude = set(self.exclude)print("exclude id: ", self.exclude)with open("own.txt", "a+") as fs:self.own = map(lambda x: x.strip(), fs.readlines())self.own = set(self.own)print("own id: ", self.own)

从天天基金网获取基金数据,通过抓包得到数据的链接,爬虫与抓包这里不做展开,有兴趣可单独联系。
基金数据每天更新一次,获取到基金数据之后,存入DateFrame,去掉多余的列,只保留8个指标,然后将数据转为html,方便后面直接返回给前端展示。

# 获取近一年基金数据def GetData(self):now = time.time()if (now - self.last_time < 60 * 60 * 24):  # 24小时更新一次return self.fund_tableself.last_time = nows = requests.Session()now = datetime.today()# 起始时间为一年前的今天,结束时间为今天sd = date2str(now - timedelta(days=365)).strftime('%Y-%m-%d')ed = date2str(now).strftime('%Y-%m-%d')res = s.get('http://fund.eastmoney.com/data/rankhandler.aspx?op=ph&dt=kf&ft=%s&rs=&gs=0&sc=1yzf&st=desc&sd=%s&ed=%s&qdii=|&tabSubtype=,,,,,&pi=1&pn=%d&dx=1&v=%lf' %(self.fund_type, sd, ed, self.num, random())).contentres = res[res.find("["):res.rfind("]") + 1]obj = json.loads(res)arr = []for fund in obj:arr.append(fund.split(",")[:-4])columns = ["基金代码", "基金简称", "", "", "单位净值", "累计净值", "日增长率", "近1周", "近1月","近3月", "近6月", "近1年", "近2年", "近3年", "今年来", "成立来", "", "", "", "", "手续费"]self.fund_df = pd.DataFrame(arr, columns=columns)# 去掉多余的列self.fund_df.drop(self.fund_df.columns[[-2, -3, -4, -5, -6, -7, 2, 3, 4, 5, 6]],axis=1, inplace=True)self.fund_df.insert(0, "checkbox", "")# 自选基金数据self.own_df = self.fund_df[self.fund_df['基金代码'].isin(self.own)]self.own_table = self.own_df.to_html(index=False)# 其他基金数据self.fund_df = self.fund_df[~self.fund_df['基金代码'].isin(self.exclude)]self.fund_table = self.fund_df.to_html(index=False)return self.fund_table

设置路由,监听前端请求,删除基金的时候,将基金代码写入文件并更新基金数据,下次请求将不再返回已删除的基金

      @self.app.route("/fund", methods=["GET", "DELETE"])def fund():# 查看全部基金if request.method == "GET":return self.GetData()# 删除选中的基金else:id_list = request.form.getlist("id[]")self.fund_df = self.fund_df[~self.fund_df['基金代码'].isin(id_list)]self.fund_table = self.fund_df.to_html(index=False)self.exclude |= set(id_list)with open("exclude.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.exclude))return "OK"

关于自选基金,加自选时,将基金代码添加到自选基金列表,并且添加到已删除列表,保证记录的唯一性。取消自选时从自选列表删除,重新在全部基金里显示。

@self.app.route("/fund", methods=["GET", "DELETE"])def fund():# 查看全部基金if request.method == "GET":return self.GetData()# 删除选中的基金else:id_list = request.form.getlist("id[]")self.fund_df = self.fund_df[~self.fund_df['基金代码'].isin(id_list)]self.fund_table = self.fund_df.to_html(index=False)self.exclude |= set(id_list)with open("exclude.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.exclude))return "OK"@self.app.route("/own", methods=["GET", "POST", "DELETE"])def own():# 查看自选基金if request.method == "GET":return self.own_table# 加自选if request.method == "POST":id_list = request.form.getlist("id[]")self.own_df = self.own_df.append(self.fund_df[self.fund_df['基金代码'].isin(id_list)])self.own_table = self.own_df.to_html(index=False)self.own |= set(id_list)with open("own.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.own))self.fund_df = self.fund_df[~self.fund_df['基金代码'].isin(id_list)]self.fund_table = self.fund_df.to_html(index=False)self.exclude |= set(id_list)with open("exclude.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.exclude))return "OK"# 取消自选else:id_list = request.form.getlist("id[]")self.fund_df = self.own_df[self.own_df['基金代码'].isin(id_list)].append(self.fund_df)self.fund_table = self.fund_df.to_html(index=False)self.exclude -= set(id_list)with open("exclude.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.exclude))self.own_df = self.own_df[~self.own_df['基金代码'].isin(id_list)]self.own_table = self.own_df.to_html(index=False)self.own -= set(id_list)with open("own.txt", "w") as fs:fs.writelines(map(lambda x: "%s\n" % x, self.own))return "OK"

前端实现

页面加载时向后台请求数据,然后使用bootstrap-table进行表格渲染

// 获取全部基金数据
$.ajax({url: '/fund',type: 'GET',success: function (res) {$("#panel-all").html(res);$all_table = $('#panel-all table');$all_table.bootstrapTable(Object.assign({ toolbar: "#all-toolbar" }, fund_table_option));$("#all-toolbar").show();}
});// 获取自选基金数据
$.ajax({url: '/own',type: 'GET',success: function (res) {$("#panel-own").html(res);$own_table = $('#panel-own table');$own_table.bootstrapTable(Object.assign({ toolbar: "#own-toolbar" }, fund_table_option));$("#own-toolbar").show();}
});

基金删除,加自选,取消自选

// 删除选中的基金
$("#delete").click(function () {var selections = $all_table.bootstrapTable('getAllSelections').map(function (row) {var uid = row["基金代码"];$all_table.bootstrapTable("removeByUniqueId", uid);return uid;});$.ajax({url: '/fund',type: 'DELETE',data: { "id": selections },success: function () { }});
});// 单只基金 加自选
var add_own = function (code, ajax) {var row = $all_table.bootstrapTable("getRowByUniqueId", code);row["checkbox"] = false;$own_table.bootstrapTable("append", row);$all_table.bootstrapTable("removeByUniqueId", code);if (ajax) {$.ajax({url: '/own',type: 'POST',data: { "id": [code] },success: function () { }});}
};// 选中的基金 批量加自选
$("#batch_add_own").click(function () {var selections = $all_table.bootstrapTable('getAllSelections').map(function (row) {var uid = row["基金代码"];add_own(uid, false);return uid;});$.ajax({url: '/own',type: 'POST',data: { "id": selections },success: function () { }});
});var del_own = function (code, ajax) {var row = $own_table.bootstrapTable("getRowByUniqueId", code);row["checkbox"] = false;$all_table.bootstrapTable("prepend", row);$own_table.bootstrapTable("removeByUniqueId", code);if (ajax) {$.ajax({url: '/own',type: 'DELETE',data: { "id": [code] },success: function () { }});}
};// 选中的基金取消自选
$("#batch_del_own").click(function () {var selections = $own_table.bootstrapTable('getAllSelections').map(function (row) {var uid = row["基金代码"];del_own(uid, false);return uid;});$.ajax({url: '/own',type: 'DELETE',data: { "id": selections },success: function () { }});
});

在本地存储的版本中,以上操作不需要与后台交互,不需发送ajax请求,只需将变化的基金代码列表存入localStorage。如果对flask不太了解的话,建议先熟悉local版的代码,后台代码较为简单,熟悉了之后再阅读完整的版本。

####参考网站:
天天基金网:
http://fund.eastmoney.com/
flask中文文档:
https://dormousehole.readthedocs.io/en/latest/
bootstrap-table中文文档:
http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/
highstock演示:
https://www.hcharts.cn/demo/highstock
Python-Flask实现基金自选网站

代码地址如下:
http://www.demodashi.com/demo/14734.html

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_710655.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

任晶磊:如何看待程序员在 GitHub 发起抗议互联网公司实行 996 工作制网站?

作者&#xff1a;任晶磊 有人说&#xff0c;此行为艺术仍然停留在抱怨的阶段。那么我们来看看出路在何方&#xff0c;所幸已有人在路上。注意&#xff0c;这里都是正在落地的干货。 Disclaimer&#xff1a;我在表达观点时会引用自己的研究工作。如果认为此有夹带私货之嫌&…

大型网站架构系列:分布式消息队列

以下是消息队列以下的大纲&#xff0c;本文主要介绍消息队列概述&#xff0c;消息队列应用场景和消息中间件示例&#xff08;电商&#xff0c;日志系统&#xff09;。 本次分享大纲 消息队列概述消息队列应用场景消息中间件示例JMS消息服务常用消息队列参考&#xff08;推荐&am…

Python网页分析,分析网站的日志数据

前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 以下文章来源于大话数据分析&#xff0c;作者&#xff1a;尚天强 网站的日志数据记录了所有Web对服务器的访问活动&#xff0c;本节通过Python第…

基于django快速开发一个网站(一)

* 创建虚拟环境、基于虚拟环境创建django2.0.0和图片加载库和mysql数据库驱动 1. 创建目录并创建虚拟环境 ╰$ mkdir Cornucopiavirtualenv ╰$ cd Cornucopiavirtualenv ╰$ virtualenv env1 2. 进入bin目录&#xff0c;并激活虚拟环境 ╰$ cd bin ╰$ source activate …

发现一个好看的手机壁纸网站,撸代码的手已经饥渴难耐了

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 最近有同学的爬虫代码出了bug&#xff0c;给问我怎么改 于是就发现了这个好看的手机壁纸网站。 看到那么多好看的壁纸&#xff0c;我的爬虫已经饥渴难耐…

浅谈web网站架构演变过程

前言我们以javaweb为例&#xff0c;来搭建一个简单的电商系统&#xff0c;看看这个系统可以如何一步步演变。该系统具备的功能&#xff1a;用户模块&#xff1a;用户注册和管理商品模块&#xff1a;商品展示和管理交易模块&#xff1a;创建交易和管理阶段一、单机构建网站网站的…

php域名墙检测,php 网站域名被墙判断请求方法

可以使用exec去进行查询判断&#xff0c;判断traceroute to 出的ip和最后追踪到的IP是否匹配&#xff0c;如果不匹配可能就被墙了。也可以有个保险的方法&#xff0c;去请求下看是否有返回数据没有基本就是墙了。查询命令方法&#xff1a;traceroute --tcp youtubemy.com[rootl…

思科模拟器企业网站服务器配置,思科模拟器服务器配置

思科模拟器服务器配置 内容精选换一换虚拟IP(Virtual IP Address&#xff0c;简称VIP)是一个未分配给真实弹性云服务器网卡的IP地址。弹性云服务器除了拥有私有IP地址外&#xff0c;还可以拥有虚拟IP地址&#xff0c;用户可以通过其中任意一个IP(私有IP/虚拟IP)访问此弹性云服务…

推荐95个极富创意的单页网站设计实例欣赏

随着网络带宽的快速提升&#xff0c;越来越多的Web视觉设计师开始将自己的网页设计推向单页面的表现形式&#xff0c;他们在不断的尝试各种令人耳目一新的设计方案&#xff0c;像下面的这些例子有很多都是出自个人网站&#xff0c;使用JavaScript来实现单页面内的内容切换&…

30 个用于杂志网站的 WordPress 主题

WordPress 已经形成了一个非常完善的生态链&#xff0c;为 WordPress 开发的各种插件、主题越来越丰富。本文介绍 30 个适用于杂志网站使用的 WordPress 主题&#xff0c;其中也包含一些收费的主题&#xff0c;制作非常精美。 免费的 WordPress 杂志主题 Snips DotNews Render …

网站安全检测 Web 安全测试工具

随着 Web 应用越来越广泛&#xff0c;Web 安全威胁日益凸显。黑客利用网站操作系统的漏洞和 Web 服务程序的 SQL 注入漏洞等得到Web服务器的控制权限&#xff0c;轻则篡改网页内容&#xff0c;重则窃取重要内部数据&#xff0c;更为严重的则是在网页中植入恶意代码&#xff0c;…

SharePoint 2010设计(Design)权限能操作的网站操作菜单项

在SharePoint平台中有经典的5大权限&#xff1a;完全控制、设计、参与讨论、只读、仅查看。其中设计权限与完全控制权限有些相似&#xff0c;而只读和仅查看基本上差不多&#xff0c;参与讨论权限主要是针对内容管理的。设计权限在SharePoint 2010里是不能设置权限的&#xff0…

ubuntu服务器网站备份,用 Ubuntu 建立 Time Machine 备份服务器

用 Ubuntu 建立 Time Machine 备份服务器&#xff1a;1、安装 Netatalksudo apt-get install netatalk2、设置 Time Machine 备份文件存放位置, 假设位置在 /backup/TimeMachinesudo vi /etc/netatak/AppleVolumes.default#~/ "Home Directory"/backup/TimeMachine &…

arcgis制作瓦片地图_挖掘Dark Sky Maps(热的要死后,疯传的一个气温地图网站)...

最近&#xff0c;各种朋友圈&#xff0c;社会媒体&#xff0c;都在疯传一张图&#xff0c;这张图显示的全球的气温图&#xff0c;本没有什么特别的&#xff0c;但是这张图的网站来源所展示的数据与气象局或者各种天气预报的温度值相差倒是不少&#xff0c;引来一片网友的吐槽。…

django 跳转其他网站_Django 实战 | 搭一个 GitHub 用户展示网站 04

一、搜索页面跳转在 urls.py 中添加一个 user 路径&#xff1a;from django.urls import path from . import viewsurlpatterns [path(, views.home, name"home"),path(user/, views.user, name"user"), ]在 views.py 中添加一个 user 方法&#xff1a;de…

使用LogParser分析IIS网站日志

LogParser是个强大的&#xff0c;多功能的分析工具&#xff0c;它统一的查询方式适用于各种文本类型文件&#xff08;例如日志文件&#xff0c;XML文件&#xff0c;CSV文件&#xff09;和操作系统层面数据文件&#xff08;例如事件日志&#xff0c;注册表&#xff0c;文件系统&…

Webydo:一款在线自由创建网站的 Web 应用

Webydo 是一款专业的在线建站应用&#xff0c;使平面设计师可以创建和管理 HTML 网站&#xff0c;而无需编写代码。设计人员可以设计任何类型网站&#xff0c;只需要点击按钮&#xff0c;就能够发布先进的 HTML 网站。 你可以控制所有的设计组件&#xff0c;如&#xff1a;元素…

元素“Button”不是已知元素。原因可能是网站中存在编译错误,或者缺少web.config文件...

最近开发的时候ASP控件都有波浪下划线&#xff0c;提示不是已知元素&#xff0c;搞得挺郁闷的。虽然不影响变异&#xff0c;不过就是不爽。 折腾N久...... 解决了&#xff0c;把FramWork平台换成3.5&#xff0c;问题解决&#xff0c;不知道为啥&#xff0c;求大神指点。 问题描…

优化网站设计(三):对资源添加缓存控制

前言 网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议。这方面的研究一直没有停止过&#xff0c;我在不同的场合也分享过这样的话题。 作为通用的原则&#xff0c;雅虎的工程师团队曾经给出过35个最佳实践。这个列表请参考 Best Practices fo…

网站服务器上加入三层开发的网站错误解决

在网站服务器上添加三层开发的网站&#xff0c;发现网站打开的时候提示Server Error in / Application.截图如下 解决办法&#xff1a; 1,把文件夹中的bin文件夹移动到上一目录下&#xff0c;比如放入该文件的路径是root根目录&#xff0c;然后新建test目录&#xff0c;上传网站…