做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)
图:
股票自选助手
这是一个基于 Django 开发的 A 股自选股票信息查看系统。系统使用 akshare 库获取实时股票数据,支持添加、删除和更新股票信息。
功能特点
- 支持添加自选股票
- 实时显示股票价格和涨跌幅
- 一键更新所有股票数据
- 支持删除不需要的股票
- 使用中国时区显示更新时间
- 支持简体中文界面
技术栈
- Python 3.8+
- Django 5.0.1
- akshare(A股数据获取)
- Bootstrap 5.1.3(前端界面)
- SQLite(数据存储)
安装步骤
- 克隆项目到本地:
git clone [项目地址]
cd stock_tracker
- 创建并激活虚拟环境(可选但推荐):
python -m venv venv
# Windows
venv\Scripts\activate
# Linux/Mac
source venv/bin/activate
- 安装依赖包:
pip install django akshare pandas
- 初始化数据库:
python manage.py migrate
- 启动开发服务器:
python manage.py runserver
- 访问系统:
打开浏览器,访问 http://127.0.0.1:8000
使用说明
添加股票
- 在输入框中输入股票代码,支持以下格式:
-
- 直接输入代码:
600519
(系统会自动判断沪深市场) - 带后缀格式:
- 直接输入代码:
-
-
- 上证股票:
600519.SS
- 深证股票:
000001.SZ
- 上证股票:
-
- 点击"添加"按钮将股票添加到自选列表
更新股票数据
- 点击"更新价格"按钮可以一次性更新所有股票的最新数据
- 系统会显示更新成功和失败的股票数量
删除股票
- 点击每个股票行右侧的"删除"按钮可以将股票从自选列表中移除
项目结构
stock_tracker/
├── manage.py
├── stock_tracker/ # 项目配置目录
│ ├── __init__.py
│ ├── settings.py # 项目设置
│ ├── urls.py # URL配置
│ └── wsgi.py
└── stocks/ # 股票应用目录├── __init__.py├── models.py # 数据模型├── views.py # 视图函数├── urls.py # 应用URL配置└── templates/ # 模板文件└── stocks/└── stock_list.html
开发说明
数据模型
Stock
模型包含以下字段:
symbol
: 股票代码name
: 股票名称current_price
: 当前价格change_percent
: 涨跌幅last_updated
: 最后更新时间
主要视图函数
stock_list
: 显示股票列表add_stock
: 添加新股票remove_stock
: 删除股票update_prices
: 更新股票价格
注意事项
- 时区设置:
-
- 系统使用中国时区 (Asia/Shanghai)
- 所有时间显示均为本地时间
- 数据更新:
-
- 使用 akshare 获取实时数据
- 支持批量更新所有股票
- 错误处理:
-
- 系统会显示详细的错误信息
- 包含股票代码格式提示
维护和更新
- 数据库备份:
-
- 定期备份 SQLite 数据库文件
- 依赖更新:
-
- 定期检查并更新依赖包
- 特别注意 akshare 的更新
代码:
stocks\models.py
from django.db import modelsclass Stock(models.Model):symbol = models.CharField(max_length=10, unique=True)name = models.CharField(max_length=100)current_price = models.DecimalField(max_digits=10, decimal_places=2, null=True)change_percent = models.DecimalField(max_digits=5, decimal_places=2, null=True)last_updated = models.DateTimeField(auto_now=True)def __str__(self):return f"{self.symbol} - {self.name}"
stocks\views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import Stock
import akshare as ak
from datetime import datetime
import pandas as pddef stock_list(request):stocks = Stock.objects.all().order_by('symbol')return render(request, 'stocks/stock_list.html', {'stocks': stocks})def add_stock(request):if request.method == 'POST':symbol = request.POST.get('symbol', '').upper()try:# 处理股票代码格式if symbol.endswith('.SZ'):code = symbol.replace('.SZ', '')market = 'sz'elif symbol.endswith('.SS'):code = symbol.replace('.SS', '')market = 'sh'else:code = symbolmarket = 'sh' if code.startswith('6') else 'sz'# 获取实时行情stock_info = ak.stock_zh_a_spot_em()stock_data = stock_info[stock_info['代码'] == code]if stock_data.empty:messages.error(request, f'找不到股票 {symbol} 的信息。请确保:\n1. 股票代码格式正确\n2. 对于上证股票,可以添加.SS后缀\n3. 对于深证股票,可以添加.SZ后缀')return redirect('stock_list')# 获取第一行数据stock_row = stock_data.iloc[0]stock_obj, created = Stock.objects.get_or_create(symbol=symbol,defaults={'name': stock_row['名称']})# 更新股票信息stock_obj.current_price = float(stock_row['最新价'])stock_obj.change_percent = float(stock_row['涨跌幅'])stock_obj.save()if created:messages.success(request, f'成功添加股票 {symbol}({stock_row["名称"]})')else:messages.success(request, f'成功更新股票 {symbol} 的信息')except Exception as e:messages.error(request, f'添加股票时出错: {str(e)}\n建议:\n1. 检查股票代码格式\n2. 确保网络连接正常')return redirect('stock_list')def remove_stock(request, symbol):try:stock = Stock.objects.get(symbol=symbol)stock.delete()messages.success(request, f'已删除股票 {symbol}')except Stock.DoesNotExist:messages.error(request, f'找不到股票 {symbol}')return redirect('stock_list')def update_prices(request):success_count = 0error_count = 0stocks = Stock.objects.all()try:# 获取所有A股实时行情stock_info = ak.stock_zh_a_spot_em()for stock in stocks:try:# 处理股票代码格式if stock.symbol.endswith('.SZ'):code = stock.symbol.replace('.SZ', '')elif stock.symbol.endswith('.SS'):code = stock.symbol.replace('.SS', '')else:code = stock.symbol# 查找对应的股票数据stock_data = stock_info[stock_info['代码'] == code]if not stock_data.empty:stock_row = stock_data.iloc[0]stock.current_price = float(stock_row['最新价'])stock.change_percent = float(stock_row['涨跌幅'])stock.save()success_count += 1else:error_count += 1except:error_count += 1continueexcept Exception as e:messages.error(request, f'更新价格时出错: {str(e)}')return redirect('stock_list')if success_count > 0:messages.success(request, f'成功更新 {success_count} 支股票的价格')if error_count > 0:messages.warning(request, f'有 {error_count} 支股票更新失败')return redirect('stock_list')
stocks\urls.py
from django.urls import path
from . import viewsurlpatterns = [path('', views.stock_list, name='stock_list'),path('add/', views.add_stock, name='add_stock'),path('remove/<str:symbol>/', views.remove_stock, name='remove_stock'),path('update/', views.update_prices, name='update_prices'),
]
stocks\templates\stocks\stock_list.html
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>自选股票</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body><div class="container mt-4"><h1 class="mb-4">我的自选股票</h1>{% if messages %}<div class="messages">{% for message in messages %}<div class="alert alert-{{ message.tags }}">{{ message }}</div>{% endfor %}</div>{% endif %}<!-- 添加新股票的表单 --><div class="card mb-4"><div class="card-body"><h5 class="card-title">添加新股票</h5><form method="post" action="{% url 'add_stock' %}" class="row g-3">{% csrf_token %}<div class="col-auto"><input type="text" name="symbol" class="form-control" placeholder="输入股票代码" required></div><div class="col-auto"><button type="submit" class="btn btn-primary">添加</button></div></form></div></div><!-- 股票列表 --><div class="card"><div class="card-body"><div class="d-flex justify-content-between align-items-center mb-3"><h5 class="card-title">股票列表</h5><a href="{% url 'update_prices' %}" class="btn btn-success">更新价格</a></div>{% if stocks %}<div class="table-responsive"><table class="table table-hover"><thead><tr><th>代码</th><th>名称</th><th>当前价格</th><th>涨跌幅</th><th>最后更新</th><th>操作</th></tr></thead><tbody>{% for stock in stocks %}<tr><td>{{ stock.symbol }}</td><td>{{ stock.name }}</td><td>{{ stock.current_price }}</td><td class="{% if stock.change_percent > 0 %}text-success{% elif stock.change_percent < 0 %}text-danger{% endif %}">{{ stock.change_percent|floatformat:2 }}%</td><td>{{ stock.last_updated|date:"Y-m-d H:i:s" }}</td><td><a href="{% url 'remove_stock' stock.symbol %}" class="btn btn-danger btn-sm" onclick="return confirm('确定要删除这支股票吗?')">删除</a></td></tr>{% endfor %}</tbody></table></div>{% else %}<p class="text-center">暂无自选股票,请添加。</p>{% endif %}</div></div></div><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
stock_tracker\urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('stocks.urls')),
]
stock_tracker\settings.py
INSTALLED_APPS = [。。。'stocks',
]LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'USE_I18N = TrueUSE_TZ = True
AKShare 使用说明
AKShare 是一个优秀的开源财经数据接口库,用于获取中国金融市场数据。本项目主要使用其 A 股数据接口。
安装方法
pip install akshare
基本使用
import akshare as ak
A股数据获取
1. 实时行情数据
获取所有 A 股实时行情数据:
# 获取所有A股实时行情
stock_info = ak.stock_zh_a_spot_em()# 返回的数据包含以下字段:
# - 代码: 股票代码
# - 名称: 股票名称
# - 最新价: 当前价格
# - 涨跌幅: 涨跌百分比
# - 涨跌额: 价格变动
# - 成交量: 成交股数
# - 成交额: 成交金额
# - 振幅: 价格振幅
# - 最高: 最高价
# - 最低: 最低价
# - 今开: 开盘价
# - 昨收: 昨日收盘价
2. 个股历史数据
获取单个股票的历史数据:
# 获取股票历史数据
stock_history = ak.stock_zh_a_hist(symbol="000001", period="daily", start_date="20240101", end_date="20240110")# 参数说明:
# - symbol: 股票代码(不带市场后缀)
# - period: 周期(daily-日线,weekly-周线,monthly-月线)
# - start_date: 开始日期
# - end_date: 结束日期
3. 股票基本信息
获取股票的基本信息:
# 获取股票基本信息
stock_info = ak.stock_individual_info_em(symbol="000001")# 返回数据包含:
# - 股票代码
# - 股票简称
# - 行业
# - 总市值
# - 流通市值
# - 等基本面信息
本项目中的使用
在本项目中,我们主要使用了以下功能:
- 获取实时行情:
# 从 views.py 中的实现
def add_stock(request):# 获取实时行情数据stock_info = ak.stock_zh_a_spot_em()# 查找特定股票stock_data = stock_info[stock_info['代码'] == code]if not stock_data.empty:# 获取股票信息stock_row = stock_data.iloc[0]current_price = float(stock_row['最新价'])change_percent = float(stock_row['涨跌幅'])
- 批量更新价格:
# 从 views.py 中的实现
def update_prices(request):# 一次获取所有A股数据stock_info = ak.stock_zh_a_spot_em()for stock in stocks:# 查找对应的股票数据stock_data = stock_info[stock_info['代码'] == code]if not stock_data.empty:# 更新价格信息stock_row = stock_data.iloc[0]stock.current_price = float(stock_row['最新价'])stock.change_percent = float(stock_row['涨跌幅'])
注意事项
- 数据限制:
-
- 接口访问可能有频率限制
- 建议适当控制请求频率
- 考虑数据缓存机制
- 代码格式:
-
- A股代码格式:6位数字
- 上证股票以 6 开头
- 深证股票以 0 或 3 开头
- 错误处理:
-
- 注意处理网络异常
- 处理数据为空的情况
- 处理数值转换异常
常见问题
- 数据获取失败:
-
- 检查网络连接
- 确认股票代码格式
- 查看是否触发频率限制
- 数据不准确:
-
- 确认是否在交易时间
- 检查数据更新时间
- 验证股票代码正确性
相关资源
- AKShare 官方文档
- GitHub 仓库
- AKShare 使用教程
更新记录
- 2024-01-10: 首次创建文档
- 使用 akshare 1.15.68 版本
- 主要实现 A 股实时数据获取功能
相关文章:

做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)
图: 股票自选助手 这是一个基于 Django 开发的 A 股自选股票信息查看系统。系统使用 akshare 库获取实时股票数据,支持添加、删除和更新股票信息。 功能特点 支持添加自选股票实时显示股票价格和涨跌幅一键更新所有股票数据支持删除不需要的股票使用中…...

01、kafka知识点综合
kafka是一个优秀大吞吐消息队列,下面我就从实用的角度来讲讲kafka中,“kafka为何有大吞吐的机制”,“数据不丢失问题”,“精准一次消费问题” 01、kafka的架构组织和运行原理 kafka集群各个节点的名称叫broker,因为kaf…...
怎么用python写个唤醒睡眠电脑的脚本?
环境: win10 python3.12 问题描述: 怎么用python写个唤醒睡眠电脑的脚本? 解决方案: 1.唤醒处于睡眠状态的电脑通常不是通过编程直接实现的,而是依赖于硬件和操作系统提供的特性。对于Windows系统,可…...

【Linux】Linux开发:GDB调试器与Git版本控制工具指南
Linux相关知识点可以通过点击以下链接进行学习一起加油!初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建 在 Linux 开发中,GDB 调试器和 Git 版本控制工具是开发者必备的利器。GDB 帮助快速定位代码问题,G…...
Git 的引用规格(refspec)语法
目录 引用规格语法格式常见用法强制 -f 和 的区别git fetch origin remote-branch:local-branch 和 git push origin local-branch:remote-branch 区别 引用规格语法格式 格式如下:[]<src>:<dst> 常见用法 # fetch git fetch origin <remote-bra…...

反转链表题目
文章目录 反转链表题目链接:[在线OJ](https://leetcode.cn/problems/reverse-linked-list/description/)题目详解思路1:思路1算法复杂度 思路2代码实现思路2算法复杂度 结语 欢迎大家来到我的博客,给生活来点impetus 让我们进入《题海探骊》…...

LED灯按键调光芯片、PWM调光IC、发光灯控制调光芯片
按键调光芯片,特别是LED灯使用PWM调光的芯片IC,是一种用于控制LED灯具亮度的集成电路,常用于台灯、壁灯、吊灯等照明设备中。这种芯片通过脉冲宽度调制(PWM)技术来调节LED的亮度,可以实现从最亮到最暗的平滑…...
Android Room 报错:too many SQL variables (code 1 SQLITE_ERROR) 原因及解决方法
报错信息: android.database.sqlite.SQLiteException: too many SQL variables (code 1 SQLITE_ERROR): while compiling: SELECT * FROM points WHERE id IN (?,?,?,...,?,?,?)SQLiteException: too many SQL variables 通常是由于一次查询或插入的 SQL 语句…...

USA-Entrepreneur-20240708-Business/Unusual
How to Get More Attention You can’t run a great business if you can’t capture people’s attention, says Gary Vaynerchuk. “如果你无法吸引人们的注意力,你就不能经营一家伟大的企业。”——Gary VaynerchukGary Vaynerchuk是一位知名的企业家、作家和公…...

AI算法在目标锁定跟踪领域的利与弊!
AI目标锁定与制导的优点 提高精度和效率: AI算法能够快速准确地分析大量数据,从而改进目标识别和跟踪,提高打击或投放的准确性和效率。 通过深度学习模型,AI可以识别图像中的特征并判断是否存在目标,进一步提取目标…...

移远BC28_opencpu方案_pin脚分配
先上图,BC28模块的pin脚如图所示: 下面看看GPIO的复用管脚 然后我自己整理了一份完整的pin功能列表...

初学stm32 --- II2C_AT24C02,向EEPROM中读写数据
目录 IIC总线协议介绍 IIC总线结构图 IIC协议时序 1. ACK(Acknowledge) 2. NACK(Not Acknowledge) IO口模拟II2C协议 发送起始信号: 发送停止信号: 检测应答信号: 发送应答信号&#x…...

动态规划汇总1
1.动态规划 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,…...

【计算机网络】lab5 ARP协议
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀计算机网络_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...

分布式缓存redis
分布式缓存redis 1 redis单机(单节点)部署缺点 (1)数据丢失问题:redis是内存存储,服务重启可能会丢失数据 (2)并发能力问题:redis单节点(单机)部…...

【Rust】数据类型
目录 思维导图 1. 数据类型概述 1.1 标量类型 1.1.1 整数类型 1.1.2 浮点数类型 1.1.3 布尔类型 1.1.4 字符类型 1.2 复合类型 1.2.1 元组类型 1.2.2 数组类型 2. 类型注解与类型推断 3. 整数溢出处理 4. 数字运算 5. 示例 思维导图 1. 数据类型概述 Rust是一种静…...

在现代工业自动化领域CClinkIE转ModbusTCP网关的应用
在现代工业自动化领域,开疆智能CCLINKIE转ModbusTCP网关扮演着至关重要的角色,尤其是在立体仓库的应用中。立体仓库系统通过高度集成的自动化设备和先进的信息技术,实现了物料存储和管理的高效率。CCLINKIE转ModbusTCP网关作为连接不同工业通…...
ASP.NET Core与GraphQL集成
一、引言:探索 C# 与ASP.NET Core、GraphQL 的协同魅力 在当今数字化浪潮中,Web 开发领域不断演进,新技术层出不穷。C# 作为.NET 平台上的中流砥柱,凭借其强大的功能与优雅的语法,成为众多开发者构建各类应用程序的得…...
Zabbix 从入门到精通
一、Zabbix 简介 1.1 什么是 Zabbix Zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级开源解决方案。它能监控各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位 / 解决存在的各种问题。 1…...
文生图模型的技术原理、训练方案与微调方案
文生图模型的技术原理、训练方案与微调方案 引言 文生图(Text-to-Image)模型是一类能够根据文本描述生成对应图像的深度学习模型。近年来,随着生成对抗网络(GANs)和扩散模型(Diffusion Models)等技术的进步,文生图模型在图像生成领域取得了显著的进展。本文将详细介绍…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...