给Python爬虫做一个界面.上

96
Garfield_Liang
0.1 2017.04.13 07:45* 字数 1973

<p>做爬虫做了那么久,开始逐渐不满足写好程序,每次只能完成一件事情。开始思考如何可以做一个简单界面交互,再增加爬虫的可操作室,做交互界面有两个思路:</p>

  • 用Django做一个web界面;
  • 用PyQt做一个exe程序界面;

<p>事实上在我写这一篇文章的时候,已经完成PyQt的demo,再开始思考两种方式的优劣。后来想通了,web界面可以无缝隙跨平台跨系统进行沟通,所以采用html语言的web界面会是以后的交互主体。可是这不妨碍我们先看一看Pyqt,这一篇文章先介绍怎么用PyQt来做exe界面。</p>

<p>这篇文章会偏向于Pyqt的介绍,爬虫之前已经有比较多的文章介绍了,在这里更多的是介绍怎么做Pyqt的界面,以及将我们的爬虫嵌入到界面内。</p>

先写个爬虫

<p>这一次我们来采集点喜闻乐见的内容妹子图,我们目标是扒出首页所有妹子图的链接。这个网站的逻辑比较简单,直接首页get之后,再通过BeautifulSoup的各种find就能扒到所有的链接。当然,如果比较贪心的,可以在里面再加上翻页器的功能,具体就是在链接后面加入/page/(page_number)就可以了,page_number是相应的页数,,</p>

<p>不带翻页器,写了一个专门爬妹子图的类,附带效果图,输出每个页面链接的id以及titlte,通过页面id我们可以进入到title对应的页面进一步的做我们想做的嘿嘿嘿。</p>

class Mzitu():
    
    def __init__(self):
        url = "http://www.mzitu.com/"
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
                   'Host': 'www.mzitu.com'}
        response = requests.get(url, headers = headers)
        content = BeautifulSoup(response.text, 'lxml')
        linkblock = content.find('div', class_="postlist")
        self.linklist = linkblock.find_all('li')
    
    def getli(self):
        linklist = self.linklist
        linksum = dict()
        
        for link in linklist:
            url = link.a.get('href')
            linkid = re.search(r'(\d+)', url).group()
            firstspan = link.span
            titleword = firstspan.get_text()
            secondspan = firstspan.find_next_sibling('span')
            uploadtime = secondspan.get_text()
            thirdspan = secondspan.find_next_sibling('span')
            viewcount = thirdspan.get_text()
            title = "%s 发布在%s 共浏览%s" % (titleword, uploadtime, viewcount)
            linksum[linkid] = title
        return linksum
嗯,效果图

<p>在之前的Python爬虫项目中,基本就是止于此,将所有链接爬出来后,再一个链接一个链接的进入,做我们想做的事情。但如果我现在和你说,我不要所有链接都进入,进入哪些链接,我要通过title或者浏览次数,甚至是图片判断。那这个时候,我们就要有一个交互页面给我们的用户,这个界面给我们的用户筛选他喜欢的链接进行选择性的下载。</p>


先举个例子教你做界面

<p>简单介绍一下PyQt是个什么。PyQt就是Python语言的GUI编程解决方案之一。在PyQt5中,可通过自带的Creator工具生成窗体文件,并通过内置函数uic转化为Python代码。</p>

<p>简单来说,你可以通过Qt Creator(PyQt4是叫做Qt Designer,此处只以Qt Creator为例,官网下载度盘下载)画出你想要的任何界面,再使用内置函数uic或者外部命令pyuic转化为Python代码,然后将生成的Python代码和你自身的程序关联就可以。盗用老外的一张流程图:</p>

[流程图](http://projects.skylogic.ca/blog/how-to-install-pyqt5-and-build-your-first-gui-in-python-3-4/)

<p>安装是很简单的,这个软件本身是开源的,选择非商业用途就可以一直使用,一路下一步安装完毕。完成后打开界面,Ctrl+N新开一个文档之后,依次选择Qt以及Qt Designer Form之后,选好工作目录,就可以进入设计页面。在设计页面上将左侧的元素,拖拽到中间的设计页面就摆放好即可,做好后保存就能生成一个.ui后缀名的文件:</p>

使用界面
新建一个页面
设计页面

<p>假如现在需要做一个加法器,实现两个数字a和b的相加,数字a和b的通过数字输入。拖拽元素将这个界面完成,效果如下图。左边有简单的加法输入以及输出显示框,点击下面计算按钮开始计算,右边有一个输出历史计算的页面。元素列表处可以看到各个拖拽元素的名称以及对应的类,所有的这些元素都在MainWindow以及centralwidget上面。</p>

<p>记住我们所设定的元素输入textEdit、textEdit_2、元素输出textEdit_3、历史记录输出textBrowser、以及计算按钮pushButton所对应的元素名称。</p>

计算器页面以及元素列表

<p>保存后,会在工作目录上出现一个以.ui后缀为名的文件,通过notepad++打开了,可以发现内部就是一个xml文件。现在需要将这个窗体文件转化为python文档,PyQt给我们提供了两个方式,一个是通过外部命令pyuic5,一个是内置函数uic。</p>

mainwindow.ui
外部命令pyuic5

<p>用外部命令pyuic5可以将.ui的文件转化为.py的文件,在.ui所在文件夹空白处按着shift鼠标点右键,打开控制命令行,输入:</p>

pyuic5 -x mainwindow.ui -o mainwindow.py

<p>pyuic是一个转化工具,通过查看pyuic.bat的代码,知道其本质是调用PyQt5.uic.pyuic,点开生成的mainwindow.py文件,点开运行一下,便可以看到界面。在上面输入任何数字,但不能计算,没有任何内容显示。我们需要对mainwindow.py进行修改,将元素和函数关联:</p>

计算器界面

<p>在mainwindow.py里面,setupUI是用来生成整个界面的函数,里面包括对元素位置、大小、字体、对象名称、对象间关系。retranslateUi应该是对文字的转化,具体要看QtCore.QCoreApplication.translate的说明文档。最后的主体main函数,是生成窗体对象、窗体显示以及退出,是pyuic5命令中的-x参数生成。</p>

<p>通过toPlainText引用textEdit以及textEdit_2的数字,在addfunction内完成加法运算,最后将结果输出到textEdit_3里面,并通过textBrowser.append来保存计算过程。计算界面如图所示:</p>

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        ... ...  ##此处太长省略了
        self.pushButton.clicked.connect(self.addfunction) ##用来将pushButton关联加法的函数
        
    def addfunction(self):  ##用来实现加法的函数
        a = float(self.textEdit.toPlainText())
        b = float(self.textEdit_2.toPlainText())
        c = a + b
        self.textEdit_3.setText(str(c))
        self.textBrowser.append("%.2f + %.2f = %.2f" % (a, b, c))

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "加法计算器"))
        self.label_2.setText(_translate("MainWindow", "+"))
        self.label_3.setText(_translate("MainWindow", "="))
        self.pushButton.setText(_translate("MainWindow", "计算"))

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
计算界面
通过uic内部转化

<p>上面这种方法最好的地方在于,你可以通过更改代码的方式对界面进行更改。但事实上,对于一个爬虫界面而言,需求复杂的还是比较少,并且不熟悉编程的人会更依赖在Qt Creator上做更改,那这样每次都需要通过外部命令去更新界面程序文件就会显得有点繁琐。可以考虑采用内部命令uic,直接加载.ui文件进行操作:</p>

import sys
from PyQt5 import uic, QtWidgets

(form_class, qtbase_class) = uic.loadUiType('mainwindow.ui')

class MainWindow(qtbase_class, form_class):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.addfunction)
    
    def addfunction(self):
        a = float(self.textEdit.toPlainText())
        b = float(self.textEdit_2.toPlainText())
        c = a + b
        self.textEdit_3.setText(str(c))
        self.textBrowser.append("%.2f + %.2f = %.2f" % (a, b, c))
       
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ui = MainWindow()
    ui.show()
    sys.exit(app.exec_())

<p>uic.lodUiType该函数输出两个类,一个是form class,一个是Qt base class。根据链接的说明文件,form class 仅仅是一个类,衍生自Python object type,Qt base class是一个ui的框架类,这个框架就类似于QDialog、QWidget以及QMainWindow。(但是这两个类的具体情况还是没有弄清楚,ui的基本特征是哪个class提供,通过super继承是如何使这两个类运行起来的,等等)。</p>

<p>后一个方法相对会更加方便,更改ui之后,不需要经过外部命令就可以直接调用,适合前提调试;如果是ui已经成熟了,用第一个方法的一致性会更好。</p>


小结

<p>通过这一篇文章,我们已经将所有的素材备齐了,下一篇文章,需要将这两者结合起来。我们要对爬下来的内容做一个筛选界面,然后爬虫最终根据我们的筛选来输出链接。</p>

爬虫&数据分析