python项目实战---使用图形化界面下载音乐
音乐下载
设计思路:
- 设计界面
- 编写爬虫代码
- 绑定爬虫
- 打包exe文件
这个是最终的设计成果,所有的下载歌曲都在“下载mp3”文件夹里面
完整代码
- 逻辑代码
import os.path
import reimport requests
from PyQt5.QtWidgets import QApplication,QWidget,QMessageBox
import sysfrom PyQt5 import QtCore, QtGui, QtWidgets
from get_music import get_urlclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(800, 500)self.verticalLayout = QtWidgets.QVBoxLayout(Form)self.verticalLayout.setObjectName("verticalLayout")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.label = QtWidgets.QLabel(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.label.setFont(font)self.label.setObjectName("label")self.horizontalLayout.addWidget(self.label)self.lineEdit = QtWidgets.QLineEdit(Form)self.lineEdit.setObjectName("lineEdit")self.horizontalLayout.addWidget(self.lineEdit)self.verticalLayout.addLayout(self.horizontalLayout)self.listWidget = QtWidgets.QListWidget(Form)self.listWidget.setObjectName("listWidget")self.verticalLayout.addWidget(self.listWidget)self.listWidget.itemDoubleClicked.connect(Form.downloads_music)self.horizontalLayout_2 = QtWidgets.QHBoxLayout()self.horizontalLayout_2.setObjectName("horizontalLayout_2")spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem)self.pushButton = QtWidgets.QPushButton(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.pushButton.setFont(font)self.pushButton.setObjectName("pushButton")self.horizontalLayout_2.addWidget(self.pushButton)spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem1)self.pushButton_2 = QtWidgets.QPushButton(Form)self.pushButton_2.setObjectName("pushButton_2")self.horizontalLayout_2.addWidget(self.pushButton_2)spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem2)self.pushButton_3 = QtWidgets.QPushButton(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.pushButton_3.setFont(font)self.pushButton_3.setObjectName("pushButton_3")self.horizontalLayout_2.addWidget(self.pushButton_3)spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem3)self.verticalLayout.addLayout(self.horizontalLayout_2)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "音乐下载器"))self.label.setText(_translate("Form", "音乐名称:"))self.pushButton.setText(_translate("Form", "搜索"))self.pushButton.clicked.connect(Form.btn_search)self.pushButton_2.setText(_translate("Form", "更多"))self.pushButton_2.clicked.connect(Form.btn_more)self.pushButton_3.setText(_translate("Form", "清空"))self.pushButton_3.clicked.connect(Form.btn_clear)class MyWindow(QWidget):def __init__(self):super().__init__()self.ui = Ui_Form()self.ui.setupUi(self)self.page1=1def btn_search(self):# print('点击搜索')self.page1 = 1pr_input = self.ui.lineEdit.text()linlks = get_url(pr_input,1)for linlk in linlks:self.ui.listWidget.addItem(f'歌名:{linlk[0]},歌手:{linlk[1]},id={linlk[2]},下载链接:{linlk[3]}')# print(f'歌名:{linlk[0]},歌手:{linlk[1]}id={linlk[2]}')def btn_more(self):pr_input = self.ui.lineEdit.text()self.page1 += 1linlks = get_url(pr_input, self.page1)for linlk in linlks:self.ui.listWidget.addItem(f'歌名:{linlk[0]},歌手:{linlk[1]},id={linlk[2]},下载链接:{linlk[3]}')def btn_clear(self):self.ui.lineEdit.clear()self.ui.listWidget.clear()self.page1 = 1def downloads_music(self,data): # 这里第二个参数就把双击对象的文本内容传过来了# print(data.text())data = data.text()author = re.findall(fr'歌名:(.*?),',data)[0]song = re.findall(fr'歌手:(.*?),',data)[0]id = re.findall(fr'id=(.*?),',data)[0]download_urls = re.findall('下载链接:(.*)',data)[0]# print(author)# print(song)# print(id)# print(download_urls)# QMessageBox.information(self, '下载提示!', f'是否下载{song}-{author}?', QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes) # 这里是下载前的提示,我觉得没用,就隐藏了code = requests.get(download_urls)url_text = code.textif 'ID3'in url_text: # 因为mp3文件的开头都是ID3music = requests.get(download_urls).contentif not os.path.exists('下载mp3'):os.mkdir('下载mp3')# print(f'下载mp3/{song}-{author}-{id}.mp3')with open(fr'下载mp3/{song}-{author}-{id}.mp3', 'wb') as f:f.write(music)QMessageBox.warning(self, '下载提示!', '下载成功')else:QMessageBox.warning(self,'下载提示!',f'下载失败!下载地址是:{download_urls}')if __name__ == '__main__':app = QApplication(sys.argv)window = MyWindow()window.show()sys.exit(app.exec_())
- 爬虫代码
import pprint
import re
import requestsdef get_url(input,pages=1):url = 'https://music.txqq.pro/'data = {'input': input,'filter': 'name','type': 'netease','page': pages}header = {'x-requested-with':'XMLHttpRequest'}rt = requests.post(url=url,headers=header,data=data)rt.encoding = rt.apparent_encodinglinks = rt.json()# print(links)re_code = links['code']print(re_code)mp3_links = links['data']track_links = []for link0 in mp3_links:downloed_url = link0['url']title = link0['title']author = link0['author']id = re.findall('id=(.*?).mp3',downloed_url)[0]# print(title,author,id,downloed_url)track_links.append([title,author,id,downloed_url])return track_links
- 界面py
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file '音乐下载器.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 300)self.verticalLayout = QtWidgets.QVBoxLayout(Form)self.verticalLayout.setObjectName("verticalLayout")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.label = QtWidgets.QLabel(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.label.setFont(font)self.label.setObjectName("label")self.horizontalLayout.addWidget(self.label)self.lineEdit = QtWidgets.QLineEdit(Form)self.lineEdit.setObjectName("lineEdit")self.horizontalLayout.addWidget(self.lineEdit)self.verticalLayout.addLayout(self.horizontalLayout)self.listView = QtWidgets.QListView(Form)self.listView.setObjectName("listView")self.verticalLayout.addWidget(self.listView)self.horizontalLayout_2 = QtWidgets.QHBoxLayout()self.horizontalLayout_2.setObjectName("horizontalLayout_2")spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem)self.pushButton = QtWidgets.QPushButton(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.pushButton.setFont(font)self.pushButton.setObjectName("pushButton")self.horizontalLayout_2.addWidget(self.pushButton)spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem1)self.pushButton_2 = QtWidgets.QPushButton(Form)self.pushButton_2.setObjectName("pushButton_2")self.horizontalLayout_2.addWidget(self.pushButton_2)spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem2)self.pushButton_3 = QtWidgets.QPushButton(Form)font = QtGui.QFont()font.setBold(True)font.setWeight(75)self.pushButton_3.setFont(font)self.pushButton_3.setObjectName("pushButton_3")self.horizontalLayout_2.addWidget(self.pushButton_3)spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)self.horizontalLayout_2.addItem(spacerItem3)self.verticalLayout.addLayout(self.horizontalLayout_2)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "音乐下载器"))self.label.setText(_translate("Form", "音乐名称:"))self.pushButton.setText(_translate("Form", "搜索"))self.pushButton_2.setText(_translate("Form", "更多"))self.pushButton_3.setText(_translate("Form", "清空"))
设计音乐下载器界面
首先要整一个标签,提示用户要输入的信息
然后再整一个输入框,让用户输入信息,我们获取用户输入的信息
然后就是一个list view这个文本框显示我们根据用户输入的信息得到的内容
接着就是三个按钮:搜索,下一页,清空
这是比较基本的需求,具体的细节可以自己脑补
爬虫代码
设计思路:
- 设计函数:给一个歌名,返回一个含歌曲详细信息的列表
- 找网站
首先是找个音乐网站,这个网站不要太牛逼,不然光反爬就够你喝一壶了
最好是找个小网站,也不要太卡,功能不用太复杂,支持搜索音乐,下载音乐就行
像图片这种格局的网站就好了
这里使用F12查看咱们下载的音乐在哪里,一般都是在数据包里面,也就是异步获取,需要使用post请求
这里的url和data不要弄错,最重要的是请求头headers
因为服务器会从请求头来判断给你返回什么内容,如果没有请求头,就返回源代码,而音乐的下载链接等详细信息都在数据包里面,我们就得不到想要的结果
所以,先去原网站,打开开发者工具栏,找下载链接,先找源代码(一般源代码都没有)
然后刷新网页,查看数据包,你会找到一个只有data的数据包,里面就是一系列的音乐下载链接
可能会遇到的问题
- 你一点击F12网页自动关闭
- 解决方法:换一个网站
- 网站上能找到数据包,但是pycharm中无论如何都得不到数据包,只有源代码
- 解决方法:把网站的数据包的所有请求头全部复制,制成字典,得到数据包之后,再一个个删除键值对
- 数据包里面不是mp3结尾的下载链接
- 解决方法:换网站,这个可能是api,反正我不会
- 没有找到数据包
- 解决方法:换网站,可能是反爬,问题比较复杂
具体问题具体分析,有其他问题评论区见
处理数据包
也就是拿到网站返回的数据包后,对数据包进行拆解
这个数据包一般是json格式,所以用json进行解析,不要用text了
import pprint
import re
import requestsdef get_url(input,pages=1):url = 'https://music.txqq.pro/'data = {'input': input,'filter': 'name','type': 'netease','page': pages}header = {'x-requested-with':'XMLHttpRequest'}rt = requests.post(url=url,headers=header,data=data)rt.encoding = rt.apparent_encodinglinks = rt.json()# print(links)re_code = links['code']print(re_code)mp3_links = links['data']track_links = []for link0 in mp3_links:downloed_url = link0['url']title = link0['title']author = link0['author']id = re.findall('id=(.*?).mp3',downloed_url)[0]# print(title,author,id,downloed_url)track_links.append([title,author,id,downloed_url])return track_links
这个数据包一般返回一个字典,第一个数据是code也就是状态码,咱们一般用不到,当然为了使代码更加健壮,可以获取一下这个状态码
第二个数据就是各种歌曲的信息了,包括歌曲的下载链接,歌名,歌手,作词,作曲等等,很明显也是一个列表,所以我使用了for循环,依次拿数据来解析
列表里面的每一项都是字典,所以我用取值的方式得到了对应的信息,也就是23~25行
因为数据包里面有一套歌曲信息,一个个返回比较麻烦,就以列表的形式进行返回了
绑定爬虫
在上一步,我们拿到了歌曲数据包,也就是返回值的列表
函数的使命完成了
现在就是设计槽函数和按钮连接了
第一个槽函数–btn_search
def btn_search(self):# print('点击搜索')self.page1 = 1pr_input = self.ui.lineEdit.text()linlks = get_url(pr_input,1)for linlk in linlks:self.ui.listWidget.addItem(f'歌名:{linlk[0]},歌手:{linlk[1]},id={linlk[2]},下载链接:{linlk[3]}')# print(f'歌名:{linlk[0]},歌手:{linlk[1]}id={linlk[2]}')
这个槽函数对应的就是搜索按钮,我们想要搜索,就要知道用户想要搜索什么,所以使用lineEdit.text()得到输入框的内容
然后就是把得到的歌名给爬虫函数
然后把得到的信息放在listWidget里面,使用addItem一行行的把内容填充进去
这里一般为了整洁会把下载链接隐藏,那样就会导致一个问题,下面你想要下载的时候,还要去找这个链接,老师的方法是把所有的链接和其他信息储存起来,放在一个全局列表里面,在以后想要下载的时候再去找
我感觉很麻烦,确实是干净了,但是代码的复杂程度就上去了,还浪费了一定的内存空间,去列表找链接也浪费时间
所以我把链接也一同放在listWidget里面了
第二个槽函数–btn_more
def btn_more(self):pr_input = self.ui.lineEdit.text()self.page1 += 1linlks = get_url(pr_input, self.page1)for linlk in linlks:self.ui.listWidget.addItem(f'歌名:{linlk[0]},歌手:{linlk[1]},id={linlk[2]},下载链接:{linlk[3]}')
这个槽函数对应的是“更多”按钮,也就是我们想要在同一歌名下得到更多的信息
因为数据包也有次序,在网站上直接搜索歌曲得到的是页数为1的数据包,再点击下一页又会刷新新的数据包,得到页数为2的数据包等等
所以涉及一个页数的信息,在init初始化里面定义一个变量page1,这个变量是专门来定位数据包的
第三个槽函数–btn_clear
def btn_clear(self):self.ui.lineEdit.clear()self.ui.listWidget.clear()self.page1 = 1
这个槽函数是最简单的,负责清理面板,也就是点击‘’清理‘’的时候把lineEdit输入框和listWidget展示框清空,有自带的clear函数
第四个槽函数–downloads_music
def downloads_music(self,data): # 这里第二个参数就把双击对象的文本内容传过来了# print(data.text())data = data.text()author = re.findall(fr'歌名:(.*?),',data)[0]song = re.findall(fr'歌手:(.*?),',data)[0]id = re.findall(fr'id=(.*?),',data)[0]download_urls = re.findall('下载链接:(.*)',data)[0]# print(author)# print(song)# print(id)# print(download_urls)# QMessageBox.information(self, '下载提示!', f'是否下载{song}-{author}?', QMessageBox.Yes | QMessageBox.No,QMessageBox.Yes) # 这里是下载前的提示,我觉得没用,就隐藏了code = requests.get(download_urls)url_text = code.textif 'ID3'in url_text: # 因为mp3文件的开头都是ID3music = requests.get(download_urls).contentif not os.path.exists('下载mp3'):os.mkdir('下载mp3')# print(f'下载mp3/{song}-{author}-{id}.mp3')with open(fr'下载mp3/{song}-{author}-{id}.mp3', 'wb') as f:f.write(music)QMessageBox.warning(self, '下载提示!', '下载成功')else:QMessageBox.warning(self,'下载提示!',f'下载失败!下载地址是:{download_urls}')
这个槽函数负责处理咱们想要下载的歌曲,也就是在展示框里面看到想要下载的歌曲,双击一下,直接下载
这里需要一个参数,也就是想要下载的歌曲信息,也就是列表的那一行信息,我们只需要在参数里面加个data就可以得到双击的那一行信息
因为前面我把下载的链接写在了信息里面,所以可以直接下载链接,这里我拿了一下歌曲的名字和歌手来创建mp3文件,因为涉及一个重名的问题,我发现重名歌曲的id不同,所以我还取了一下id来作为文件名,经过这个组合就避免的重名的问题
遇到的问题
歌曲的下载链接无效,因为涉及版权等等问题,很多下载链接都是不能使用的,但是这些链接都能正常访问
也就是说,失效的地址和正常的地址都能正常访问
失效的地址打开是一个网站,正常的地址打开就是mp3文件
这里还要再次判断一下链接是否失效,发现mp3文件的开头是’’ID3‘‘,而失效的地址一般没有
所以使用if判断‘’ID3“是否在网页源代码里面
为了让下载的歌曲比较集中,我把所有的歌曲放在了文件夹里面,名称就是下载mp3
打包exe
最后就是把写好的py程序打包,毕竟费那么大精力,不就是让不会python的人直接使用吗
要是仅仅下载歌曲,不搞界面程序,一个爬虫代码就结束了
这里使用pycharm里面的工具,鼠标右键“打开于(open in)”----找到‘’终端‘’
使用pyinstaller
输入指令-F -i 图标.ico 主函数main.py --noconsole(意思是不要终端那个黑窗口)
这里就是之前的文章写的打包命令,在爬虫基础1里面的末尾
-F 生成exe文件
-i 设置图标
相关文章:

python项目实战---使用图形化界面下载音乐
音乐下载 设计思路: 设计界面编写爬虫代码绑定爬虫打包exe文件 这个是最终的设计成果,所有的下载歌曲都在“下载mp3”文件夹里面 完整代码 逻辑代码 import os.path import reimport requests from PyQt5.QtWidgets import QApplication,QWidget,QM…...

无人机干扰与抗干扰,无人机与反制设备的矛与盾
无人机干扰与抗干扰,以及无人机与反制设备之间的关系,可以形象地比喻为矛与盾的较量。以下是对这两方面的详细探讨: 一、无人机干扰与抗干扰 1. 无人机干扰技术 无人机干扰技术是指通过各种手段对无人机系统进行干扰,使其失去正…...

JAVA基础:单元测试;注解;枚举;网络编程 (学习笔记)
单元测试 操作步骤: a.导包import org.junit; b.三个注解 Test Before After c.点击Test 运行就可以了 用在不需要控制台输入的情境下:javaweb,框架项目,微服务项目 供开发人员自己做测试。 package com.page…...

Meta 上周宣布正式开源小型语言模型 MobileLLM 系列
在 7 月发布之后,Meta 上周宣布正式开源能够在智能手机上运行的小型语言模型 MobileLLM 系列。 Meta 在四个月前发布了这两个参数量小于 10 亿的语言模型 MobileLLM 125M 及 MobileLLM 350M。如今,Meta 又开发出了更大参数量的模型版本,包括…...

安全篇(1)判断安全固件
判断安全固件的方法 一、通过串口开机打印 改方法适用Android与Tina 1.开机打印为SBOOT为安全 [289]HELLO! SBOOT is starting! 2.开机打印boot0为非安全 [88]BOOT0 commit : 1cbb5ea8b3 二、通过读数据 1.getprop | grep verifiedbootstate 这条命令的输出表示设备的…...

ArcGIS005:ArcMap常用操作101-150例动图演示
摘要:本文涵盖了GIS软件操作的多方面内容,包括地图文档的新建、打开、保存及版本兼容性处理;错误与警告的查阅及帮助文档的使用技巧;地图打印比例尺的调整与地图信息的完善;图层操作的撤销与恢复,界面元素的…...

如何用ChatGPT结合Python处理遥感数据
在科技飞速发展的时代,遥感数据的精准分析已经成为推动各行业智能决策的关键工具。从无人机监测农田到卫星数据支持气候研究,空天地遥感数据正以前所未有的方式为科研和商业带来深刻变革。然而,对于许多专业人士而言,如何高效地处…...

matlab 质心重合法实现点云配准
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、初始位置2、配准结果本文由CSDN点云侠原创,原文链接,首发于:2024年11月5日。 一、算法原理 1、原理概述 质心重合法是将源点云 P P P...

ubuntu双屏只显示一个屏幕另一个黑屏
简洁的结论: 系统环境 ubuntu22.04 nvidia-535解决方案 删除/etc/X11/xorg.conf 文件 记录一下折腾大半天的问题。 ubuntu系统是22.04,之前使用的时候更新驱动导致桌面崩溃,重新安装桌面安装不上,请IT帮忙,IT一番操作过后也表示…...

小菜家教平台:基于SpringBoot+Vue打造一站式学习管理系统
前言 现在已经学习了很多与Java相关的知识,但是迟迟没有进行一个完整的实践(之前这个项目开发到一半,很多东西没学搁置了,同时原先的项目中也有很多的问题),所以现在准备从零开始做一个基于SpringBootVue的…...

网络自动化03:简单解释send_config_set方法并举例
目录 拓扑图设备信息 netmiko涉及方法send_config_set()方法的简单示例代码输出结果代码解释导入模块配置信息config_device_interface_description 函数主程序块总结 send_config_set方法参数:1. enter_config_mode2. config_commands3. enter_config_mode4. error…...

跳表原理笔记
课程地址 跳表是一种基于随机化的有序数据结构,它提出是为了赋予有序单链表以 O(logn) 的快速查找和插入的能力 创建 首先在头部创建一个 sentinel 节点,然后在 L1 层采用“抛硬币”的方式来决定 L0 层的指针是否增长到 L1 层 例如上图中,L…...

计算机毕业设计Hadoop+PySpark深度学习游戏推荐系统 游戏可视化 游戏数据分析 游戏爬虫 Scrapy 机器学习 人工智能 大数据毕设
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

AI开发-三方库-torch-torchvision
1 需求 数据集:torchvision.datasets torchvision.datasets.MNIST数据变换:torchvision.transforms torchvision.transforms.Composetorchvision.transforms.ToTensortorchvision.transforms.Normalize模型:torchvision.models可视化工具&…...

解析 MySQL 数据库容量统计、存储限制与优化技巧
管理 MySQL 数据库时,了解数据库中的数据量和存储占用情况是非常重要的,尤其是在面对大规模数据时。无论是为了优化数据库性能,还是为了进行容量规划,准确地统计数据库的容量可以帮助我们做出更好的决策。mysql的客户端工具是Navi…...

智能工厂的软件设计 思维进阶与数学程序
本文要点 讨论 “智能工厂的软件设计”中的“数学程序”。 这里 “数学程序” 是指能“格物致知”来理解“相续”一词。 完整的表述是: 思想素养提升的 思维进阶法(三种 数学程序 : 格物致知 )之思维导图: 二叉树及其…...

技术速递|GitHub Copilot upgrade assistant for Java 技术预览发布!
作者:Nick Zhu - Senior Program Manager 排版:Alan Wang 随着人工智能和大型语言模型(LLMs)的不断发展,Agent(“智能代理”)和智能代理化工作流程正在迅速成为AI领域的下一个前沿。这些自主系统…...

淘宝有哪些API是用来获取商品列表的?(商品id列表)
淘宝商品详情接口item_get是通过商品id或者商品链接来获取商品详情数据的,但是不少客户是没有商品id的,这时需要通过接口来拿到商品id。 可以获取商品id的API有: item_search 通过关键字搜索商品列表 item_search_shop 获取店铺所有商品列…...

D59【python 接口自动化学习】- python基础之异常
day59 捕获异常常见问题 学习日期:20241105 学习目标:异常 -- 75 避坑指南:编写捕获异常程序时经常出现的问题 学习笔记: 捕获位置设置不当 设置范围不当 捕获处理设置不当 嵌套try-except语法错误 总结 位置,范围…...

解决 Spring 异步处理中的 JDK 动态代理问题及相关错误分析
解决 Spring 异步处理中的 JDK 动态代理问题及相关错误分析 遇到的问题: 在使用 Spring 的 Async 注解开启异步处理时,遇到以下错误: The bean ServiceImplChannel could not be injected as a com.wn.order.pay.recharge.controller.Serv…...

从xss到任意文件读取
xss一直是一种非常常见且具有威胁性的攻击方式。然而,除了可能导致用户受到恶意脚本的攻击外,xss在特定条件下还会造成ssrf和文件读取,本文主要讲述在一次漏洞挖掘过程中从xss到文件读取的过程,以及其造成的成因。 0x01 前言 xss一…...

nuiapp vue3 uni-ui uni.uploadFile 图片上传
<div style"position: relative;margin-top: 0.8em;"> <div style"position: absolute;left: 1.5em;top: 2em;">施工图片</div> <div style"position: absolute; left: 7em;top: 0em;right: 0em;bottom…...

【计算机科学】位运算:揭开二进制世界的奥秘
位运算是计算机运算的一种基础操作,直接作用于数据的二进制位(bit),在计算机中具有极高的效率。无论是编写高效算法,还是进行底层开发,位运算都扮演着重要角色。本文将从位运算的起源、常见操作符、应用场景…...

弹性裸金属服务器和传统裸金属服务器有什么区别?
弹性裸金属服务器是一种结合了传统裸金属服务器和云计算资源两种特点的服务器,是一种云计算服务,下面我们就来了解一下弹性裸金属服务器和传统裸金属服务器之间有什么区别吧! 弹性裸金属服务器能够支持企业快速部署新的硬件和软件系统&#x…...

shodan(五)连接Mongodb数据库Jenkinsorg、net、查看waf命令
声明:学习素材来自b站up【泷羽Sec】,侵删,若阅读过程中有相关方面的不足,还请指正,本文只做相关技术分享,切莫从事违法等相关行为,本人一律不承担一切后果 引言: 1.Shodan 是一个专门用于搜索连…...

ThingsBoard规则链节点:Push to Edge节点详解
引言 1. Push to Edge 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 边缘计算 3.2 本地数据处理 3.3 实时响应 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台,提供了设备管…...

基于 EventBridge + DashVector 打造 RAG 全链路动态语义检索能力
作者:肯梦 本文将演示如何使用事件总线(EventBridge),向量检索服务(DashVector),函数计算(FunctionCompute)结合灵积模型服务 [ 1] 上的 Embedding API [ 2] ࿰…...

【golang/navmesh】使用recast navigation进行寻路
目录 说在前面安装使用可视化 说在前面 go version:1.20.2 linux/amd64操作系统:wsl2detour-go版本:v0.2.0github:这里,求star! 安装 使用go mod安装即可go get github.com/o0olele/detour-go使用 使用场景模型构建n…...

【软考】Redis不同的数据类型和应用场景。
Redis的不同数据类型和对应的应用场景: Redis 数据类型及其应用场景 String(字符串) 特点:简单的值存储,支持二进制数据。应用场景: 缓存用户会话。缓存小的配置文件。缓存计数器。文章浏览量࿰…...

java 对人名和电话 脱敏-replaceAll
学习了《正则匹配人名》和《正则匹配电话号码》,如果要一起进行脱敏处理,改怎么做? 脱敏的,考虑配置规则,进行匹配的方式进行处理: 脱敏规则: DesensitizationRules Data public class Desens…...