给Python3爬虫做一个界面.妹子图网实战 3

给Python爬虫做一个界面.概述

一、实验简介

1.1 实验内容

通过 PyQt 给妹子图网的Python爬虫做一个交互界面,从而对 PyQt 有初步的理解,并学会如何使用 Qt Creater 做界面以及实现基础功能。课程分为三个部分:

  1. 了解如何将 Qt Creator 生成的界面导入的 Python 的环境中,并完成一个计算器Demo;
  2. 学会再实现 PyQt 中,完成图片预览以及元素列表两个Demo;
  3. 完成妹子图网爬虫的交互界面。

这是本课程的第一次实验。在这里先给大家看看,学完这三节课之后,最后我们要完成的效果:

1.2 实验知识点

  • PyQt 相关知识
  • Python Qt 编程

1.3 实验环境

  • Xfce终端
  • Python 3.x.x

1.4 适合人群

本课程难度属于一般,属于初级级别课程,适合具有 Python 基础的用户,熟悉 Python 基础知识加深巩固。

二、实验目的

通过本次实验,学会如何在如何结合 PyQt 以及 Python, 完成图片预览以及元素列表两个Demo。

三、开始实验

3.1 环境配置

本实验环境采用win10环境,实验中会用到的程序:

  1. Qt Creator: 一个轻量级界面开发环境,其设计目标是设计目标是使开发人员能够利用 Qt 这个应用程序框架更加快速及轻易的完成开发任务。
  2. requests:是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库
  3. beautifulsoup: 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。(在本节课需要用到)

前面的文章已经介绍过如何使用pyqt5,以及如何搭配环境,此处便不再重复。

3.2 配置爬虫

在写爬虫之前,我们先来看看妹子图网的首页。页面的主要内容是由24个图框组成,查看页面的源代码(View page source),我们可以轻易知道其网页的构造,每一个li节点里面包含每一个链接里面包含:标题、原图链接、跳转链接、发布时间以及浏览次数。如果要翻下一页,只需要更改网址后缀,即在链接后面加入/page/(page_number)就可以了,page_number是相应的页数,妹子图的详细爬虫教程可以参考这个大大的文章

class Mzitu():

    def __init__(self, url):
        self.url = url
        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(self.url, headers = headers)
        content = BeautifulSoup(response.text, 'lxml')
        linkblock = content.find('div', class_="postlist")
        self.linklist = linkblock.find_all('li')

    def printli(self):
        linklist = self.linklist
        linksum = list()

        for link in linklist:
            url = link.a.get('href')
            picurl = link.img.get('data-original')
            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()
            linksum.append((linkid, titleword, uploadtime, viewcount, picurl))
        return linksum

3.3 配置PyQt界面

首先是制作ui界面,拖曳3个Push Button 分别作为翻页的上页(pushButton_uppage)和下页(pushButton_nextpage)以及获得链接的开关(pushButton),拖曳Table Widget作为我们放置页面内容(tableWidget),拖曳2个Label分别作为页数显示(label_pagenum)以及图片输出(label),拖曳Text Browser作为我们链接输出(textBrowser)。

保存后好,对ui文件的进行加载:

import re, requests
from bs4 import BeautifulSoup
from PyQt5.QtWidgets import QApplication, QCheckBox, QPushButton, QHeaderView
from PyQt5.QtGui import QPixmap
import PyQt5.uic

ui_file = 'Demo.ui'
(class_ui, class_basic_class) = PyQt5.uic.loadUiType(ui_file)

 

主类先继承 form class 以及 qt base class ,然后调用爬虫的 class 来生成首页内容的列表,根据首页的内容数量来确定 Table Widget 的行数,并设定相应列宽以及行高,最后是将 Check Box 以及 Push Button 放置在 Table Widget 中,并且对其中的 Push Button 与相应的功能函数进行关联:

class Window(class_basic_class, class_ui):

    def __init__(self):
        super(Window, self).__init__() 
        self.url = "http://www.mzitu.com/"
        self.setupUi(self)
        totlist = Mzitu(self.url).printli()
        self.tableWidget.setRowCount(len(totlist))
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setColumnWidth(0, 435)
        verticalHeader = self.tableWidget.verticalHeader()
        verticalHeader.setSectionResizeMode(QHeaderView.Fixed)
        verticalHeader.setDefaultSectionSize(30)
        self.textBrowser.setOpenExternalLinks(True)  ##隐藏列表头
        self.page = 1  ##设定初始的页面数,为后面做翻页器做准备
        self.label_pagenum.setNum(self.page)  
        self.checkBoxs = [self._addCheckbox(index, item[0], item[1]) for index, item in enumerate(totlist)]
        self.pushButtons = [self._addpushButtonpic(index, item[0], item[4]) for index, item in enumerate(totlist)]
        self.pushButton.clicked.connect(self.getSelList)
        self.pushButton_nextpage.clicked.connect(lambda: self._nextPage(1))
        self.pushButton_uppage.clicked.connect(lambda: self._nextPage(-1))

 

_addCheckbox 用于生成 Check Box 单元,并将单元通过 setCellWidget 关联到 Table Widget 对应位置中。每一个 Check Box 最终都用 isChecked() 函数来判断是否有被勾选上,getSelList 是用来在 textBrowser 中输出对应内容的名称以及链接,注意链接这里我为了可以直接点开,而不需要复制到浏览器里面才能打开,所以采用 html 文本书写,以达到超级链接的效果:

    def _addCheckbox(self, index, idd, boxtitle):
        checkBox = QCheckBox()
        checkBox.setObjectName(idd)
        checkBox.setText(boxtitle)
        self.tableWidget.setCellWidget(index, 0, checkBox) ##setCellWidget前面两个数字分别代表行和列,最后是需要关联的元素
        return checkBox

    def getSelList(self):
        selList = [(item.objectName(), item.text()) for item in self.checkBoxs if item.isChecked() == True]
        for item in selList:
            url = 'http://www.mzitu.com/'+item[0]
            self.textBrowser.append(item[1])
            self.textBrowser.append('<a href = %s>%s</a>' % (url, url))  ##此处输出超级链接
        return selList

 

_addpushButton 是用于在 Table Widget 中关联 Push Button,方法和上述 Check Box 类似。注意 Push Button 关联函数那里,我使用了 Lambda 表达式。_showpic 就是一个在 Label 中输出图片的功能,具体在之前 Demo 那里已经做过叙述:

    def _addpushButtonpic(self, index, idd, href):
        pushButton = QPushButton()
        pushButton.setObjectName(idd)
        pushButton.setText(idd)
        self.tableWidget.setCellWidget(index, 1, pushButton)
        self.pushButton.clicked.connect(lambda: self._showpic(idd, href))
        return pushButton

    def _showpic(self, idd, href):
        pic = requests.get(href).content
        pixmap = QPixmap()
        pixmap.loadFromData(pic)
        self.label.setPixmap(pixmap)

 

_nextPage 是实现翻页器功能,一开始是考虑只做下一页的,但使用中发现不方便。所以需要增加向上翻的功能,这是通过将翻页数分别设定为+1改成-1来实现的。更换了页码之后,需要重新通过爬虫 class 获得新页面的内容,并重新用 _addCheckbox 以及 _addpushButto n函数来更新 Check Box 以及 Push Button 的内容,最后输出新的 self.checkboxs 以及 self.pushButtons:

    def _nextPage(self, page):
        self.page += page
        self.label_pagenum.setNum(self.page)
        url = self.url + '/page/' + str(self.page)
        totlist = Mzitu(url).printli()
        newcheckBoxs = []
        newpushButtons = []
        for index, item in enumerate(totlist):
            newcheckbox = self._addCheckbox(index, item[0], item[1])
            newpushbutton = self._addpushButtonpic(index, item[0], item[4])
            newcheckBoxs.append(newcheckbox)
            newpushButtons.append(newpushbutton)
        self.checkBoxs = newcheckBoxs
        self.pushButtons = newpushButtons

 

最后我们来看看最终效果图。

三、实验总结

最后,我们完整的程序就完成了,后面可以通过py2exe转化是window实际可以操作的执行程序,限于篇幅这里没有写道,整个 Table Widget 还可以加入浏览数、新增时间以及全选等功能,来完善整个体验。最后相信精明的老司机已经发现,既然获得链接,通过爬虫可以进一步获得链接后面的图片,然后通过筛选就可以将喜欢的图片下载到自己的硬盘里面了。

猜你喜欢

转载自blog.csdn.net/zulien/article/details/84990548