zoukankan      html  css  js  c++  java
  • 简单的爬虫程序以及使用PYQT进行界面设计(包含源码解析)

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

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

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

      可以使用pip install  来安装flickrapi和pyqt5pyqt5-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会更加方便快捷,本人当时没有时间学这个了,其实本人更推荐使用它,因为这样更加高效。

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

  • 相关阅读:
    非正式介绍Python(二)
    用js采集网页数据并插入数据库最快的方法
    一张图轻松记住PHP的*类*以及private和protected的区别
    从php到浏览器的缓存机制,不得不看!
    webpack 兼容低版本浏览器,转换ES6 ES7语法
    DEDE织梦 后台特别卡,有时响应超时的解决办法
    vue iview Select bug,在低版本浏览器中报错
    mysql_connect 等待时间长,修改连接地址为127.0.0.1即可
    看完这篇文章才对【GIT】有了大彻大悟的认识
    一次请求对多条数据进行排序的算法(二)
  • 原文地址:https://www.cnblogs.com/zedd/p/11953833.html
Copyright © 2011-2022 走看看