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

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

  • 相关阅读:
    mac os programming
    Rejecting Good Engineers?
    Do Undergrads in MIT Struggle to Obtain Good Grades?
    Go to industry?
    LaTex Tricks
    Convert jupyter notebooks to python files
    How to get gradients with respect to the inputs in pytorch
    Uninstall cuda 9.1 and install cuda 8.0
    How to edit codes on the server which runs jupyter notebook using your pc's bwroser
    Leetcode No.94 Binary Tree Inorder Traversal二叉树中序遍历(c++实现)
  • 原文地址:https://www.cnblogs.com/zedd/p/11953833.html
Copyright © 2011-2022 走看看