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

[白月黑羽]关于仿写股票数据软件题目的解答

原题:

在这里插入图片描述
对应问题视频:
在这里插入图片描述

实现的效果

请添加图片描述

不同点

实现的作品和原题要求的不同点

  1. 题目要求爬虫获取数据,作品中是调库获取所有股票历史数据
  2. 实时数据使用爬虫的方式爬取指定股票的数据,需要实时更新,我做了修改,改成按下按钮获取分时数据,不自动刷新

体会

  1. 先AKShare获取数据,总是被封IP,后改用证券宝
  2. 股票当天分时数据不好获得,这个数据是由服务器主动推送过来的,通过监听所有的收发包数据,找到了这个规律才获得数据

解答:

# python版本要3.9以上akshare才可以获取所有股票数据
# 去掉AKShare改用证券宝接口import pyqtgraph as pg
import baostock as bs
import pandas as pd
import re
import numpy as np
import json
import traceback
from threading import  Thread
from PySide6 import QtWidgets,QtCore,QtGui
from datetime import datetime
from time import sleep
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.chrome.options import Options
from datetime import datetime#数据源接口
class StockData:@staticmethoddef get_all_stock_code() -> pd.DataFrame:# 证券宝接口lg = bs.login()# 显示登陆返回信息#print('login respond error_code:'+lg.error_code)#print('login respond  error_msg:'+lg.error_msg)yesterday= (datetime.now() - pd.Timedelta(days=1)).strftime('%Y-%m-%d')three_months_ago = (datetime.now() - pd.Timedelta(days=90)).strftime('%Y-%m-%d')#### 获取交易日信息 ####rs = bs.query_trade_dates(start_date=three_months_ago, end_date=yesterday)#print('query_trade_dates respond error_code:'+rs.error_code)#print('query_trade_dates respond  error_msg:'+rs.error_msg)if rs.error_code!= '0':bs.logout()return Nonedata_list = []while (rs.error_code == '0') & rs.next():# 获取一条记录,将记录合并在一起data_list.append(rs.get_row_data())result = pd.DataFrame(data_list, columns=rs.fields)#从后面开始查找,找到一行is_trading_day=1的日期trading_days = result[result['is_trading_day']=='1']if trading_days.empty:print('没有交易日数据')bs.logout()return Nonelast_trading_day = trading_days.iloc[-1]['calendar_date']#print(str(last_trading_day) + str(type(last_trading_day)))#获取所有股票代码#### 获取某日所有证券信息 ####rs = bs.query_all_stock(day=str(last_trading_day))#print('query_all_stock respond error_code:'+rs.error_code)#print('query_all_stock respond  error_msg:'+rs.error_msg)#### 打印结果集 ####data_list = []while (rs.error_code == '0') & rs.next():# 获取一条记录,将记录合并在一起data_list.append(rs.get_row_data())result = pd.DataFrame(data_list, columns=rs.fields)#只保留sz.00开头的,sh.60开头的沪深正股数据result = result[(result['code'].str.startswith('sz.00')) | (result['code'].str.startswith('sh.60'))]#去掉index列#result.drop(columns=['index'], inplace=True)#panda复制code列,重命名为bs_coderesult['bs_code'] = result['code']#重命名code_name 为nameresult.rename(columns={'code_name':'name'}, inplace=True)#将code列前面的sz.或者sh.去掉result['code'] = result['code'].str.replace('sz.', '')result['code'] = result['code'].str.replace('sh.', '')#排序result['sort'] = result['code'].astype(int)result.sort_values(by='sort', inplace=True)result.drop(columns=['sort'], inplace=True)#重置索引result.reset_index(drop=True, inplace=True)#print(result)#### 登出系统 ####bs.logout()return result@staticmethoddef get_history_data(code:str, start_date:str, end_date:str) -> pd.DataFrame:# 证券宝接口lg = bs.login()if lg.error_code != '0':print('证券宝登录失败')return None#### 获取历史行情 ####rs = bs.query_history_k_data_plus(code,"date,code,open,close",start_date=start_date, end_date=end_date, frequency="d", adjustflag="2") #frequency="d"取日k线,adjustflag="3"默认不复权#print('query_history_k_data_plus respond error_code:'+rs.error_code)#print('query_history_k_data_plus respond  error_msg:'+rs.error_msg)#### 打印结果集 ####data_list = []while (rs.error_code == '0') & rs.next():# 获取一条记录,将记录合并在一起data_list.append(rs.get_row_data())result = pd.DataFrame(data_list, columns=rs.fields)if(result.empty):my_signal.warning_signal.emit('没有查询到数据')bs.logout()return None#修改列类型result['open'] = result['open'].astype(float)result['close'] = result['close'].astype(float)#### 登出系统 ####bs.logout()return result@staticmethoddef get_realtime_data(code:str) -> pd.DataFrame:# 先去掉所有非数字的字符,留下来六位数字str,对code进行处理,如果以60开头,添加sh前缀,如果以00开头,添加sz前缀code = ''.join(char for char in code if char.isdigit())if len(code)!= 6:return Noneif code.startswith('60'):code = 'sh' + codeelif code.startswith('00'):code ='sz' + codeprint(code)options = Options()result_df = pd.DataFrame(columns=['time','price'])caps = {"browserName": "chrome",'goog:loggingPrefs': {'performance': 'ALL'}  # 开启日志性能监听}# 将caps添加到options中for key, value in caps.items():options.set_capability(key, value)options.add_argument('--headless')  # 无头模式# 启动浏览器driver = webdriver.Chrome(options=options)url = f"https://quote.eastmoney.com/concept/{code}.html"print(url)driver.get(url)sleep(3)  # wait for the requests to take place# extract requests from logslogs_raw = driver.get_log("performance")logs = [json.loads(lr["message"])["message"] for lr in logs_raw]def log_filter(log_):return (# is an actual responselog_["method"] == "Network.eventSourceMessageReceived")for log in filter(log_filter, logs):try:#判断log中params是否存在,且params中是否存在dataif 'params' not in log or 'data' not in log['params']:continuedata = json.loads(log['params']['data'])#先判断data是否存在,且data->trends是否存在if 'data' not in data or 'trends' not in data['data']:continuedata = data['data']['trends']#判断data是否是listif isinstance(data, list):for item in data:arr =item.split(',')t = datetime.strptime(str(arr[0]),"%Y-%m-%d %H:%M")#判断时间是否在9:30-11:30 13:00-15:00之间if (t.hour <= 9 and t.minute < 30):continueif(t.hour >= 15 and t.minute > 0):continueif(t.hour == 12):continueif(t.hour == 11 and t.minute > 30):continue#双重保险if (t.hour >= 9 and t.minute >= 30) or (t.hour >= 10) :avg = round((float(arr[1]) + float(arr[2]))/2,2)new_row = pd.DataFrame([[t,avg]],columns=['time','price'],index=[0])if result_df.empty:result_df = new_rowelse:result_df = pd.concat([result_df, new_row],ignore_index=True)except Exception  as e:print(log)print(traceback.print_exc())passdriver.quit()#print(result_df)if result_df.empty:return Nonereturn result_df#信号库
class MySignal(QtCore.QObject):combox_update_signal = QtCore.Signal()history_area_data_signal = QtCore.Signal()realtime_area_data_signal = QtCore.Signal()warning_signal = QtCore.Signal(str)
#    start_timer_signal = QtCore.Signal()
#    Stop_timer_signal = QtCore.Signal()
#信号的实例化
my_signal = MySignal()#主界面
class MainWindow(QtWidgets.QWidget):def __init__(self):super().__init__()# 数据,用panda处理self.stock_code_df : pd.DataFrame  = None #股票代号数据self.history_data_df : pd.DataFrame = None #历史行情数据self.realtime_data_df : pd.DataFrame = None #实时行情数据self.today_data_df : pd.DataFrame = None #今日行情数据# 界面布局self.setWindowTitle('股票行情查看软件')self.combox = QtWidgets.QComboBox(self)self.search_btn = QtWidgets.QPushButton('同步股票清单', self)self.is_searching_stock_code = Falseself.search_edit = QtWidgets.QLineEdit(self)self.search_edit.setStyleSheet("QLineEdit { border: 1px solid #888888; }")self.tab_widget = QtWidgets.QTabWidget(self)self.history_page = QtWidgets.QWidget(self)self.realtime_page = QtWidgets.QWidget(self)self.tab_widget.addTab(self.history_page, '历史行情')self.tab_widget.addTab(self.realtime_page, '实时行情')self.layout = QtWidgets.QVBoxLayout(self)# 头部,查询股票代码布局self.header_layout = QtWidgets.QHBoxLayout()self.header_layout.addSpacing(20)self.header_layout.addWidget(self.search_btn)self.header_layout.setStretchFactor(self.search_btn,1)self.header_layout.addSpacing(20)self.search_label = QtWidgets.QLabel('请输入股票名称或代码')self.search_label.setAlignment(QtCore.Qt.AlignCenter)self.header_layout.addWidget(self.search_label)self.header_layout.setStretchFactor(self.search_label,0)self.header_layout.addSpacing(20)self.header_layout.addWidget(self.search_edit)self.header_layout.addSpacing(1)self.header_layout.addWidget(self.combox)self.header_layout.setStretchFactor(self.search_edit,2)self.header_layout.setStretchFactor(self.combox,3)self.search_edit.textChanged.connect(self.search_edit_cb)self.layout.addLayout(self.header_layout)self.layout.addWidget(self.tab_widget)self.text_label = QtWidgets.QLabel(self)self.layout.addWidget(self.text_label)# 历史行情页面布局self.history_page_layout = QtWidgets.QVBoxLayout(self.history_page)self.history_layout = QtWidgets.QHBoxLayout()self.history_page_layout.addLayout(self.history_layout)self.edit_area = QtWidgets.QTextEdit(self)self.history_page_layout.addWidget(self.edit_area)self.history_plot = pg.PlotWidget()self.history_page_layout.addWidget(self.history_plot)self.history_page_layout.setStretchFactor(self.edit_area,1)self.history_page_layout.setStretchFactor(self.history_plot,2)self.history_btn = QtWidgets.QPushButton('历史行情', self)self.date_edit_start = QtWidgets.QDateEdit(self)self.date_edit_start.setCalendarPopup(True)self.date_edit_start.setDisplayFormat("yyyy-MM-dd")self.date_edit_start.setAlignment(QtCore.Qt.AlignCenter)self.date_edit_start.setDate(QtCore.QDate.currentDate().addYears(-3))self.date_edit_end = QtWidgets.QDateEdit(self)self.date_edit_end.setCalendarPopup(True)self.date_edit_end.setDisplayFormat("yyyy-MM-dd")self.date_edit_end.setAlignment(QtCore.Qt.AlignCenter)self.date_edit_end.setDate(QtCore.QDate.currentDate())self.history_layout.addWidget(QtWidgets.QLabel('时间范围'),1,QtCore.Qt.AlignLeft)self.history_layout.addWidget(self.date_edit_start,2)self.history_layout.addWidget(QtWidgets.QLabel(' - '),0,QtCore.Qt.AlignCenter)self.history_layout.addWidget(self.date_edit_end,2)self.history_layout.addWidget(self.history_btn,1,QtCore.Qt.AlignRight)self.history_curve = None # 历史行情图的曲线self.history_vertical_line = None # 历史行情图的垂直线self.history_horizontal_line = None #历史行情图的水平线self.is_searching_history_data = False# 实时行情页面布局self.realtime_btn = QtWidgets.QPushButton('实时行情', self)self.realtime_page_layout = QtWidgets.QVBoxLayout(self.realtime_page)self.realtime_page_layout.addWidget(self.realtime_btn)self.realtime_plot = pg.PlotWidget(self)self.realtime_page_layout.addWidget(self.realtime_plot)self.realtime_curve = None # 实时行情图的曲线self.realtime_vertical_line = None # 实时行情图的垂直线self.realtime_horizontal_line = None #实时行情图的水平线self.is_searching_realtime_data = False# 初始化数据worker = Thread(target=self.init_data_thread_func)worker.start()# 信号连接my_signal.combox_update_signal.connect(self.combox_update_cb)my_signal.history_area_data_signal.connect(self.history_data_cb)my_signal.realtime_area_data_signal.connect(self.realtime_data_cb)my_signal.warning_signal.connect(self.warning_cb)self.history_plot.scene().sigMouseMoved.connect(self.history_plot_mouse_move_cb)self.realtime_plot.scene().sigMouseMoved.connect(self.realtime_plot_mouse_move_cb)self.history_btn.clicked.connect(self.history_btn_cb)self.realtime_btn.clicked.connect(self.realtime_btn_cb)self.search_btn.clicked.connect(self.search_btn_cb)self.tab_widget.tabBarClicked.connect(self.tab_widget_cb)#   定时器 不使用#self.realtime_timer = QtCore.QTimer()#self.realtime_timer.timeout.connect(self.timer_timeout_cb)# 数据加载另外起个线程def init_data_thread_func(self):# 加载本地股票代号数据,数据为CSV格式,使用panda读取# 如果文件不存在,则跳过try:self.stock_code_df = pd.read_csv('stock_symbol.csv',encoding='utf-8',dtype={'code':str,'tradeStatus':str})# 启动初始化加载到comboxself.add_item_to_combox(self.stock_code_df) #这段代码是临时数据TODO 加载本地历史行情数据,数据为CSV格式,使用panda读取,该数据为测试数据#self.history_data_df = pd.read_csv('temp_history_data.csv',encoding='utf-8')#self.history_data_df['日期'] = pd.to_datetime(self.history_data_df['日期'],format='%Y-%m-%d')# 临时加载实时数据#self.realtime_data_df = pd.read_csv('temp_realtime_data.csv',encoding='utf-8')#self.realtime_data_df['时间'] = pd.to_datetime(self.realtime_data_df['时间'],format='%Y-%m-%d %H:%M:%S')except FileNotFoundError:print('股票代号数据文件不存在')passexcept Exception as e:print('其他错误' + str(e))passdef add_item_to_combox(self, df : pd.DataFrame):self.combox.clear()temp = None#加载df前20个数据到combox,如果不到20个则加载全部if df.shape[0] > 20:temp = df.head(20)else:temp = dffor index, row in temp.iterrows():self.combox.addItem(row['code'] + "(" + row['name'] + ")")my_signal.combox_update_signal.emit()def combox_update_cb(self):self.combox.setCurrentIndex(0)# 查询历史行情的btn回调def history_btn_cb(self):def history_thread_func():text = self.combox.currentText()match = re.search(r'\d{6}', text)start_time_str = self.date_edit_start.date().toString('yyyy-MM-dd')end_time_str = self.date_edit_end.date().toString('yyyy-MM-dd')if match:code = str(match.group())#翻译为证券宝格式temp = self.stock_code_df[self.stock_code_df['code'] == code]if temp is None or temp.shape[0] == 0:my_signal.warning_signal.emit('股票代码错误')self.is_searching_history_data = Falsebs_code = temp.iloc[0]['bs_code']self.history_data_df = StockData.get_history_data(code=bs_code, start_date=start_time_str, end_date=end_time_str)if self.history_data_df is not None:my_signal.history_area_data_signal.emit()self.is_searching_history_data = Falsereturnif self.is_searching_history_data:returnself.is_searching_history_data = Trueworker = Thread(target=history_thread_func)worker.start()return# 历史行情图绘制def history_data_cb(self):self.edit_area.setText(self.history_data_df.to_string())history_data_df = self.history_data_df.copy()#打印列名和类型#print(history_data_df.columns)history_data_df['avg'] = ((history_data_df['open'] + history_data_df['close'])/2).round(2)# 行号的序号xdata = history_data_df.index.astype(int).to_list()ydata = history_data_df['avg'].astype(float).to_list()self.history_plot.plotItem.setLabel('left', '均价')axis: pg.AxisItem = self.history_plot.getPlotItem().getAxis('bottom')self.history_plot.plotItem.setLabel('bottom', '日期',units='')# x轴刻度变为字符串,可以实现日期的显示 这里费了好多脑子# self.history_plot.getPlotItem().getAxis('bottom').setTicks([[(x, history_data_df.iloc[index]['日期']) #for #index, x  in enumerate(xdata)]])x_ticks_str = [history_data_df.iloc[index]['date'] for index, x in enumerate(xdata)] x_ticks1 = []x_ticks2 = []x_ticks3 = []gap =  (round(len(x_ticks_str)) // 8 + 1 ) # 0 到 7 是 1 ,8到15是 2# 设定 gap为 4 和 2 的倍数 gap = 2 if gap == 3 else gapif gap > 4: # 4 8 12 16 20......gap = (gap + 3) // 4 * 4 x_ticks1 = [(i,x_ticks_str[i])for i in range(0,len(x_ticks_str),gap)]if gap >= 2:x_ticks2 = [(i,x_ticks_str[i])for i in range(0,len(x_ticks_str),gap // 2)]if gap >= 4 :x_ticks3 = [(i,x_ticks_str[i])for i in range(0,len(x_ticks_str),gap // 4)]#去掉x_ticks2奇数个元素,不去掉也行x_ticks2 = x_ticks2[1::2]x_ticks3 = x_ticks3[1::2]#x_ticks3 = [(i,x_ticks_str[i])for i in range(0,len(x_ticks_str),gap // 4)]plot_ticks = [x_ticks1,x_ticks2,x_ticks3]axis.setTicks(plot_ticks)#限制显示范围self.history_plot.plotItem.vb.setLimits(xMin = xdata[0],xMax =xdata[-1] *1.2 ,yMin = min(ydata) -(max(ydata) - min(ydata)) * 0.2 , yMax = max(ydata) +(max(ydata) - min(ydata)) *0.2,minXRange=10, maxXRange= (xdata[-1] - xdata[0]) *1.2,minYRange = 0.1, maxYRange = 1.4*(max(ydata) - min(ydata)))#清除旧的绘制新的if self.history_curve is not None:self.history_plot.removeItem(self.history_curve)self.history_curve = self.history_plot.plotItem.plot(xdata, ydata, pen='w')#历史行情图的鼠标移动事件def history_plot_mouse_move_cb(self,pos):if self.history_data_df is None:returnview_coords = pg.Point(pos)mouse_point  = self.history_plot.getPlotItem().vb.mapSceneToView(view_coords)x = round(mouse_point.x())#保留两位小数temp_df = self.history_data_df.copy()temp_df['avg'] = ((temp_df['open'] + temp_df['close'])/2).round(2)temp_df['temp_index'] = temp_df.index.astype(int)closest_min_idx = (temp_df['temp_index'] - x).abs().idxmin()y_value = temp_df.iloc[closest_min_idx]['avg']#如果历史行情图还没有绘制,则不绘制垂直线,水平线if self.history_curve is not None:self.history_plot.removeItem(self.history_vertical_line)self.history_plot.removeItem(self.history_horizontal_line)self.text_label.setText("价格:" + str(y_value.round(2)) + " 日期:" + temp_df.iloc[closest_min_idx]['date'])self.history_vertical_line = pg.InfiniteLine(pos=closest_min_idx, angle=90, pen='y')self.history_horizontal_line = pg.InfiniteLine(pos=y_value, angle=0, pen='y')self.history_plot.addItem(self.history_horizontal_line)self.history_plot.addItem(self.history_vertical_line)#print(idx,y_value)# 查看实时行情图btn回调def realtime_btn_cb(self):def reset_():self.is_searching_realtime_data = Falseself.realtime_btn.setEnabled(True)def realtime_thread_func():text = self.combox.currentText()match = re.search(r'\d{6}', text)if match:today = QtCore.QDate.currentDate()today_str = today.toString('yyyy-MM-dd')code = str(match.group())realtime_data_df = StockData.get_realtime_data(code=code)#如果获取的价格数据为空,则不更新数据if realtime_data_df is None or realtime_data_df.empty:reset_()return# 如果获得价格数据为0,则不更新数据if realtime_data_df['price'].sum() == 0:reset_()returnself.realtime_data_df = realtime_data_df#my_signal.start_timer_signal.emit()my_signal.realtime_area_data_signal.emit()reset_()if self.is_searching_realtime_data:returnself.is_searching_realtime_data = Trueself.realtime_btn.setEnabled(False)worker = Thread(target=realtime_thread_func)worker.start()return# 实时行情图绘制def realtime_data_cb(self):#清除旧的绘制新的if self.realtime_curve is not None:self.realtime_plot.removeItem(self.realtime_curve)realtime_data_df = self.realtime_data_df.copy()# 行号的序号xdata = realtime_data_df.index.astype(int).to_list()ydata = realtime_data_df['price'].astype(float).to_list()self.realtime_plot.plotItem.setLabel('left', '价格')axis: pg.AxisItem = self.realtime_plot.getPlotItem().getAxis('bottom')self.realtime_plot.plotItem.setLabel('bottom', '时间',units='')# x轴刻度变为字符串,固定显示9:30 10:30 14:00 15:00x_ticks_str = [(0,'9:30'),(30,'10:00'),(60,'10:30'),(90,'11:00'),(120,'11:30/13:00'),(150,'13:30'),(180,'14:00'),(210,'14:30'),(240,'15:00')]plot_ticks = [x_ticks_str]axis.setTicks(plot_ticks)#限制显示范围self.realtime_plot.plotItem.vb.setLimits(xMin = 0,xMax =250 ,yMin = min(ydata) - 1 , yMax = max(ydata) +1,minXRange=250, maxXRange= 250,minYRange = 0.1, maxYRange = 1.2*max(ydata))self.realtime_curve = self.realtime_plot.plotItem.plot(xdata, ydata, pen='w')returndef realtime_plot_mouse_move_cb(self,pos):if self.realtime_data_df is None:return#清除旧线self.realtime_plot.removeItem(self.realtime_vertical_line)self.realtime_plot.removeItem(self.realtime_horizontal_line)closest_min_idx = Noneview_coords = pg.Point(pos)mouse_point  = self.realtime_plot.getPlotItem().vb.mapSceneToView(view_coords)x = round(mouse_point.x())#保留两位小数temp_df = self.realtime_data_df.copy()temp_df['序号'] = temp_df.index.astype(int)if x < 0 or x > temp_df.iloc[-1]['序号'] or x < temp_df.iloc[0]['序号']:return # 查找可以划线的x坐标closest_min_idx = (temp_df['序号'] - x).abs().idxmin()#如果实时行情图还没有绘制,则不绘制垂直线,水平线if self.realtime_curve is not None and closest_min_idx is not None:y_value = temp_df.iloc[closest_min_idx]['price']self.text_label.setText("价格:" + str(y_value.round(2)) + " 时间:" + temp_df.iloc[closest_min_idx]['time'].strftime('%H:%M:%S'))self.realtime_vertical_line = pg.InfiniteLine(pos=closest_min_idx, angle=90, pen='y')self.realtime_horizontal_line = pg.InfiniteLine(pos=y_value, angle=0, pen='y')self.realtime_plot.addItem(self.realtime_horizontal_line)self.realtime_plot.addItem(self.realtime_vertical_line)def search_edit_cb(self):text = self.search_edit.text()if text == '':self.add_item_to_combox(self.stock_code_df)returndf = self.stock_code_df[self.stock_code_df['name'].str.contains(text) | self.stock_code_df['code'].str.contains(text)]self.add_item_to_combox(df)return# 查询所有股票代号数据的回调def search_btn_cb(self):# QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)def search_thread_func():self.is_searching_stock_code = Truestock_code_df = StockData.get_all_stock_code()#print(stock_code_df)if stock_code_df is None:print('股票数据获取失败')if stock_code_df.equals(self.stock_code_df):print('股票数据无更新')else:self.stock_code_df = stock_code_dfself.stock_code_df.to_csv('stock_symbol.csv',index=False,encoding='utf-8')print('股票数据更新成功')self.search_btn.setEnabled(True)self.is_searching_stock_code = Falseif self.is_searching_stock_code:returnself.is_searching_stock_code = Trueself.search_btn.setEnabled(False)#self.search_btn.setEnabled(False)worker = Thread(target=search_thread_func)worker.start()def warning_cb(self,msg):QtWidgets.QMessageBox.warning(self, "警告", msg)# 切换tab页时清除text_labeldef tab_widget_cb(self,index):self.text_label.setText("")#def start_timer_cb(self):#    self.realtime_timer.start(1000*60 * 5) #5分钟更新一次数据#def stop_timer_cb(self):#    self.realtime_timer.stop()#def timer_timeout_cb(self):#print("定时器触发" + str(QtCore.QDateTime.currentDateTime().toString('HH:mm:ss')))#self.realtime_data_cb()if __name__ == '__main__':app = QtWidgets.QApplication()window = MainWindow()window.show()app.exec()

相关文章:

[白月黑羽]关于仿写股票数据软件题目的解答

原题&#xff1a; 对应问题视频&#xff1a; 实现的效果 不同点 实现的作品和原题要求的不同点 题目要求爬虫获取数据&#xff0c;作品中是调库获取所有股票历史数据实时数据使用爬虫的方式爬取指定股票的数据&#xff0c;需要实时更新&#xff0c;我做了修改&#xff0c;改…...

详解LZ4文件解压缩问题

详解LZ4文件解压缩问题 一、LZ4文件解压缩方法1. 使用LZ4命令行工具2. 使用Python库3. 使用第三方工具4. 在线解压工具 二、常见问题及解决方法1. 解压显示文件损坏2. 解压后文件大小异常 三、总结 LZ4是一种快速的压缩算法&#xff0c;广泛应用于需要实时压缩和解压缩大文件的…...

vue项目中单独文件的js不存在this.$store?.state怎么办

在Vue项目中&#xff0c;如果你在单独的文件&#xff08;比如插件、工具函数等&#xff09;中遇到this.$store不存在的情况&#xff0c;这通常是因为this上下文不指向Vue实例&#xff0c;或者Vuex store没有被正确地注入到Vue实例中。以下是几种可能的解决方案&#xff1a; 确保…...

Github提交Pull Request教程 Git基础扫盲(零基础易懂)

1 PR是什么&#xff1f; PR&#xff0c;全称Pull Request&#xff08;拉取请求&#xff09;&#xff0c;是一种非常重要的协作机制&#xff0c;它是 Git 和 GitHub 等代码托管平台中常见的功能&#xff0c;被广泛用于参与社区贡献&#xff0c;从而促进项目的发展。 PR的整个过…...

Java函数式编程【二】【Stream的装饰】【中间操作】【map映射器】【摊平映射器flatMap】

一、Java的Stream流式编程中的中间操作 Java的Stream流式编程中&#xff0c;中间操作是对数据流进行处理的一种方式&#xff0c;这些操作通常返回流对象本身&#xff0c;以便可以链接更多的操作。以下是一些常见的中间操作&#xff1a; filter(Predicate predicate) - 用于通过…...

树莓派明明安装了opencv和numpy,却找不到

当然不止树莓派&#xff0c;配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法&#xff1a;【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突&#xff1a; 树莓派上可能有多个版本…...

numpy.float8不存在;Python中,实现16位浮点数

目录 python中矩阵的浮点数存储 numpy.float8不存在 Python中,实现16位浮点数 实现 float16 关于 float8 python中矩阵的浮点数存储 在Python中,矩阵通常是通过嵌套列表(list of lists)、NumPy数组(numpy.ndarray)或其他类似的数据结构来表示的。矩阵中存储的数值所…...

Redis集群配置 (不使用docker 部署)

1. Redis集群简介 1.1 什么是Redis集群 Redis集群是一种通过将多个Redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。它允许Redis在不同节点上同时提供服务&#xff0c;提高整体性能和可靠性。根据搭建的方式和集群的特性&#xff0c;Redis集群主要有三种模式&…...

HTML5系列(7)-- Web Storage 实战指南

前端技术探索系列&#xff1a;HTML5 Web Storage 实战指南 &#x1f5c4;️ 致读者&#xff1a;本地存储的新纪元 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 HTML5 中的 Web Storage 技术&#xff0c;这是一个强大的本地存储解决方案&#xff0c;让我们能…...

【在Linux世界中追寻伟大的One Piece】读者写者问题与读写锁

目录 1 -> 读者写者问题 1.1 -> 什么是读者写者问题 1.2 -> 读者写者与生产消费者的区别 1.3 -> 如何理解读者写者问题 2 -> 读写锁 2.1 -> 读写锁接口 3 -> 读者优先(Reader-Preference) 4 -> 写者优先(Writer-Preference) 1 -> 读者写者…...

用到动态库的程序运行过程

当我们写好了一段代码然后编译运行后会生成可执行文件&#xff0c;该文件会存在磁盘的当前目录下&#xff0c;而当我们开始运行这段程序时&#xff0c;操作系统&#xff08;加载器&#xff09;需要将其从磁盘加载进内存然后执行相关操作&#xff0c;而对于用到动态库的程序&…...

类型转换与IO流:C++世界的变形与交互之道

文章目录 前言&#x1f384;一、类型转换&#x1f388;1.1 隐式类型转换&#x1f388;1.2 显式类型转换&#x1f381;1. C 风格强制类型转换&#x1f381;2. C 类型转换操作符 &#x1f388;1.3 C 类型转换操作符详解&#x1f381;1. static_cast&#x1f381;2. dynamic_cast&…...

Pytorch使用手册- TorchVision目标检测微调Tutorial的使用指南(专题十二)

这篇教程的目标是对一个预训练的 Mask R-CNN 模型进行微调,应用于 Penn-Fudan 行人检测与分割数据集。该数据集包含 170 张图像,里面有 345 个行人实例,我们将通过这个教程来演示如何使用 torchvision 中的新特性,训练一个面向自定义数据集的目标检测和实例分割模型。 注意…...

人工智能机器学习算法分类全解析

目录 一、引言 二、机器学习算法分类概述 &#xff08;一&#xff09;基于学习方式的分类 1. 监督学习&#xff08;Supervised Learning&#xff09; 2. 无监督学习&#xff08;Unsupervised Learning&#xff09; 3. 强化学习&#xff08;Reinforcement Learning&#xf…...

Linux 35.6 + JetPack v5.1.4@DeepStream安装

Linux 35.6 JetPack v5.1.4DeepStream安装 1. 源由2. 步骤Step 1 安装Jetpack 5.1.4 L4T 35.6Step 2 安装依赖组件Step 3 安装librdkafkaStep 4 安装 DeepStream SDKStep 5 测试 deepstream-appStep 6 运行 deepstream-app 3. 总结3.1 版本问题3.2 二进制help 4. 参考资料 1. …...

图数据库 | 11、图数据库架构设计——高性能图存储架构(下)

在上篇内容中&#xff0c;老夫着重讲了高性能图存储系统的特点&#xff0c;咱们继续往下讲重点——高性能存储架构的设计思路&#xff01;&#xff01; 2.高性能存储架构设计思路 首先呢&#xff0c;存储架构以及核心数据结构的设计思路通常围绕如下4个维度来进行&#xff1a…...

【HTTP】HTTP协议

一个Web Server就是个服务器软件&#xff08;程序&#xff09;&#xff0c;或者是运行这个服务器软件的硬件&#xff08;计算机&#xff09;&#xff0c;其主要功能是通过HTTP协议与客户端进行通信&#xff0c;来接收&#xff0c;存储&#xff0c;处理来自客户端的HTTP请求&…...

大数据新视界 -- Hive 基于 MapReduce 的执行原理(上)(23 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

SpringBoot源码解析(六):打印Banner

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…...

【计算机网络】实验6:IPV4地址的构造超网及IP数据报

实验 6&#xff1a;IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网&#xff08;无分类编制&#xff09;的了解。 加深对IP数据包的发送和转发流程的了解。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、了解IPV4地址的构造超网…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...

大模型——基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程

基于Docker+DeepSeek+Dify :搭建企业级本地私有化知识库超详细教程 下载安装Docker Docker官网:https://www.docker.com/ 自定义Docker安装路径 Docker默认安装在C盘,大小大概2.9G,做这行最忌讳的就是安装软件全装C盘,所以我调整了下安装路径。 新建安装目录:E:\MyS…...

IP选择注意事项

IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时&#xff0c;需要考虑以下参数&#xff0c;然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...

华为云Flexus+DeepSeek征文 | MaaS平台避坑指南:DeepSeek商用服务开通与成本控制

作者简介 我是摘星&#xff0c;一名专注于云计算和AI技术的开发者。本次通过华为云MaaS平台体验DeepSeek系列模型&#xff0c;将实际使用经验分享给大家&#xff0c;希望能帮助开发者快速掌握华为云AI服务的核心能力。 目录 作者简介 前言 一、技术架构概览 1.1 整体架构设…...