由于这个是毕业设计的内容,而且还是跨专业的。爬虫程序肯定是很简单的,就是调用Yahoo的API进行爬取图片。这篇博客主要讲的是基础的界面设计。
放上源码,然后分部解析一下重要的地方。注:flickrapi需要翻墙
代码复制的时候可能掉几个字母或者符号,不建议复制代码,如需复制请自行检查是否有拼写错误
可以使用pip install 来安装flickrapi和pyqt5和pyqt5-tools
总体界面如图所示:
下面是源码:
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("帮助文档: 1.输入搜索图片的关键字 2.选择图片储存路径,如不选择默认使用程序所在路径 3.单击开始进行下载") 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:UsersAdministratorDesktopsvchost.exelogo2.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会更加方便快捷,本人当时没有时间学这个了,其实本人更推荐使用它,因为这样更加高效。
有什么问题可以评论留言,看见了会第一时间回复。