让你的小爬虫穿上新外衣,做一只界面友好型的爬虫
在上一篇文章中,我们完成了一只能够导入并读取Excel文件内容,并进行网页自动爬取,并将爬取的内容保存下来的小爬虫,已经非常的能干了。但是这只小爬虫缺少一件外衣(图形界面),不能友好的进行交互,那么这篇文章中,我们就来着手制作这个图形界面。
图形界面库的选择
Python支持多种图形界面的第三方库,包括wxWidgets、Qt、GTK。
我当时刚刚寻找制作衣服材料(GUI)的时候也是眼花缭乱,尝试过很多,比如Tkinter,但是试了一下后发现有点丑,不适合我的审美。最后我将目标锁定为Qt。
PyQt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。本教程使用Python 3。Qt库是最强大的GUI库之一。PyQt5做为Python的一个模块,它有620多个类和6000个函数和方法。这是一个跨平台的工具包,它可以运行在所有主要的操作系统,包括UNIX,Windows,Mac OS。pyqt5是双重许可。
PyQt5的安装
这里我们仍然请上神器pip登场。
pip install PyQt5
安装完成以后就可以直接使用,不需要任何配置信息。
这里借用一下他人的代码,来测试你的PyQt5是否能正常执行。
import sys
#这里我们提供必要的引用。基本控件位于pyqt5.qtwidgets模块中。
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
#每一pyqt5应用程序必须创建一个应用程序对象。sys.argv参数是一个列表,从命令行输入参数。
app = QApplication(sys.argv)
#QWidget部件是pyqt5所有用户界面对象的基类。他为QWidget提供默认构造函数。默认构造函数没有父类。
w = QWidget()
#resize()方法调整窗口的大小。这离是250px宽150px高
w.resize(250, 150)
#move()方法移动窗口在屏幕上的位置到x = 300,y = 300坐标。
w.move(300, 300)
#设置窗口的标题
w.setWindowTitle('Simple')
#显示在屏幕上
w.show()
#系统exit()方法确保应用程序干净的退出
#的exec_()方法有下划线。因为执行是一个Python关键词。因此,exec_()代替
sys.exit(app.exec_())
运行程序,显示一个对话框,安装成功。
接下来我百度了各种PyQt5的代码写法,试了下用手写的方式来实现界面排版( PyQt5布局管理),但是发现这个难度有点大,类似于闭着眼睛打代码,全靠脑补,效率太低了。最后决定用软件来帮助我实现界面布局。
一番搜寻,决定使用QtCreator来进行界面的绘制。
QTCreator
QTCreator是跨平台的QT IDE,提供图形化的UI绘制工具。
首先,你的系统中必须准备好Python环境,并且安装对应版本的PyQt5库,再然后安装对应版本的QtCreator。
在使用QTCreator的时候我绕了一个很大的弯路,看着教程各种配置了一番Python的使用环境,但是你只是用QTCreator设计一个图形界面,而不需要在里面设计代码(代码部分放到VSCode中去写)的话,就不需要配置,可以直接拿来使用。
下载安装完QTCreator,打开,选择文件→新建文件或项目,选择Qt→Qt Designer Form。
选择Main Window→路径和文件名自己设置→下一步,最后点击完成会生成一个.ui的文件,就可以拖动左边的组件进行界面的绘制了。
这里顺带说一下QT设计师界面类和Qt Designer Form的区别。当时看着教程,里面说到这一步:选择button组件进行信号槽连接,进入cpp文件中进行代码操作。可是我怎么点都是报错,后来才发现选择Qt Designer Form只会产生一个.ui的文件,而选择QT设计师界面类,会生成3个文件,分别是.h、.cpp和.ui文件。
只有选择了QT设计师界面类,点击连接信号槽才能跳转到.cpp文件中进行代码编写。我们只做界面布局的话,只需要一个.ui文件就够了,因为代码的编写完全可以到更棒的VSCode中操作。
完成了这些我们就可以愉快的拖动图标进行界面布局了。这个是我设计的界面,看上去很普通,大家轻拍。(其实已经是第三版界面了,前两版特别是第一版简直丑到惨不忍睹,只是为了功能的实现而去尝试下设计的)
说到界面设计,那我要给大家说一个我遇到的坑,就是这个QGroupBox组件。
乍一看这玩意我以为是透明的,没在意层次,结果后面运行的时候,在QGroupBox里的按钮怎么按都按不下去,QLineEdit组件怎么点击都无法输入,还以为是我的环境配置出了问题,捣鼓了好久。最后发现是QGroupBox组件的问题。这个组件其实也是有厚度的,虽然是透明的给你一个假象,其实类似于css属性中的z-index。所以需要用这个组件的时候,需要先放QGroupBox,然后再配置QGroupBox里面的其他组件,才不会引起看上去什么事儿都没,但是实际上已经被覆盖的问题。
将.ui的界面文件转换为.py文件
设计完界面后,我们需要把这个.ui变成代码,以方便我们之后的操作。
- 首先在cmd中打开.ui所在路径
cd E:/QT_Creator/bin
- 然后输入
pyuic5 -o mainwindow.py mainwindow.ui
回车.其中,-o 后的参数为输出文件的名称 -o 后第二个参数即为生成的ui文件的名称
这样就能得到一个名为mainwindow.py的文件,我们用VSCode打开,就可以对他进行操作了。
这个时候在VSCode中按下F5会报错,所以还需要配置几个步骤。
- 增加几个引用
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog,QMessageBox
import sys
- 添加主函数脚本
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
然后再次按下F5,成功运行,弹出界面。
这个时候,我们要把按钮和输入框的改造下,使其能够交互起来。
QPushButton的信号槽连接:
self.choose_file.clicked.connect(self.open_file)
,传入的是点击后执行的方法。获取QLineEdit里面的文本:
self.cookie_edit.text()
。将文案输出到QTextBrowser组件中显示:
self.message_show.append('爬取全部文章成功\n')
。判断复选框是否选中
self.only_name.isChecked()
,返回的是true/false。
运行中我发现,每次执行的时候,QTextBrowser组件中的文案,不能像print()方法一样,一行一行的输出,每次都是要等到全部执行完后,一次性输出。这个不符合我设计QTextBrowser组件的初衷。于是我又去问了问怎么样才能让QTextBrowser组件中的文案一行一行的输出。
最终多方尝试后,解决了这个问题,就是加入这句代码QApplication.processEvents()
,可以将这句代码放入循环中,就能做到界面的实时刷新了。
self.message_show.append('爬取文章链接成功\n')
QtWidgets.QApplication.processEvents() #界面实时刷新
在复杂操作的过程中频繁调用QApplication.processEvents()。这个函数告诉Qt处理所有那些还没有被处理的各类事件,然后将控制权返还给调用者。实际上QApplication.exec()就是一个不停调用processEvents()函数的while循环。
完成了这些的准备后。将上篇文章中完成的小爬虫稍加改造移植过来。按F5执行一下试试。
有了很棒的交互,能够对一些非法操作做出判断并提示,而不会直接保存,程序中断响应。最后填入正确的参数,点击开始爬取。
完美的获取了我们所需要的数据,而且能根据需求进行范围爬取。QTextBrowser组件也能根据爬取的进度,一行一行的显示。
后记
本篇文章,详细的讲了python的图形界面库PyQt5的使用、QTCreator的下载安装使用以及.ui转为.py的方法。截止到这第四篇的系列文章,我们的小爬虫不仅能自己完成全部文章的爬取,而且还穿上了人机交互良好的新衣服。已经变的非常优秀了。但是还缺少最后一样,这只小爬虫目前还是非常依赖本地电脑的配置,要是放到其他电脑上,缺少了需要的环境,它就又一动不动了。所以在下篇文章,也是最后一篇文章中,我们要将这只小爬虫,打包发布出来,使它可以在其他电脑上欢快自在的运行。