当前位置: 首页 > news >正文

【爬虫】爬取股票历史K线数据写入数据库(三)

在这里插入图片描述
前几天有写过两篇:
【爬虫】爬取A股数据写入数据库(二)
【爬虫】爬取A股数据写入数据库(一)

现在继续完善,分析及爬取股票的历史K线数据通过ORM形式批量写入数据库。

2024/05,本文主要内容如下:

  1. 对东方财富官网进行分析,并作数据爬取,使用python,使用pip install requests 模拟http数据请求,获取数据。
  2. 将爬取的数据写入通过 sqlalchemy ORM 写入 sqlite数据库。
  3. 记录爬取股票的基本信息,如果库中已存在某个股票代码,则进行更新。
  4. 后续计划:会不断完善,最终目标是做出一个简单的股票查看客户端。
  5. 本系列所有源码均无偿分享,仅作交流无其他,供大家参考。
    python依赖环境如下:
pip install requests==2.31.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pandas==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install jsonpath==0.8.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install sqlalchemy==2.0.30 -i https://pypi.tuna.tsinghua.edu.cn/simple

1. 对东方财富官网历史K线数据分析

网页地址:https://quote.eastmoney.com/sz002224.html?jump_to_web=true#fullScreenChart
通过分析网页,发现https://push2his.eastmoney.com/api/qt/stock/kline/get?请求后面带着一些参数即可以获取到相应数据,我们不断调试,模拟这类请求即可。分析过程如下图所示,F12调出调试框,不断尝试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 爬取数据代码逻辑

如下即爬取数据的可运行代码,复制后直接能跑:

import pandas as pd
from typing import List
import requests
from jsonpath import jsonpathclass CustomedSession(requests.Session):def request(self, *args, **kwargs):kwargs.setdefault('timeout', 60)return super(CustomedSession, self).request(*args, **kwargs)
session = CustomedSession()
adapter = requests.adapters.HTTPAdapter(pool_connections = 50, pool_maxsize = 50, max_retries = 5)
session.mount('http://', adapter)
session.mount('https://', adapter)# 请求地址
QEURY_URL = 'http://push2his.eastmoney.com/api/qt/stock/kline/get'
# HTTP 请求头
EASTMONEY_REQUEST_HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko','Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
}"""
获取单只股票的历史K线数据
"""
def get_k_history_data(stock_codes: str, # 股票代码beg: str = '19000101', # 开始日期,19000101,表示 1900年1月1日end: str = '20500101', # 结束日期klt: int = 101,  # 行情之间的时间间隔 1、5、15、30、60分钟; 101:日; 102:周; 103:月fqt: int = 1, # 复权方式,0 不复权 1 前复权 2 后复权
):try:# 生成东方财富专用的secidif stock_codes[:3] == '000':   # 沪市指数secid = f'1.{stock_codes}'elif stock_codes[:3] == '399': # 深证指数secid = f'0.{stock_codes}'if stock_codes[0] != '6':  # 沪市股票secid = f'0.{stock_codes}'else:secid = f'1.{stock_codes}' # 深市股票EASTMONEY_KLINE_FIELDS = {'f51': '日期', 'f52': '开盘', 'f53': '收盘', 'f54': '最高', 'f55': '最低','f56': '成交量', 'f57': '成交额', 'f58': '振幅', 'f59': '涨跌幅', 'f60': '涨跌额', 'f61': '换手率',}fields = list(EASTMONEY_KLINE_FIELDS.keys())# columns = list(EASTMONEY_KLINE_FIELDS.values())fields2 = ",".join(fields)params = (('fields1', 'f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13'),('fields2', fields2),('beg', beg),('end', end),('rtntype', '6'),('secid', secid),('klt', f'{klt}'),('fqt', f'{fqt}'),)code = secid.split('.')[-1]json_response = session.get(QEURY_URL, headers=EASTMONEY_REQUEST_HEADERS, params=params, verify=False).json()data_list = []klines: List[str] = jsonpath(json_response, '$..klines[:]')if not klines:return data_listname = json_response['data']['name']rows = [kline.split(',') for kline in klines]# 0           1      2     3      4      5        6           7        8        9       10# 日期,       开盘,   收盘, 最高,  最低,   成交量,  成交额,      振幅,    涨跌幅,   涨跌额, 换手率# 2024-05-08, 4.89,  4.82, 4.91,  4.80,  61811,  29955564.00,  2.25,  -1.23,    -0.06,  0.98# data_list = [{'code': '002224', 'name': '三力士', 'time': '2024-05-08', 'info': '0,1,2,3,4,5,6,7,8,9,10'}]for row in rows:time, open, close, high, low, vol, quota, mm, change, range, tun = rowline_str = f'{open},{close},{high},{low},{vol},{quota},{mm},{change},{range},{tun}'data_list.append({'id': None,'code': code, 'name': name, 'time': time, 'info': line_str})return data_listexcept Exception as e:print('get_k_history_data error-----------------------', str(e))return data_listif __name__ == "__main__":data = get_k_history_data(stock_codes='002224', beg='20240507', end='20500101')print('----', data)

3. 将爬取的数据通过ORM形式写入数据库

数据库表设计:

from sqlalchemy import create_engine, Column, Integer, String, DateTime, Float, Index, Table
from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session
from sqlalchemy.schema import UniqueConstraint
from datetime import datetime# 声明一个基类,所有的ORM类都将继承自这个基类
DBBase = declarative_base()# 创建引擎
engine = create_engine('sqlite:///a.db',  echo=False)
# 绑定引擎
Session = sessionmaker(bind=engine)
# 创建数据库链接池,直接使用session即可为当前线程拿出一个链接对象conn
db_session = scoped_session(Session)'''
股票K线信息表
0           1      2     3      4      5        6           7        8        9       10
日期,       开盘,   收盘, 最高,  最低,   成交量,  成交额,      振幅,    涨跌幅,   涨跌额, 换手率
2024-05-08, 4.89,  4.82, 4.91,  4.80,  61811,  29955564.00,  2.25,  -1.23,    -0.06,  0.98
data_list = [{'code': '002224', 'name': '三力士', 'time': '2024-05-08', 'info': '1,2,3,4,5,6,7,8,9,10'}]
'''
class tb_k(DBBase):__tablename__ = 'tb_k'id = Column(Integer, primary_key=True, autoincrement=True)code = Column(String, nullable=False, comment="股票代码")name = Column(String, comment="股票名称")time = Column(String, comment="时间")info = Column(String, comment="开盘,收盘,最高,最低,成交量,成交额,振幅,涨跌幅,涨跌额,换手率")__table_args__ = (Index('unique_index', 'code', 'time', unique=True),)
# 创建表, 创建所有class xx(DBBase)
DBBase.metadata.create_all(engine)

写入数据库的逻辑:

# 查询某个股票最近更新K线的日期
def query_latast_K_data(code):result = db_session.query(tb_k).filter(tb_k.code==code).order_by(desc(tb_k.time)).first()if result is None:return '19000101'return str(result.time).replace('-','')# 批量插入或更新某只股票的历史K线数据
def insert_or_update_stock_k(data_list):if len(data_list) <= 0:returntry:db_session.bulk_insert_mappings(tb_k, data_list)db_session.commit()except Exception as e:print('insert_or_update_stock_k error=', str(e))

4. 整体逻辑流程

步骤:

  1. 输入某个股票代码爬取该股票的历史K线数据
  2. 将返回结果组成数组,批量写入数据库
  3. 每次写入前,会根据该股票代码,查询最新的同步日期,从该日期开始进行追加同步
# 更新某个股票的最新日K线数据到数据库
def update_k_info_db(code='002224'):# 根据 code 查询库中已存在的某个股票日K线数据的最近日期,作为开始日期,向后获取beg_time = db_orm.query_latast_K_data(code)data_list = stock.get_k_history_data(stock_codes=code, beg=beg_time, end='20500101')if len(data_list) > 0:db_orm.insert_or_update_stock_k(data_list)if __name__ == "__main__":update_base_info_db()

最终结果保存在 a.db中,例如:
在这里插入图片描述
更多内容可关注我,后续源码包均在上面回复下载:
【爬虫】爬取A股数据系列工具

相关文章:

【爬虫】爬取股票历史K线数据写入数据库(三)

前几天有写过两篇&#xff1a; 【爬虫】爬取A股数据写入数据库&#xff08;二&#xff09; 【爬虫】爬取A股数据写入数据库&#xff08;一&#xff09; 现在继续完善&#xff0c;分析及爬取股票的历史K线数据通过ORM形式批量写入数据库。 2024/05&#xff0c;本文主要内容如下…...

文心一言指令

文心一言&#xff08;ERNIE Bot&#xff09;是百度公司开发的人工智能语言模型&#xff0c;它可以接收各种指令来执行不同的任务。以下是一些可能的指令示例&#xff1a; 知识问答&#xff1a; 指令&#xff1a;“请问什么是人工智能&#xff1f;”文心一言会回答关于人工智能…...

常用的命令技巧总结

java命令执行 如下编码网站&#xff1a; Runtime.exec Payload Generater | AresXs Blogjava.lang.Runtime.exec() Payload Workarounds - Jackson_Thttps://www.bugku.net/runtime-exec-payloads/ 手动编码操作 bash -c {echo,cGluZyAxMjcuMC4wLjE7ZWNobyAxID50ZXN0LnR4dA}|…...

T97燃脂咖啡招商模式,私域分销模式设计

t97燃脂咖啡招商模式&#xff0c;希柔T97微商模式&#xff0c;社交电商系统 ​坐标&#xff1a;厦门&#xff0c;我是易创客肖琳 深耕社交新零售行业10年&#xff0c;主要提供新零售系统工具及顶层商业模式设计、全案策划运营陪跑等。 低卡咖啡第一品牌“T97”&#xff0c;突然…...

触摸OpenNJet,感悟云原生

小程一言 云原生使得应用充分利用云计算、容器化和微服务架构等现代技术来构建和运行应用程序。 云原生技术的用处在于提高应用程序的可靠性、可伸缩性和灵活性&#xff0c;加快开发和部署速度&#xff0c;降低成本&#xff0c;提升整体的效率和竞争力。通过采用云原生技术&a…...

UE4 自定义shader获取灯光位置

UE4.26:How to get the direction of specific directional lights in custom node material? - #4 by Arkiras - Rendering - Epic Developer Community Forums 获取灯光位置的shader&#xff0c;应该是这个了...

机器学习(五) ----------决策树算法

目录 1 核心思想 2 决策树算法主要步骤 3 决策树算法的分类 3.1 ID3算法&#xff08;Iterative Dichotomiser 3&#xff09;&#xff1a; 3.1.1 基本步骤 3.1.2 原理 信息增益 3.1.3 注意事项 3.2 C4.5算法&#xff1a; 3.2.1. 信息增益率 计算公式 3.2.2. 构建决策…...

Redis的数据完全是存在内存中的吗?

是的&#xff0c;Redis的数据完全是存储在内存中的。这也是Redis能够提供非常高速的读写性能的主要原因&#xff0c;尤其适用于需要快速响应的应用场景。然而&#xff0c;虽然Redis将所有数据存储在内存中&#xff0c;但它也提供了持久化机制&#xff0c;可以将数据异步地保存到…...

Linux开发--Linux设备驱动核心

Author: cpu_codeDate: 2020-06-30 16:15:35LastEditTime: 2020-07-01 17:59:23FilePath: \md\Linux\6818_Linux驱动.mdGitee: https://gitee.com/cpu_codeCSDN: https://blog.csdn.net/qq_44226094 Linux设备驱动核心概念 Linux内核中断处理 Linux操作系统下同裸机程序一样…...

vue3引入vant完整步骤

在Vue 3中引入Vant&#xff08;一个基于Vue的移动端UI组件库&#xff09;的完整步骤通常包括以下几个部分&#xff1a; 安装Vue CLI&#xff08;如果你还没有安装的话&#xff09;&#xff1a; npm install -g vue/cli 创建一个新的Vue项目&#xff1a; 假设你希望项目名为my…...

C语言——文件缓冲区

一、用户缓冲区和系统缓冲区 缓冲区的概念确实可以分为多个层次&#xff0c;其中最常见的两个层次是用户缓冲区和系统缓冲区。 这里的用户缓冲区和系统缓冲区都包括输入输出缓冲区。 1、用户缓冲区&#xff08;User-space Buffer&#xff09; 用户缓冲区是指由用户程序&…...

如何快速检测原理图中的元器件与PLM系统的一致性,提高原理图设计准确性

背景介绍 保证原理图中的元器件来源于公司的PLM系统、ERP系统的&#xff0c;是输出有效BOM的根源&#xff0c;初始BOM的准确率&#xff0c;能大大降低ECN的数量&#xff0c;提高生产备料的时效&#xff0c;缩短采购周期。 然而&#xff0c;原理图设计过程中&#xff0c;由于…...

英特尔处理器排行

英特尔的处理器性能排行通常是根据其发布的不同代数和型号来划分的&#xff0c;以下是一些高性能的英特尔处理器&#xff1a; Intel 酷睿 i9 14900K&#xff1a;这是目前英特尔桌面平台中的旗舰处理器之一&#xff0c;提供了极高的性能&#xff0c;适合高端游戏和专业工作负载…...

【日志革新】在ThinkPHP5中实现高效TraceId集成,打造可靠的日志追踪系统

问题背景 最近接手了一个骨灰级的项目&#xff0c;然而在项目中遇到了一个普遍的挑战&#xff1a;由于公司采用 ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;作为日志收集和分析工具&#xff0c;追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功…...

英译汉早操练-(二十)

hello大家好&#xff0c;这篇跟随十九&#xff0c;继续真题学习。如果想看全部请返回到第十九篇。 英译汉早操练-&#xff08;十九&#xff09;-CSDN博客 The political upheaval in Libya and elsewhere in North Africa has opened the way for thousands of new migrants to…...

Go-Zero自定义goctl实战:定制化模板,加速你的微服务开发效率(四)

前言 上一篇文章带你实现了Go-Zero和goctl&#xff1a;解锁微服务开发的神器&#xff0c;快速上手指南&#xff0c;本文将继续深入探讨Go-Zero的强大之处&#xff0c;并介绍如何使用goctl工具实现模板定制化&#xff0c;并根据实际项目业务需求进行模板定制化实现。 通过本文…...

(五)STM32F407 cubemx IIC驱动OLED(1)IIC协议篇

&#xff08;五&#xff09;STM32F407 cubemx IIC驱动OLED&#xff08;1&#xff09;IIC协议篇 这篇文章主要是个人的学习经验&#xff0c;想分享出来供大家提供思路&#xff0c;如果其中有不足之处请批评指正哈。   废话不多说直接开始主题&#xff0c;本人是基于STM32F407V…...

OpenCV特征匹配总结

1.概述 在深度学习出现之前&#xff0c;图像中的特征匹配方法主要有 2.理论对比 3.代码实现 #include <iostream> #include <opencv2/opencv.hpp>int main(int argc, char** argv) {if(argc ! 3) {std::cerr << "Usage: " << argv[0] <…...

二叉树的四种遍历代码实现

二叉树的遍历大致能分为以下几种 1.前序&#xff1a;根 左 右 2.中序&#xff1a;左 根 右 3.后序&#xff1a;左 右 根 4.层序&#xff1a;从根开始一层一层的向下 如上图访问顺序: 前序&#xff1a;1 2 3 N N N 4 5 N N 6 N N 中序&#xff1a;N 3 N 2 N 1 N 5 N 4 N …...

系统和功能测试:确保软件的功能和易用性

目录 概述 功能测试 LOSED 模型 用例的设计 等价类划分 边界值分析 循环结构测试的综合方法 因果图 决策表 功能图 正交实验设计 易用性测试 内部易用性测试 外部易用性测试 功能性测试 正向功能性测试 负向功能性测试 功能性测试工具 结语 概述 在软件开发…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...