[白月黑羽]关于仿写股票数据软件题目的解答
原题:
对应问题视频:
实现的效果
不同点
实现的作品和原题要求的不同点
- 题目要求爬虫获取数据,作品中是调库获取所有股票历史数据
- 实时数据使用爬虫的方式爬取指定股票的数据,需要实时更新,我做了修改,改成按下按钮获取分时数据,不自动刷新
体会
- 先AKShare获取数据,总是被封IP,后改用证券宝
- 股票当天分时数据不好获得,这个数据是由服务器主动推送过来的,通过监听所有的收发包数据,找到了这个规律才获得数据
解答:
# 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()
相关文章:

[白月黑羽]关于仿写股票数据软件题目的解答
原题: 对应问题视频: 实现的效果 不同点 实现的作品和原题要求的不同点 题目要求爬虫获取数据,作品中是调库获取所有股票历史数据实时数据使用爬虫的方式爬取指定股票的数据,需要实时更新,我做了修改,改…...

详解LZ4文件解压缩问题
详解LZ4文件解压缩问题 一、LZ4文件解压缩方法1. 使用LZ4命令行工具2. 使用Python库3. 使用第三方工具4. 在线解压工具 二、常见问题及解决方法1. 解压显示文件损坏2. 解压后文件大小异常 三、总结 LZ4是一种快速的压缩算法,广泛应用于需要实时压缩和解压缩大文件的…...
vue项目中单独文件的js不存在this.$store?.state怎么办
在Vue项目中,如果你在单独的文件(比如插件、工具函数等)中遇到this.$store不存在的情况,这通常是因为this上下文不指向Vue实例,或者Vuex store没有被正确地注入到Vue实例中。以下是几种可能的解决方案: 确保…...

Github提交Pull Request教程 Git基础扫盲(零基础易懂)
1 PR是什么? PR,全称Pull Request(拉取请求),是一种非常重要的协作机制,它是 Git 和 GitHub 等代码托管平台中常见的功能,被广泛用于参与社区贡献,从而促进项目的发展。 PR的整个过…...

Java函数式编程【二】【Stream的装饰】【中间操作】【map映射器】【摊平映射器flatMap】
一、Java的Stream流式编程中的中间操作 Java的Stream流式编程中,中间操作是对数据流进行处理的一种方式,这些操作通常返回流对象本身,以便可以链接更多的操作。以下是一些常见的中间操作: filter(Predicate predicate) - 用于通过…...
树莓派明明安装了opencv和numpy,却找不到
当然不止树莓派,配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法:【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突: 树莓派上可能有多个版本…...
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在不同节点上同时提供服务,提高整体性能和可靠性。根据搭建的方式和集群的特性,Redis集群主要有三种模式&…...
HTML5系列(7)-- Web Storage 实战指南
前端技术探索系列:HTML5 Web Storage 实战指南 🗄️ 致读者:本地存储的新纪元 👋 前端开发者们, 今天我们将深入探讨 HTML5 中的 Web Storage 技术,这是一个强大的本地存储解决方案,让我们能…...

【在Linux世界中追寻伟大的One Piece】读者写者问题与读写锁
目录 1 -> 读者写者问题 1.1 -> 什么是读者写者问题 1.2 -> 读者写者与生产消费者的区别 1.3 -> 如何理解读者写者问题 2 -> 读写锁 2.1 -> 读写锁接口 3 -> 读者优先(Reader-Preference) 4 -> 写者优先(Writer-Preference) 1 -> 读者写者…...

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

类型转换与IO流:C++世界的变形与交互之道
文章目录 前言🎄一、类型转换🎈1.1 隐式类型转换🎈1.2 显式类型转换🎁1. C 风格强制类型转换🎁2. C 类型转换操作符 🎈1.3 C 类型转换操作符详解🎁1. static_cast🎁2. dynamic_cast&…...
Pytorch使用手册- TorchVision目标检测微调Tutorial的使用指南(专题十二)
这篇教程的目标是对一个预训练的 Mask R-CNN 模型进行微调,应用于 Penn-Fudan 行人检测与分割数据集。该数据集包含 170 张图像,里面有 345 个行人实例,我们将通过这个教程来演示如何使用 torchvision 中的新特性,训练一个面向自定义数据集的目标检测和实例分割模型。 注意…...
人工智能机器学习算法分类全解析
目录 一、引言 二、机器学习算法分类概述 (一)基于学习方式的分类 1. 监督学习(Supervised Learning) 2. 无监督学习(Unsupervised Learning) 3. 强化学习(Reinforcement Learning…...
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、图数据库架构设计——高性能图存储架构(下)
在上篇内容中,老夫着重讲了高性能图存储系统的特点,咱们继续往下讲重点——高性能存储架构的设计思路!! 2.高性能存储架构设计思路 首先呢,存储架构以及核心数据结构的设计思路通常围绕如下4个维度来进行:…...

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

大数据新视界 -- Hive 基于 MapReduce 的执行原理(上)(23 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

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

【计算机网络】实验6:IPV4地址的构造超网及IP数据报
实验 6:IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网(无分类编制)的了解。 加深对IP数据包的发送和转发流程的了解。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、了解IPV4地址的构造超网…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...