PyQt5界面多线程多进程爬虫(爬了600w张网页, 出现了一些问题)

  • Post author:
  • Post category:其他



有个问题没解决: 将运行过程显示在右边的界面框里的光标问题(光标问题容易解决), 及异常退出的问题.


错误代码:

QObject::connect: Cannot queue arguments of type ‘QTextCursor’

(Make sure ‘QTextCursor’ is registered using qRegisterMetaType().)

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

原因: 意外退出的原因结果调试得出的结果应该是,使用QTextBrowser时,由于使用了多线程,因为使用的方式是将其当做参数传入函数由线程调用, 当一个线程运行完销毁时,销毁了传入的QTextBrowser, 由于线程数据共享所以也导致界面意外崩溃.


解决: 采用进程间的队列通信,使得前面的问题得到了解决.


在这里插入图片描述

在这里插入图片描述


这幅图存在上述问题.


代码:(测试过了, 有问题, 主要是抓取数据时, cpu占用率太高(进程\线程切换太费系统资源), 内存占用太大变量用完没有删除, 没时间就不改了, 先储存着, 以后有时间再改, 一个系统的功能还未完全, 比如: 数据库查找, 本地txt保存, 多线程多进程启动时QTextBrowser的数据显示问题; 代码存在的问题: 代码健壮性不足, 代码冗余, 链接获取取巧了)


主运行代码(

main.py

):

from uI import UserInterface
from moduleFunc import *
from PyQt5.QtWidgets import QApplication
import sys
# 逻辑运行区
def logicalArea(UI):
    dbName = pymongoInit(UI)
    UI.editA.clear()
    UI.editA.append('欢迎来到逻辑运行区!')
    # 保存+显示
    if UI.uIControl[5][1].isChecked():
        UI.editA.append('逻辑保存')
        if UI.uIControl[7][1].isChecked():
            UI.editA.append('逻辑开启多线程')
            # 显示所有小说的标题及保存所有小说的内容
            if UI.uIControl[11][1].isChecked():
                UI.editA.append('逻辑开启多进程')
                # 获取整个站点的小说(待完成)
                getAllNovelChapterInfo(UI, saveFlag=True, dbName=dbName)
            # 获取一本小说的总info, 及保存小说(已完成)
            else:
                UI.editA.append('逻辑未开多进程')
                saveNovelChapterInfo(UI, dbName)
        else:
            UI.editA.append('逻辑未开多线程')
            # 显示所有小说的标题和url及保存相应信息
            if UI.uIControl[11][1].isChecked():
                UI.editA.append('逻辑开启多进程')
                # 显示并保存一个站点所有的小说信息
                saveAllNovelInfo(UI, dbName)
            # 显示单篇小说的内容及保存该内容至指定数据库*********************
            else:
                UI.editA.append('逻辑未开多进程')
                saveSimgleArt(UI, dbName)
    else:
        UI.editA.append('逻辑只显示')
        # 显示
        if UI.uIControl[7][1].isChecked():
            UI.editA.append('逻辑开启多线程')
            if UI.uIControl[11][1].isChecked():
                UI.editA.append('逻辑开启多进程')
                # 显示一个站点所有小说及每部小说的详细信息的信息(待完成----未开多线程深入一部, 多进入一个网页)
                getAllNovelChapterInfo(UI)
            else:
                UI.editA.append('逻辑未开多进程')
                # 显示一部小说的信息
                getNovelChapterInfo(UI=UI)
        else:
            UI.editA.append('逻辑未开多线程')
            # 显示所有小说的名字及url
            if UI.uIControl[11][1].isChecked():
                UI.editA.append('逻辑开启多进程')
                # 显示所有小说信息
                getAllNovelInfo(UI)
            else:
                UI.editA.append('逻辑未开多进程')
                # 显示一篇小说
                simgleArt(UI)
def initData(UI):
    UI.uIControl[0][1].setText('http://www.xbiquge.la/15/15409/')
    UI.uIControl[3][1].setText('<div id="content">(.*?)<p>.*?</p>*.?</div>')
    UI.uIControl[6][1].setText('<h1>(.*?)</h1>')
    UI.uIControl[8][1].setText("<dd><a href='(.*?)' >(.*?)</a></dd>")
    UI.uIControl[10][1].setText(str(16))
    UI.uIControl[12][1].setText(str(4))
    UI.uIControl[13][1].setText('<li><a href="(.*?)">(.*?)</a></li>')
    UI.uIControl[2][1].setText('道君')
    UI.uIControl[14][1].setText('biquge')
def main():
    app = QApplication(sys.argv)
    UI = UserInterface()
    initData(UI)

    UI.uIControl[4][1].clicked.connect(lambda: logicalArea(UI))
    sys.exit(app.exec_())
if __name__ == '__main__':
    main()


自定义函数部分(

moduleFunc.py

):

import pymongo, requests, re, os
from PyQt5.QtWidgets import QMessageBox
from threading import Thread
from multiprocessing import Process, Pool
# 创建数据库连接
def pymongoInit(UI):
    client = pymongo.MongoClient('localhost', 27017, connect=False)
    dbName = UI.uIControl[14][1].text()
    biquge = client[dbName]
    return biquge
# 创建数据表(已完成)
def pymongeUser(UI=None, biquge=None, name=None, data=None, mulSaveFlag=False):
    try:
        table = biquge[name]
    except:
        if not mulSaveFlag:
            UI.queue.put('<font color=red>创建数据库{}失败</font>'.format(name))
        else:
            print('\033[31;0m创建数据库{}失败\033[0m'.format(name))
        return 0
    # 判断重复
    if data['title'] not in [article['title'] for article in table.find()]:
        table.insert_one(data)
        if not mulSaveFlag:
            UI.queue.put('<font color=green>{0} {1} {2}</font>'.format(name, data['title'], '数据存入成功'))
        else:
            print(('\033[32;0m{0} {1} {2}\033[0m'.format(name, data['title'], '数据存入成功')))
    else:
        # 存入的数据content是列表时,执行本操作
        if isinst



版权声明:本文为weixin_43690548原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。