python使用PyQT5展示爬虫爬取过程实例

359

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

许多音乐网站为了良好的用户体验一般情况下对于爬虫的过滤规则相对较为宽泛,很多爬虫都是以数据采集为目的,上两篇博客中介绍了PyQT5的界面设计方法,由于在QyQT中拥有许多的控件,所以对于界面编程来说是一个非常漫长的学习过程,我有空的时候也会通过实例更新一些控件的使用方法,由深到浅。

今天主要是将爬虫采集到的音乐榜单以字典的形式显示到textEdit控件中,所以在界面中我们就需要将这个控件拖拽进去,下面的就是界面的代码,非常简单,就是两个按钮跟一个文本编辑框。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'searchMusic.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(1096, 886)
        self.horizontalLayoutWidget = QtWidgets.QWidget(Form)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 1081, 31))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.btstart = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btstart.setObjectName("btstart")
        self.horizontalLayout.addWidget(self.btstart)
        self.btclose = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btclose.setObjectName("btclose")
        self.horizontalLayout.addWidget(self.btclose)
        self.verticalLayoutWidget = QtWidgets.QWidget(Form)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 40, 1081, 841))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.textEdit = QtWidgets.QTextEdit(self.verticalLayoutWidget)
        self.textEdit.setObjectName("textEdit")
        self.verticalLayout.addWidget(self.textEdit)

        self.retranslateUi(Form)
        self.btclose.clicked.connect(Form.close)
        self.btstart.clicked.connect(Form.startTest)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.btstart.setText(_translate("Form", "爬取歌曲"))
        self.btclose.setText(_translate("Form", "关闭窗口"))

代码运行时,界面的风格大概是下面这个样子,看起来还是非常单调的,为了好理解这个过程,所以界面没有做过多的修饰,这样代码方便理解。

image.png

下面就是上面代码的调用函数,也是主函数,爬虫的实现过程也是在该函数中呈现的

import requests
from bs4 import BeautifulSoup
import time
from searchMusic import Ui_Form
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys


headers = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
}

class MainWindow(QMainWindow, Ui_Form):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        self.MyTimer = QTimer()
        self.index = 0

    def get_info(self):
        self.index += 1
        url = "https://www.kugou.com/yy/rank/home/{}-8888.html".format(str(self.index))
        web_data = requests.get(url, headers=headers)
        soup = BeautifulSoup(web_data.text, 'lxml')
        ranks = soup.select('span.pc_temp_num')
        titles = soup.select('div.pc_temp_songlist > ul > li > a')
        times = soup.select('span.pc_temp_tips_r > span')
        for rank, title, time in zip(ranks, titles, times):
            data = {
                "rank": rank.get_text().strip(),
                "singer": title.get_text().replace("\n", "").replace("\t", "").split('-')[1],
                "song": title.get_text().replace("\n", "").replace("\t", "").split('-')[0],
                "time": time.get_text().strip()
            }
            strData = str(data)
            self.textEdit.append(strData)
        if self.index == 23:
            self.MyTimer.stop()

    def startTest(self):
        self.MyTimer.start(1000)
        self.MyTimer.timeout.connect(self.get_info)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

代码中getinfo主要是爬虫的执行体,将爬虫的数据写入到textEdit也就是self.textEdit.append()这一句在起作用,所以说作为一个文本编辑框,其使用起来还是非常便的。

image.png

image.png

image.png

上面是整个程序的执行结果,需要说明的是,程序执行时需要用定时器来实现,不要使用while遍历url完成整个爬虫过程,这样会导致在爬取过程中界面一直处于假死状态,textEdit里面的内容也不会更新,直至while结束后才会突然更新整个textEdit界面,达不到实时交互的目的。

整个程序的逻辑非常简单,仅作为小例子展示,更复杂的功能在后期的博客中会慢慢实现。