PyQt制作【小红书图片抓取】神器

文章目录

  • 📢闲言碎语
  • 🐾窗口设计
  • 🐾功能设计
  • 📚资源领取

在这里插入图片描述

📢闲言碎语

最近写一个系统,被一个Bug折腾了两天,至今还未解决。由于解决Bug弄得我有点心力憔悴,于是想着写其他小项目玩玩(爬取小红书图片),放松放松,在构思这个小项目的时候想着弄得稍微复杂点,弄着弄着花了大概三个小时时间(屁股要坐烂了),以为要准备结束了,结果又遇到Bug……😵

前前后后解决大大小小的Bug又花了大概一个小时😊

在这里插入图片描述

好在最终将Bug解决了,项目也成功的启动咯~

在这里插入图片描述

具体实现,请往下看👇

🐾窗口设计

如下图所示,主窗口主要有窗口图标、自动的鼠标图标、“小红书图片抓取”标签、带有frame窗口的QLineEdit和两个QPushButton,虽然看起来简单,但其背后逻辑功能的实现也不是很难。

首先需要定义一个子类Frame,并通过继承QFrame类来进行一些窗口的基本设置,设置其窗口的样式和背景颜色。

class Frame(QFrame):def __init__(self, parent=None):super().__init__(parent)self.setFrameStyle(QFrame.Box | QFrame.Plain)self.setLineWidth(3)	# 外线宽self.setMidLineWidth(3)		# 中线宽 self.setStyleSheet("QFrame {border: 3px solid #ff2442;}")   # 设置边框颜色

接着设计主窗口,设置窗口和鼠标的图标,再设置基本的控件,其中setFrameWidget方法主要是将控件放在Frame窗口中,并通过传入的参数,计算控件的大小和移动的位置,让控件与Frame窗口贴合,达到一个美化的效果。

然后重写mousePressEventmouseMoveEventmouseReleaseEvent事件,实现鼠标在窗口中按下可移动的功能,其中还会带动processWindow(显示过程信息的窗口)的移动。

class MainWindow(QMainWindow):def __init__(self, parent=None):super().__init__(parent)# 设置窗口self.setWindowTitle('小红书图片抓取')self.resize(400, 250)self.setWindowIcon(QIcon('window.png'))self.setStyleSheet('background-color: white;')# 设置鼠标self.setCursor(QCursor(QPixmap('mouse.png').scaled(30, 30), 0, 0))# 设置frame窗口宽度self.frameWidth = 3self.mouseFlag = Falseself.setup_ui()# 设置组件def setup_ui(self):# 设置窗口大标题label_title = QLabel(self)label_title.setText('小红书图片抓取')label_title.setStyleSheet('color: #ff2442')label_title.move(50, 10)label_title.setFont(QFont('华文行楷', 25))label_title.adjustSize()# 设置文本框接收self.lineEdit_filepath = self.setFrameWidget(QLineEdit, (130, 30), (70, 80))# 设置选择文件按钮self.button_selectFile = self.setFrameWidget(QPushButton, (100, 30), (220, 80))self.button_selectFile.setText("选择文件")self.button_selectFile.setFont(QFont('华文行楷', 13))self.button_selectFile.clicked.connect(lambda: self.selectFile(self.lineEdit_filepath))# 设置开始启动按钮self.button_start = self.setFrameWidget(QPushButton, (200, 70), (90, 150))self.button_start.setText('开始启动')self.button_start.setFont(QFont('华文行楷', 20))self.button_start.clicked.connect(self.start)# 选择文件def selectFile(self, lineEdit):# 弹出对话框选择文件夹file_dialog = QFileDialog()file_dialog.setFileMode(QFileDialog.AnyFile)file_dialog.exec_()selected_files = file_dialog.selectedFiles()if selected_files:lineEdit.setText(selected_files[0])# 开始启动def start(self):self.setProcessWindow()# 实例化功能类appFunction = AppFunction(self.textEdit_process)# 获取小红书链接LinkUrls = appFunction.getLinkUrls(self.lineEdit_filepath.text())for linkurl in LinkUrls:t = threading.Thread(target=appFunction.run, args=(linkurl,))t.setDaemon(True)t.start()# 设置frame组件def setFrameWidget(self, widget, widget_size, widget_move, frameToplevel=None):if frameToplevel != None:frame = Frame(frameToplevel)else:frame = Frame(self)widget = widget(frame)frame.move(widget_move[0], widget_move[1])frame.resize(widget_size[0], widget_size[1])widget.move(self.frameWidth, self.frameWidth)widget.resize(widget_size[0] - self.frameWidth*2, widget_size[1] - self.frameWidth*2)if widget.inherits("QPushButton"):widget.setStyleSheet("background-color: #ff2442; color: white;")elif widget.inherits("QLineEdit") or widget.inherits("QTextEdit"):widget.setStyleSheet('border: none; font-weight: bold;')   # 设置为无边框return widget# 新窗口的设置def setProcessWindow(self):self.processWindow = ProcessWindow()self.processWindow.setGeometry(self.x()+500, self.y(), 250, 290)# 设置记录过程的textEditself.textEdit_process = QTextEdit(self.processWindow)self.textEdit_process.resize(250, 290)self.textEdit_process.setStyleSheet('border: none; color: white;')    # 设置为无边框self.textEdit_process.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)     # 隐藏垂直滚动条self.processWindow.show()# 窗口移动def mousePressEvent(self, evt):if evt.button() == Qt.LeftButton:self.mouseFlag = Trueself.mouse_x, self.mouse_y = evt.globalPos().x(), evt.globalPos().y()self.origin_x, self.origin_y = self.x(), self.y()def mouseMoveEvent(self, evt):if self.mouseFlag == True:move_x = self.origin_x + (evt.globalPos().x() - self.mouse_x)move_y = self.origin_y + (evt.globalPos().y() - self.mouse_y)self.move(move_x, move_y)try:self.processWindow.move(move_x+500, move_y)     # 过程信息展示窗口移动except:passdef mouseReleaseEvent(self, evt):self.mouseFlag = False# 窗口关闭def closeEvent(self, evt):try:self.processWindow.close()except:pass

在设计显示过程信息的窗口时将窗口设置为半透明、背景颜色为黑色,并在其中添加QTextEdit输入框并设置其无边框和垂直滚动条为不可见,最终在整个程序执行时,会将不同过程不同颜色字体的信息放到输入框中显示,达到一个电影中常见的黑客操作信息时的炫酷效果。

    # 新窗口的设置def setProcessWindow(self):self.processWindow = ProcessWindow()self.processWindow.setGeometry(self.x()+500, self.y(), 250, 290)# 设置记录过程的textEditself.textEdit_process = QTextEdit(self.processWindow)self.textEdit_process.resize(250, 290)self.textEdit_process.setStyleSheet('border: none; color: white;')    # 设置为无边框self.textEdit_process.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)     # 隐藏垂直滚动条self.processWindow.show()# ====================================== 新窗口-过程信息展示区 ======================================
class ProcessWindow(QWidget):def __init__(self):super().__init__()self.setWindowFlag(Qt.FramelessWindowHint)  # 将窗口设置为无边框无标题self.setWindowOpacity(0.5)  # 将窗口设置为半透明self.setStyleSheet('background-color: black;')

🐾功能设计

功能设计主要实现读取excel中的链接、访问链接、在显示过程信息的窗口的输入框中插入信息、获取图片URL、爬取并下载图片。

# ====================================== 爬取图片能执行 ======================================
class AppFunction:def __init__(self, textEdit):self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'}self.pattern = 'url\("(.*)"\);'self.nowPath = os.getcwd()self.textEdit = textEditself.cursor = self.textEdit.textCursor()    # 获取光标位置# 红色self.red = QColor(Qt.yellow)# 绿色self.green = QColor(Qt.green)# 驱动路径driver_path = 'D:\chromedriver-win32\chromedriver.exe'# 固定搭配直接用就行了self.service = Service(executable_path=driver_path)# 无头模式self.option = webdriver.ChromeOptions()self.option.add_experimental_option('excludeSwitches', ['enable-automation'])self.option.add_argument('--disable-blink-features=AutomationControlled')# self.option.add_argument('--headless')# 执行方法def run(self, url):self.getPhotoUrl(url)# 插入文本def insertText(self, text, color):format = QTextCharFormat()format.setForeground(color)self.cursor.insertText(text, format)    # 在QTextEdit中插入文字self.textEdit.ensureCursorVisible()     # 在插入的时候随着光标向下滚动,即达到文字自动滚动效果# 获取图片URLdef getPhotoUrl(self, url):url = urldriver = webdriver.Chrome(service=self.service, options=self.option)self.insertText('\n' + url + ' -- 开始抓取图片URL', self.red)driver.get(url)# 等待图片URL出现WebDriverWait(driver, 1000).until(EC.presence_of_element_located((By.XPATH, '//div[@class="swiper-wrapper"]/div')))# 获取图片URLtemp_PhotoUrls = [i.get_attribute('style') for i in driver.find_elements(By.XPATH, '//div[@class="swiper-wrapper"]/div')]# 获取小红书标题title = driver.find_element(By.XPATH, '//div[@id="detail-title"]').text# 正则方法清洗图片urlPhotoUrls = list(set([re.findall(self.pattern, i)[0] for i in temp_PhotoUrls]))# 关闭浏览器driver.close()self.insertText('\n' + url + ' -- 图片URL抓取完成', self.green)self.getPhoto(PhotoUrls, title)# 获取图片def getPhoto(self, PhotoUrls, title):path = os.path.join(self.nowPath, title)if not os.path.exists(path):  # 创建文件夹os.makedirs(path)for i in range(len(PhotoUrls)):self.insertText('\n' + PhotoUrls[i] + ' -- 开始抓取图片', self.red)res = requests.get(PhotoUrls[i], headers=self.headers)with open(f'./{title}/{i}.webp', 'wb') as f:f.write(res.content)self.insertText('\n' + f'{self.nowPath}\\{title}\\{i}.png' + ' -- 下载完成', self.green)self.insertText(f'\n{title}图片下载完成!\n'.center(71, '='), self.green)# 读取文件,获取网页链接def getLinkUrls(self, path):f = openpyxl.load_workbook(path)sheet = f['Sheet1']LinkUrls = [i.value for i in sheet['A']]return LinkUrls

📚资源领取

关注微信公众号👉【Python小作坊】,回复💬“小红书图片爬取”,即可免费领取(含源代码)~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/189657.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Halcon WPF 开发学习笔记(2):Halcon导出c#脚本和WPF初步开发

文章目录 前言HalconC#教学简单说明如何二开机器视觉如何二次开发Halcon导出Halcon脚本新建WPF项目,导入Halcon脚本和Halcon命名空间 前言 我目前搜了一下我了解的机器视觉软件,有如下特点 优点缺点兼容性教学视频(B站前三播放量)OpenCV开源&#xff0…

Windows桌面黑屏无法打开软件窗口不显示卡死等解决方案

问题还原 该软件窗口无论如何操作均 无法打开显示的窗口 ,但是 可使用 ALTTab 看到任务视图 目录 问题还原 解决方案 1. 使用 WinR 打开命令窗口 盲输 cmd 2. 盲输 taskkill /f /im explorer.exe 关闭资源管理器 3. 输入 start explorer.exe 启动任务管理器即可恢复正常…

TDD、BDD、ATDD以及SBE的概念和区别

在软件开发或是软件测试中会遇到以下这些词:TDD 、BDD 、ATDD以及SBE,这些词代表什么意思呢? 它们之间有什么关系吗? TDD 、BDD 、ATDD以及SBE的基本概念 TDD:(Test Driven Development)是一种…

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于飞蛾扑火优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神…

链表OJ题(4)

目录 10.链表的回文结构 11.随机链表的复制 🙂找中间节点一定要考虑偶数个和奇数个的问题。 🙂指针指向的前中后。 🙂链表节点的位置个数/链表的节点中的数字。🆗🆗 今天最后两道链表OJ题目。 10.链表的回文结构…

【C++】非类型模板参数 | array容器 | 模板特化 | 模板为什么不能分离编译

目录 一、非类型模板参数 二、array容器 三、模板特化 为什么要对模板进行特化 函数模板特化 补充一个问题 类模板特化 全特化与偏特化 全特化 偏特化 四、模板为什么不能分离编译 为什么 怎么办 五、总结模板的优缺点 一、非类型模板参数 模板参数分两类&#x…

数据结构预算法--链表(单链表,双向链表)

1.链表 目录 1.链表 1.1链表的概念及结构 1.2 链表的分类 2.单链表的实现(不带哨兵位) 2.1接口函数 2.2函数的实现 3.双向链表的实现(带哨兵位) 3.1接口函数 3.2函数的实现 1.1链表的概念及结构 概念:链表是一种物理存储结…

黑豹程序员-架构师学习路线图-百科:Knife4j API接口文档管理

文章目录 由来:接口文档第一代:Swagger第二代:Knife4j界面 由来:接口文档 古老编程是一个语言前后端通吃,ASP、JSP、PHP都是如此。 但随着项目规模变大,项目团队也开始壮大,岗位职责开始细分&a…

如何从零开始手写一个消息中间件(从宏观角度理解消息中间件的技术原理)

如何从零开始手写一个消息中间件(从宏观角度理解消息中间件的技术原理) 什么是消息中间件消息中间件的作用逐一拆解消息中间件的核心技术消息中间件核心技术总览IOBIONIOIO多路复用AIOIO多路复用详细分析selectpollepoll Java中的IO多路复用 协议序列化消…

【halcon】halcon 函数文件 以及 脚本引擎如何调用外部函数文件 上篇

前言 halcon有几种文件: 本地程序函数(.hdev)外部函数文件(.hdvp)库函数(.hdp) 说多了容易混淆,今天就说,我觉得最有用的:外部函数文件(.hdvp) 步骤 先写一段halcon脚本&#x…

Nuxt.js——基于 Vue 的服务端渲染应用框架

文章目录 前言一、知识普及什么是服务端渲染什么是客户端渲染?服务端渲染与客户端渲染那个更优秀? 二、Nuxt.js的特点Nuxt.js的适用情况? 三、Vue是如何实现服务端渲染的?安装依赖使用vue安装 Nuxt使用npm install安装依赖包使用n…

C语言——打印1000年到2000年之间的闰年

闰年&#xff1a; 1、能被4整除不能被100整除 2、能被400整除 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int year;for(year 1000; year < 2000; year){if((year%4 0) && (year%100!0) || (year%400 0)){printf("%d ",ye…

Java学习_对象

对象在计算机中的执行原理 类和对象的一些注意事项 this关键字 构造器 构造器是一种特殊的方法 : 特殊之处在于&#xff0c;名字必须与所在类的名字一样&#xff0c;而且不能写返回值类型 封装 封装的设计规范&#xff1a;合理隐藏、合理暴露 实体类 成员变量和局部变量的区别 …

vite基础学习笔记:14.路由跳转(二)携带query参数

说明&#xff1a;自学做的笔记和记录&#xff0c;如有错误请指正 1. 路由跳转&#xff08;携带query参数&#xff09; &#xff08;1&#xff09;第一层路由&#xff08;点击卡片路由跳转至新页面-携带query参数&#xff09; 知识点&#xff1a; query传参对应的是path和qu…

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower

vscode 终端进程启动失败: shell 可执行文件“C:\Windows\System32\WindowsPower 第一次用vscode&#xff0c;然后遇到这个问题&#xff0c;在设置里搜索 terminal.integrated.defaultProfile.windows 将这里的null改成"Command Prompt" 重启就可以了

【Git】深入了解Git及其常用命令

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Git的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Git是什么 二.SVN和Git的区别 三.Git的…

通过SD卡给某摄像头植入可控程序

0x01. 摄像头卡刷初体验 最近研究了手上一台摄像头的sd卡刷机功能&#xff0c;该摄像头只支持fat32格式的sd卡&#xff0c;所以需要先把sd卡格式化为fat32&#xff0c;另外微软把fat32限制了最大容量32G&#xff0c;所以也只能用不大于32G的sd卡来刷机。 这里使用32G的sd卡来…

docker-compose安装es以及ik分词同义词插件

目录 1 前言 2 集成利器Docker 2.1 Docker环境安装 2.1.1 环境检查 2.1.2 在线安装 2.1.3 离线安装 2.2 Docker-Compose的安装 2.2.1 概念简介 2.2.2 安装步骤 2.2.2.1 二进制文件安装 2.2.2.2 离线安装 2.2.2.3 yum安装 3 一键安装ES及Kibana 3.1 yml文件的编写…

【Redis系列】Redis的核心命令(上)

哈喽&#xff0c;大家好&#xff0c;我是小浪。那么上篇博客教会了大家如何在Linux上安装Redis&#xff0c;那么本篇博客就要正式开始学习Redis啦&#xff0c;跟着俺的随笔往下看~ 1、启动Redis 那么如何启动Redis呢&#xff1f;最常用的是以下这个命令&#xff1a; redis-cl…

堆的应用-----Top k 问题

目录 前言 Topk问题 1.问题描述 2.解决方法 3.代码实现&#xff08;C/C&#xff09; 前言 在人工智能算法岗位的面试中&#xff0c;TopK是问得最多的几个问题之一&#xff1a; 到底有几种方法&#xff1f; 这些方案里蕴含的优化思路究竟是怎么样的&#xff1f; 为啥T…