简单的爬虫程序以及使用PYQT进行界面设计(包含源码解析)

时间:2023-08-18 18:34:02

  由于这个是毕业设计的内容,而且还是跨专业的。爬虫程序肯定是很简单的,就是调用Yahoo的API进行爬取图片。这篇博客主要讲的是基础的界面设计。

放上源码,然后分部解析一下重要的地方。注:flickrapi需要*

  代码复制的时候可能掉几个字母或者符号,不建议复制代码,如需复制请自行检查是否有拼写错误

  可以使用pip install  来安装flickrapi和pyqt5和pyqt5-tools

  总体界面如图所示:

简单的爬虫程序以及使用PYQT进行界面设计(包含源码解析)

  下面是源码:

import sys
import os
from PyQt5.QtWidgets import QWidget,
QPushButton,QGroupBox,
QApplication,QLabel,QLineEdit,QToolTip, QMessageBox,QFileDialog,QTextEdit,QProgressBar,QVBoxLayout
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QFont
from PyQt5.QtGui import QPixmap
import time
import flickrapi
import urllib.request #导入相应的模块
stop=0 #设置一个全局变量用于停止程序
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self): #设计界面
self.setGeometry(300, 200, 580, 400) #设置窗体尺寸
self.setWindowTitle('DeepLearn Lab') #命名窗体的标题 QToolTip.setFont(QFont('SansSerif', 10)) #设置控件提示信息的字体格式及大小
self.btn = QPushButton('开始', self) #设计开始按钮
self.btn.setToolTip('单击开始来下载图片') #设置按钮的提示信息
self.btn.clicked.connect(self.doAction) #建立信号和槽的联系,将单击信号与下面的doacion进行链接
self.pbar = QProgressBar(self) #设计一个进度条
self.textEdit=QTextEdit(self) #设计一个文本输出框
self.textEdit.setPlaceholderText("帮助文档:\n1.输入搜索图片的关键字\n2.选择图片储存路径,如不选择默认使用程序所在路径\n3.单击开始进行下载")
self.textEdit.resize(400,200) #设置文本输出框大小
self.btn3 = QPushButton('停止', self) #设计停止按钮
self.btn3.setToolTip('单击来结束下载图片')
self.btn3.clicked.connect(self.stopxz) #建立信号和槽的联系,将单击信号与下面的stopxz进行链接
self.lineEdit = QLineEdit(self) #设计输入框
self.lineEdit.setPlaceholderText("输入搜索关键字")
self.lineEdit.setToolTip('请输入需要搜索的图片的关键字,请用英文输入')
self.lineEdit2 = QLineEdit(self)
self.btn2 = QPushButton('选择保存路径', self) #设计保存下载路径的按钮
self.btn2.setToolTip('请输入储存图片的磁盘地址')
self.btn2.clicked.connect(self.filepath) #建立信号和槽的联系,将单击信号与下面的filepath进行链接
self.groupBox = QGroupBox(self) #设置QT容器
self.groupBox.move(450, 105) #移动容器的位置
self.groupBox.resize(120,280) #设置容器的尺寸
self.groupBox.setTitle('菜单栏') #设置容器的标题
self.groupBox.setAlignment(4) #4为ALignHCenter为居中的意思
layout = QVBoxLayout() #新建一个垂直布局
layout.addWidget(self.lineEdit) #往该布局中添加各种控件
layout.addWidget(self.btn2)
layout.addWidget(self.btn)
layout.addWidget(self.btn3)
self.groupBox.setLayout(layout) #显示该布局
self.groupBox2 = QGroupBox(self) #设置QT容器2
self.groupBox2.move(10, 10)
self.groupBox2.resize(420,300)
self.groupBox2.setTitle('程序运行信息反馈')
self.groupBox2.setAlignment(4) #4为ALignHCenter为居中的意思
layout2 = QVBoxLayout()
layout2.addWidget(self.textEdit)
self.groupBox2.setLayout(layout2)
self.groupBox3 = QGroupBox(self) #设置QT容器3
self.groupBox3.move(310, 330)
self.groupBox3.resize(120,55)
self.groupBox3.setTitle('已下载图片数量')
layout3 = QVBoxLayout()
layout3.addWidget(self.lineEdit2)
self.groupBox3.setLayout(layout3)
self.groupBox4 = QGroupBox(self) #设置QT容器4
self.groupBox4.move(10, 330)
self.groupBox4.resize(280,55)
self.groupBox4.setTitle('进度条显示')
layout4 = QVBoxLayout()
layout4.addWidget(self.pbar)
self.groupBox4.setLayout(layout4)
self.groupBox5 = QGroupBox(self) #设置QT容器5
self.groupBox5.setStyleSheet("border:none") #隐藏容器的边框
self.groupBox5.move(442, 8)
self.groupBox5.resize(136,95)
self.lbl = QLabel (self) #新建一个控件来显示图片
layout5 = QVBoxLayout()
pixmap = QPixmap (r"C:\Users\Administrator\Desktop\svchost.exe\logo2.jpg") # 按指定路径找到图片
self.lbl.setPixmap (pixmap) # 在label上显示图片
self.lbl.setScaledContents (True) # 让图片自适应label大小
layout5.addWidget(self.lbl)
self.groupBox5.setLayout(layout5)
self.show() #显示主窗口
def filepath(self): #用于修改下载路径的函数
self.textEdit.append('当前储存路径为 '+str(os.getcwd()))
file_path=QFileDialog.getExistingDirectory(self)
os.chdir(file_path)
self.textEdit.append('修改后的储存路径为 '+str(os.getcwd()))
def doAction(self): #主函数,用于下载图片
QMessageBox.question(self, '提示',
"单击yes下载图片,下载过程请耐心等待", QMessageBox.Yes, QMessageBox.Yes) #最后一个QMessageBox.No的意思是默认为no
shuru=self.lineEdit.text() #获取输入的内容
api_key='c5dd68f9ba0895eb6fba771e963784f9' #在Yahoo上申请的API账户和密码
api_secret='d11363e44eb2b2e0'
flickr=flickrapi.FlickrAPI(api_key,api_secret,cache=True) #生成flickr对象
count=1 #初始化一个计数器
try:
#爬取text为'cross the road'的照片,这里可以根据自己的需要设置其它的参数
photos=flickr.walk(text=str(shuru),extras='url_c',tag_mode='all',tags='street')#使用walk方法获得图片的url
except Exception as e:
print('Error')
for photo in photos:
url=photo.get('url_c')
self.textEdit.append('当前访问的URL为: '+str(url))
if count>0:
if str(url)!='None':
response=urllib.request.urlopen(url) #获得数据
cat_jpg=response.read(url)
with open ('photo'+str(count)+'.jpg','wb') as f: #下载图片
f.write(cat_jpg)
QString='已下载'+str(count) #显示已下载数量
jishu=count/2
self.pbar.setValue(jishu)
count=count+1
self.lineEdit2.setText(QString)
QApplication.processEvents() #刷新窗口防止卡死
if stop==1:
break
self.textEdit.append('停止下载 ')
def stopxz(self): #当停止按钮按下时改变全局变量值来间接停止爬取图片
global stop
stop=1
def closeEvent(self, event): #重写关闭事件
reply = QMessageBox.question(self, '提示', #设计一个提示框
"确定要退出搜索程序吗?", QMessageBox.Yes |
QMessageBox.No, QMessageBox.No) #最后一个QMessageBox.No的意思是默认为no
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
if __name__ == '__main__': app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())

  首先是爬虫部分,由于是利用了flickrapi,所以只需要按规则使用就可以了。

  具体分析如下

     api_key='c5dd68f9ba0895eb6fba771e963784f9'      #在Yahoo上申请的API账户和密码
api_secret='d11363e44eb2b2e0'
flickr=flickrapi.FlickrAPI(api_key,api_secret,cache=True) #生成flickr对象
count=1 #初始化一个计数器
try:
#爬取text为'cross the road'的照片,这里可以根据自己的需要设置其它的参数
photos=flickr.walk(text=str(shuru),extras='url_c',tag_mode='all',tags='street')#使用walk方法获得图片的url
except Exception as e:
print('Error')
for photo in photos:                #遍历所有的url
url=photo.get('url_c')if count>0:
if str(url)!='None':           #url 有两种形式,一种为正确的url 一种为none,防止因为none而导致访问错误这里直接排除none
response=urllib.request.urlopen(url) #获得数据
cat_jpg=response.read(url)
with open ('photo'+str(count)+'.jpg','wb') as f: #下载图片
f.write(cat_jpg)
QString='已下载'+str(count) #显示已下载数量
count=count+1                  #累加,使得文件名字不重复

首先创建一个窗体。

把该导入的都导入进去

import sys
from PyQt5.QtWidgets import QWidget,
QPushButton,QGroupBox,
QApplication,QLabel,QLineEdit,QToolTip, QMessageBox,QFileDialog,QTextEdit,QProgressBar,QVBoxLayout
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QFont
from PyQt5.QtGui import QPixmap class Example(QWidget):
def __init__(self):                #没记错的话是构造器,与之相对应的是析构器(c++中的称呼)
super().__init__()
self.initUI()
def initUI(self): #设计界面
self.setGeometry(300, 200, 580, 400) #设置窗体尺寸
self.setWindowTitle('DeepLearn Lab') #命名窗体的标题
   def closeEvent(self, event): #重写关闭事件
reply = QMessageBox.question(self, '提示', #设计一个提示框
"确定要退出搜索程序吗?", QMessageBox.Yes |
QMessageBox.No, QMessageBox.No) #最后一个QMessageBox.No的意思是默认为no
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore()
if __name__ == '__main__': app = QApplication(sys.argv) #这三个是必不可少的部分
ex = Example()
sys.exit(app.exec_())

这样就创建了一个空白的窗口,点击×会出来提示,因为把closeevent这个函数重写了。

---------------------------------然后创建控件并链接相关的函数

---------------------------------举一个例子,该例子用于更改图片下载的路径

     self.btn2 = QPushButton('选择保存路径', self)   #设计保存下载路径的按钮
self.btn2.setToolTip('请输入储存图片的磁盘地址')
self.btn2.clicked.connect(self.filepath) #建立信号和槽的联系,将单击信号与下面的filepath进行链接
def filepath(self): #用于修改下载路径的函数
file_path=QFileDialog.getExistingDirectory(self) #获取选择的路径
os.chdir(file_path)                    #更改当前的工作路径

接下来创建一个容器把控件放进去(不放也可以,这仅仅只是为了好看)

-------------------------例子:

     self.groupBox = QGroupBox(self)                 #设置QT容器
self.groupBox.move(450, 105) #移动容器的位置
self.groupBox.resize(120,280) #设置容器的尺寸
self.groupBox.setTitle('菜单栏') #设置容器的标题
self.groupBox.setAlignment(4) #4为ALignHCenter为居中的意思(仅仅对上述的“菜单栏”有效)
                        这里的参数可以给0-4还是1-4我忘记了,不同的数字对应不同的对齐方式,可以挨个试试 layout = QVBoxLayout() #新建一个垂直布局
layout.addWidget(self.lineEdit) #往该布局中添加各种控件
layout.addWidget(self.btn2)
layout.addWidget(self.btn)
layout.addWidget(self.btn3)
self.groupBox.setLayout(layout) #显示该布局 一定要有这一步,不然容器不显示

剩下的就是一些控件的基本用法,可以参考代码,里面写的自认比较清楚简单。

用到的功能就下面这几个功能,使用方法和上述一样,就不一一赘述了。

from PyQt5.QtWidgets import QWidget,
QPushButton,QGroupBox,
QApplication,QLabel,QLineEdit,QToolTip, QMessageBox,QFileDialog,QTextEdit,QProgressBar,QVBoxLayout
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QFont
from PyQt5.QtGui import QPixmap

其实用QT Designer会更加方便快捷,本人当时没有时间学这个了,其实本人更推荐使用它,因为这样更加高效。

有什么问题可以评论留言,看见了会第一时间回复。