python 选择 flask_Python-Flask实现基金自选网站

news/2024/5/14 7:31:24/文章来源:https://blog.csdn.net/weixin_39981093/article/details/110282297

项目介绍

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

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

项目截图如下:

4gJLoIf2m3vfiap5QOT.png

mbTWxAZnPDkjp0iGjsN.png

1s8HU4DfXFbGUh140J3.png

项目文件结构

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

项目运行

安装python

安装python第三方依赖库,项目文件夹中有依赖文件 pip install -r requirements.txt,依赖的库主要有flask,flask-bootstrap,pandas,gevent,requests。

运行 python fund.py,成功运行会输出 Listening at 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 = True

self.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_table

self.last_time = now

s = 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())).content

res = 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://www.luyixian.cn/news_show_727922.aspx

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

相关文章

poi获取段落位置_某少儿不宜网站图片拍摄位置分析,Python批量读取图片GPS位置!...

1. python读取图片exif属性中的GPS信息智能手机或平板如果在拍照时开启定位服务&#xff0c;照片中就会记录拍照位置信息和拍摄时间。如果将原始照片直接发送发布到网上&#xff0c;无意中就泄漏了自己的位置信息&#xff0c;有恶意企图的人可能会通过照片分析出你的家庭住址和…

开源框架_Java快速开发网站开源框架集合

介绍程序员都有开发博客网站的梦想,如果自己从买服务器开始搞起的话,会是一个非常漫长的过程.消耗的不光是时间还有非常多的精力,多半都会放弃了.但是如果把这个链路中的耗时的部分给优化下,那么这个梦想就非常的简单了.下面是搜集的一些快速开发博客网站的开源项目,可以帮助大…

机器学习实战|使用K-临近算法改进约会网站的配对效果

1 准备数据&#xff1a;从文本文件中解析数据 datingTestSet.txt: 每列分别代表每年获得的飞行常客里程数、玩游戏视频所耗时间百分比、每周消费的冰淇淋公升数、不喜欢/魅力一般/极具魅力&#xff08;即标签&#xff09; datingTestSet2.txt: 使用file2matrix函数处理输入…

电脑有回声_企业建设网站流程解析-上海回声网络

伴随着互联网的快速发展&#xff0c;几乎95%的企业都有属于自己的网站。网站作为企业在互联网上营销的敲门砖&#xff0c;其重要性不言而喻。很多人对网站的建设流程没有多大的概念&#xff0c;其实企业要想做好一个网站&#xff0c;流程这块是相当重要的。上海回声网络科技有限…

ckks方案优化最好的_怎样才能让网站优化快速有成效?

在网站运营中&#xff0c;网站优化最为关键。但是为什么很多优化人员优化不上去自己的网站呢?总的来说还是没有做好优化。那么我们应该怎样去优化网站才能快速有效的起到效果呢?深圳网站优化推广第一、每天更新网站的内容优化想要做好贵在持之以恒&#xff0c;我们必须每天坚…

服务器网站关联数据库,服务器关联数据库

服务器关联数据库 内容精选换一换PostgreSQL支持逻辑备份。您可使用pg_dump逻辑备份功能&#xff0c;导出备份文件&#xff0c;再通过psql导入到RDS中&#xff0c;实现将PostgreSQL的数据导入到云数据库RDS中。云数据库RDS服务支持开启公网访问功能&#xff0c;通过弹性公网IP进…

CentOS7.5基于LNMP平台搭建动态网站

**基于LNMP平台搭建动态网站**主机服务器&#xff1a;CentOS7.5 验证客户端&#xff1a;windows10/7 ***LNMP 动态网站部署架构是一套由Linux Nginx MySQL PHP 组成的动态网站系统 需要安装&#xff1a;PHP NGINXMYSQL 以及一系列依赖包。一、 先安装所需要的依赖包以及其他…

kali linux使用社会工程学工具伪造网站

使用社会工程学工具伪造网站 ​ 社会工程学是一种通过对受害者心理弱点、本能反应、好奇心、信任、贪婪等心理陷阱进行诸如欺骗等危害手段取得自身利益的手法&#xff0c;是通过研究受害者心理&#xff0c;并以此诱使受害者做出配合&#xff0c;从而达到自身目的的方法。 ​ …

php301劫持,黑帽seo技巧-301权重代码劫持

原标题&#xff1a;黑帽seo技巧-301权重代码劫持黑帽seo技巧-301权重代码劫持&#xff0c;让别人网站权重变成自己网站的权重&#xff01;一、为什么要做地区劫持&#xff1a;不会被发现的黑帽seo技巧-地区劫持代码最近群里(QQ群&#xff1a;165383652)的小伙伴有人问&#xff…

【资源网站】推荐几个搜索资源网站

学习技术过程我们常见需要使用搜索引擎来检索资料&#xff0c;国内常用的也就是百度了。当然&#xff0c;有条件的话(如在高校)首先推荐使用Google&#xff0c;如果没办法使用&#xff0c;可以使用以下几个作为备用&#xff1a; linux公社资料&#xff1a;linux.linuxidc.com

MR_LINUX_DRIVER安装教程,CentOS安装RAID卡驱动总结_Linux教程_Linux公社-Linux系统门户网站...

有些时候CentOS Linux内核不存在raid卡的驱动&#xff0c;以前只能用软盘加载驱动&#xff0c;其实是还有其它方法的&#xff0c;只要找到官方相应的驱动&#xff0c;现在Raid卡的品牌很多&#xff0c;但是大部分独立raid卡为highpoint&#xff0c;3ware,adapter,lsi,promise等…

python爬虫学习笔记(一)-- 网站自动登录(一)

上篇介绍了Python的5中参数类型&#xff0c;这里我们再简单的复习一下&#xff1a; 这个案例中&#xff0c;我们使用requests中定义个get函数来复习&#xff1a; get(url, paramsNone, **kwargs) post(url, dataNone, jsonNone, **kwargs) url是位置参数或者关键字参数、par…

debian wget安装_Linux小白网站搭建——宝塔面板安装

网站服务器搭建是个较为麻烦的过程&#xff0c;对于小白来讲确实有点困难&#xff0c;那么今天出一套小白教程。提前准备&#xff1a;服务器(阿里云&#xff0c;腾讯云&#xff0c;华为云等等)首先连接自己的服务器(每个命令之后需要键入回车键)浏览器百度搜索宝塔&#xff0c;…

dede建站mysql_【CMS系统建站】dedecms如何访问后台

dedecms如何访问后台&#xff1f;访问dedecms后台的方法&#xff1a;第一&#xff0c;默认的后台入口是http://你的域名/dede/如果你没有修改&#xff0c;通过默认的后台路径就可以访问。一般dedecms的帐号密码为admin。第二&#xff0c;如果您修改了dedecms的访问路径&#xf…

搭建神经网络---可视化 网站(干货)

下面的内容适合于初学者更好地对 不同的神经网络模型 能形象的了解。 官网地址&#xff1a;http://playground.tensorflow.org/ 下图是主界面&#xff1a; 参数说明&#xff1a; 1&#xff09;Problem type 问题类型&#xff08;是分类问题&#xff0c;还是回归问题&#xff…

基于华为云轻松搭建属于自己的网站 (Linux,Apache,MySQL,PHP)

前言 本文使用华为云服务&#xff0c;向大家搭建属于自己的网站&#xff0c;搭建过程会详细介绍。搭建网站的过程亲自走了3遍&#xff0c;确认没问题才写这篇博客的&#xff0c;大家放心地根据步骤流程一步一步。如果大家担心自己能不能搭建成功&#xff0c;本文有网站搭建时每…

基于华为云轻松搭建属于自己的网站 LAMP(Linux,Apache,MySQL,PHP)

前言 本文使用华为云服务,向大家搭建属于自己的网站,搭建过程会详细介绍。搭建网站的过程亲自走了3遍,确认没问题才写这篇博客的,大家放心地根据步骤流程一步一步。如果大家担心自己能不能搭建成功,本文有网站搭建时每个过程步骤的截图,大家看着流程步骤和图片引导,是能…

仅通过SQL备份文件将MOSS服务器场及所有网站数据迁移到新的一台服务器上

背景&#xff1a;这是一次完整到服务器迁移项目。现有MOSS的物理环境是两台服务器&#xff0c;一台后台的SQL服务器&#xff0c;一台前台的Web服务器。SQL服务器为Win03SQL05&#xff0c;Web服务器为Win03MOSS07。由于整个MOSS系统上只承担了某部门的共享数据、规章制度等文档&…

新建不了_「重庆网络营销推广」新建网站的五点网络推广方法

现在越来越多的企业都开始接触互联网了&#xff0c;通过互联网营销推广方式很多的企业都从中得到了很高的收益&#xff0c;不过企业想接触互联网就必须得有一个自己的网站&#xff0c;而对于一个刚介入互联网的企业来说根本就不会推广自己的新网站&#xff0c;那么接下来就给大…

共享游戏服务器网站,共享游戏服务器链接

共享游戏服务器链接 内容精选换一换在创建SAP HANA主节点服务器的时候创建了1个SBD共享卷&#xff0c;因此需要将此共享卷挂载到SAP HANA备节点服务器上。另外在创建SAP S/4HANA主节点服务器的时候创建了3个共享卷&#xff0c;因此也需要将这3个共享卷分别绑定到SAP S/4HANA备节…