爬取QQ空间好友点赞数据——Python+PyQt5(北邮期末python大作业)

 效果展示:

编辑

功能介绍:输入好友昵称,获取在QQ空间中,谁给TA点赞最多和TA给谁点赞最多的数据

目录

一,获取登录信息

二, 进行数据爬取

1.寻找要爬取的点赞信息

2.定位每一条说说

3.获取所有QQ好友信息

4.Threadpool多线程处理

5.参数获得与文件处理

6.第二部分代码

三,数据分析

四,UI展示——PyQt5

五,代码过程与遇到的问题


 

 

一,获取登录信息

既然决定了要对QQ空间进行信息爬取,那么作为一个需要账号密码进入的私人网页,首先需要的就是请求里的cookie信息,这样我们在后续爬取的过程中才能跳过登录,直接获取信息。

原本想使用Chrome handless的方式无窗口登录,但传统的账号密码登录需要手机验证码,尝试扫描二维码的方式却又发现使用urlretrive下载的二维码图片会被刷新更新而不可使用。

最后选择了最基础的selenium方式,打开浏览器界面,只需要简单登录,等待5s后页面会自动关闭,而后也就获取到了cookie信息,简单明了而又方便。

编辑

这里使用的代码是第一个程序文件:cookie_load.py

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
import json
from selenium.webdriver.common.by import By

# 采用最基础的selenium有窗口式登录方法,原本想用handless,但发现账号密码登录要手机验证,二维码扫描用urlretruve无法搞定,遂作罢
# 这种方式简单直接且有效,何乐而不为

# 加载谷歌驱动
path = 'chromedriver.exe'
s = Service(executable_path=path)
browser = webdriver.Chrome(service=s)

# 进入自己的QQ空间主页
url = 'https://user.qzone.qq.com/你的QQ'
browser.get(url)
sleep(5)

# 保存本地的cookie
cookies = browser.get_cookies()
cookie_dic = {}
for cookie in cookies:
    if 'name' in cookie and 'value' in cookie:
        cookie_dic[cookie['name']] = cookie['value']
    with open('cookie_dict.txt', 'w') as f:
        json.dump(cookie_dic, f)

二, 进行数据爬取

1.寻找要爬取的点赞信息

首先我们进入空间,点击说说,进入说说模块 编辑

而后找到其中一条说说,点击“等45人”处,会弹出点赞的好友列表

观察右侧Network响应,会发现有一个get_like_list_app,通过preview可以看出其中包含了所有点赞好友的信息,可以说是很详细了,昵称,QQ号,性别,星座,地区都有。

这时我们可以确定,它就是我们要爬取的信息辣

编辑

此时就要找每一条说说的get_like_list的url之间的规律,观察相邻几条说说的get_like_list的url,可以发现,只有参数tid是不同的,每一条说说,对应唯一的tid

编辑

之后我们的任务就是寻找每一个说说所对应的tid,也就是定位每一个说说的信息了,让我们回到说说主页,刷新界面,继续寻找包含了整页说说信息的端口

实现这部分功能爬取的代码如下,其中的参数m是下一个部分获得的说说信息

# 获取点赞信息数据(从说说“等人”处发现)
    def get_like(self, m, qq, name):
        g_tk = self.get_gtk()
        uin = self.get_uin()
        tid = m['tid']
        # 原始链接
        url_like = 'https://user.qzone.qq.com/proxy/domain/users.qzone.qq.com/cgi-bin/likes/get_like_list_app?'
        # 进行拼接
        data_like = {
            'uin': uin,
            'unikey': 'http://user.qzone.qq.com/' + str(qq) + '/mood/' + str(tid) + '.1',
            'begin_uin': 0,
            'query_count': 60,
            'if_first_page': 1,
            'g_tk': g_tk
        }
        data_like_encode = urllib.parse.urlencode(data_like)
        url_like = url_like + data_like_encode
        res = requests.get(url_like, headers=header, cookies=cookie)
        res.encoding = 'UTF-8'
        like_data = re.findall('\((.*)\)', res.text, re.S)[0]
        like_message = json.loads(like_data)
        # 数据量太大,请求繁忙导致部分页码可能无法请求到,错误跳出
        try:
            for l in like_message['data']['like_uin_info']:
                file_like.write(name + '<-' + str(l['nick']) + '\n')
        except KeyError:
            print(name)
            print(like_message)

2.定位每一条说说

回到说说主页,刷新界面,观察右侧端口,发现其中emotion_cgi_msglist_v6

点开发现,它包含了一整页说说的详细信息

编辑

通过爬取它的内容,我们就可以定位到当页的每一条说说

而后和上一步一样,观察每一页说说的url,寻找规律,发现不同页码的 emotion_cgi_msglist_v6的url,只有参数pos发生了变化,第一页的pos=0,第二页的pos=20,以此类推。

这样一来,我们就能够通过拼接url来批量爬取所有页码的说说了

通过函数locate来实现这个功能,代码如下:

'''
    通过此函数对每一个人的QQ空间进行爬取
    先爬取说说每一页整页数据,通过对比发现,一页有二十个说说,不同页的说说url受参数pos控制
    然后根据每一页的信息对每一个说说进行定位
    '''

    def locate(self, qq, name):
        g_tk = self.get_gtk()
        uin = self.get_uin()
        # 标记第几页
        page = 1
        pos = 0
        # 循环爬取每一页的内容
        while True:
            # 初始url
            emotion_url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?'
            # 对url进行拼接
            emotion_data = {
                'uin': qq,
                'pos': pos,
                'num': 20,
                'hostUin': qq,
                'replynum': 100,
                'callback': '_preloadCallback',
                'code_version': 1,
                'format': 'jsonp',
                'need_private_comment': 1,
                'g_tk': g_tk,
            }
            emotion_url = emotion_url + urllib.parse.urlencode(emotion_data)
            # 对内容进行读取
            res = requests.get(emotion_url, headers=header, cookies=cookie)
            r = re.findall('\((.*)\)', res.text)[0]
            with open(f'find/testfind{name}_{page}.json', 'w', encoding='utf-8') as fp:
                fp.write(r)
            message = json.loads(r)
            print(f'成功读取{name}的第{page}页说说')
            # 进行翻页操作
            pos += 20
            page += 1
            # 判断是否结束操作
            # 没有说说
            if 'msglist' not in message:
                break
            # 爬取完毕
            if message['msglist'] == None:
                print(f'{name}的空间爬取结束')
                break
            # 对每一个说说进行处理
            for m in message['msglist']:
                # 获取点赞信息数据
                self.get_like(m, qq, name)

3.获取所有QQ好友信息

我们希望能够得到一个比较大的数据量——即爬取所有好友的说说信息,而后展开数据分析。

因此在上述步骤我们已经拥有爬取一个好友的所有说说信息之后,我们需要获得所有好友的信息(昵称+QQ号),从而循环爬取所有好友的信息。

获得所有好友信息的端口仍然从QQ空间找到。

点开我的说说,点击“@”按键,系统将弹出所有的好友供你选择@谁,同时观察右侧的network端口,出现了friend_show_qqfriends.cgi,一个从名称上看起来就很像我们要寻找的端口,进入发现,果然包含了所有好友的信息。

编辑

之后仍然和之前的步骤一样,不过这次省去了寻找url规律的过程,通过requests方法获得数据并处理,就得到了我们所有的好友数据。

这部分的功能通过函数get_friend实现,代码如下:

# 获取好友信息,并将其存在一个列表中
    # 获取所有的好友{姓名,备注,QQ号,头像}
    def get_friend(self):
        # @按键的原始url,自己的url需要进行参数拼接
        at_url = 'https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_show_qqfriends.cgi?'
        g_tk = self.get_gtk()
        uin = self.get_uin()
        data = {
            'uin': uin,
            'do': 1,
            'g_tk': g_tk
        }
        # urlencode方法,进行url拼接
        new_data = urllib.parse.urlencode(data)
        at_url = at_url + new_data
        # requests方法,获取网页数据
        res = requests.get(at_url, headers=header, cookies=cookie)
        # 获取好友信息的数据
        friend_json = re.findall('\((.*)\)', res.text, re.S)[0]
        with open('friend_list.json', 'w', encoding='utf-8') as fp:
            fp.write(friend_json)
        # 将数据转换为python中的字典形式
        friend_dict = json.loads(friend_json)
        friend_result_list = []
        # 循环将好友的姓名qq号存入列表中(需要观察上面的friend_list.json文件)
        for friend in friend_dict['items']:
            friend_result_list.append([friend['name'], friend['remark'], friend['uin'], friend['img']])
        # 得到的好友字典是{name:remark:uin:img}格式的
        # print(friend_result_list)
        return friend_result_list

    # 裁剪好友列表函数
    def refine(self):
        r_list = []
        for friend in self.get_friend():
            r_list.append([friend[2], friend[0]])
        return r_list

    # 判断是否为共同好友的函数,返回一个QQ号组成的列表
    def uinlist(self):
        uin_list = []
        for friend in self.get_friend():
            uin_list.append(friend[2])
        return uin_list

4.Threadpool多线程处理

在完成了上述的工作后,我们已经具备了爬取所有好友说说点赞信息的能力。但实际操作起来爬取一个好友的一页说说就需要2~3秒的时间,爬取所有好友的所有说说时间不可估计。

因此我们需要提高爬虫的速度,采用threadpool多线程处理的方法,有一个固定的模板,因此操作起来相对简单,套用即可,使用后效果甚佳,速度大大提升。

通过函数start实现,代码如下:

# 开始运行端口
    # 使用多线程threadpool进行实现,提升效率
    def start(self):
        r_list = self.refine()
        # 开启15个线程
        pool = threadpool.ThreadPool(10)
        # 提交任务到线程池
        requests = threadpool.makeRequests(self.get, r_list)
        # 开始执行任务
        for req in requests:
            pool.putRequest(req)  # 提交
        pool.wait()

5.参数获得与文件处理

这里回顾一下第二部分数据爬取的两个细节问题。

参数获得,在进行url的parse.urlencode拼接时,需要两个关键的参数:uin和gtk,其中uin就是自己的qq号码,通过cookie信息可以得到,gtk是一个重要的参数,几乎所有url拼接中都要用到它,它的获得方式我们在网上可以查到,是通过函数计算而得 的。

通过get_uin和get_gtk两个函数可以获得两个参数,代码如下:

# 得到uin,即自己的QQ账号,需要进行一下裁剪
    def get_uin(self):
        uin = cookie['uin'][1:]
        return uin

    # 获取gtk参数,计算方法从网上可查的(重要参数)
    def get_gtk(self):
        p_skey = cookie['p_skey']
        h = 5381
        for i in p_skey:
            h += (h << 5) + ord(i)
            g_tk = h & 2147483647
        return g_tk

第二部分获得的数据如何为之后的数据分析所用呢,我们这里采取的是存为一个like.txt的方式,供后续读取。

 

 

6.第二部分代码

 第二部分整体由文件data_collect.py实现

代码如下:

import urllib
import requests
import json
import re
import threadpool
import urllib.parse
import time
import operator as op
import csv


# 将对QQ空间的操作封装为一个类
class Qzone:
    # 得到uin,即自己的QQ账号,需要进行一下裁剪
    def get_uin(self):
        uin = cookie['uin'][1:]
        return uin

    # 获取gtk参数,计算方法从网上可查的(重要参数)
    def get_gtk(self):
        p_skey = cookie['p_skey']
        h = 5381
        for i in p_skey:
            h += (h << 5) + ord(i)
            g_tk = h & 2147483647
        return g_tk

    # 获取好友信息,并将其存在一个列表中
    # 获取所有的好友{姓名,备注,QQ号,头像}
    def get_friend(self):
        # @按键的原始url,自己的url需要进行参数拼接
        at_url = 'https://user.qzone.qq.com/proxy/domain/r.qzone.qq.com/cgi-bin/tfriend/friend_show_qqfriends.cgi?'
        g_tk = self.get_gtk()
        uin = self.get_uin()
        data = {
            'uin': uin,
            'do': 1,
            'g_tk': g_tk
        }
        # urlencode方法,进行url拼接
        new_data = urllib.parse.urlencode(data)
        at_url = at_url + new_data
        # requests方法,获取网页数据
        res = requests.get(at_url, headers=header, cookies=cookie)
        # 获取好友信息的数据
        friend_json = re.findall('\((.*)\)', res.text, re.S)[0]
        with open('friend_list.json', 'w', encoding='utf-8') as fp:
            fp.write(friend_json)
        # 将数据转换为python中的字典形式
        friend_dict = json.loads(friend_json)
        friend_result_list = []
        # 循环将好友的姓名qq号存入列表中(需要观察上面的friend_list.json文件)
        for friend in friend_dict['items']:
            friend_result_list.append([friend['name'], friend['remark'], friend['uin'], friend['img']])
        # 得到的好友字典是{name:remark:uin:img}格式的
        # print(friend_result_list)
        return friend_result_list

    # 裁剪好友列表函数
    def refine(self):
        r_list = []
        for friend in self.get_friend():
            r_list.append([friend[2], friend[0]])
        return r_list

    # 判断是否为共同好友的函数,返回一个QQ号组成的列表
    def uinlist(self):
        uin_list = []
        for friend in self.get_friend():
            uin_list.append(friend[2])
        return uin_list

    '''
    通过此函数对每一个人的QQ空间进行爬取
    先爬取说说每一页整页数据,通过对比发现,一页有二十个说说,不同页的说说url受参数pos控制
    然后根据每一页的信息对每一个说说进行定位
    '''

    def locate(self, qq, name):
        g_tk = self.get_gtk()
        uin = self.get_uin()
        # 标记第几页
        page = 1
        pos = 0
        # 循环爬取每一页的内容
        while True:
            # 初始url
            emotion_url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?'
            # 对url进行拼接
            emotion_data = {
                'uin': qq,
                'pos': pos,
                'num': 20,
                'hostUin': qq,
                'replynum': 100,
                'callback': '_preloadCallback',
                'code_version': 1,
                'format': 'jsonp',
                'need_private_comment': 1,
                'g_tk': g_tk,
            }
            emotion_url = emotion_url + urllib.parse.urlencode(emotion_data)
            # 对内容进行读取
            res = requests.get(emotion_url, headers=header, cookies=cookie)
            r = re.findall('\((.*)\)', res.text)[0]
            with open(f'find/testfind{name}_{page}.json', 'w', encoding='utf-8') as fp:
                fp.write(r)
            message = json.loads(r)
            print(f'成功读取{name}的第{page}页说说')
            # 进行翻页操作
            pos += 20
            page += 1
            # 判断是否结束操作
            # 没有说说
            if 'msglist' not in message:
                break
            # 爬取完毕
            if message['msglist'] == None:
                print(f'{name}的空间爬取结束')
                break
            # 对每一个说说进行处理
            for m in message['msglist']:
                # 获取点赞信息数据
                self.get_like(m, qq, name)

    # 获取点赞信息数据(从说说“等人”处发现)
    def get_like(self, m, qq, name):
        g_tk = self.get_gtk()
        uin = self.get_uin()
        tid = m['tid']
        # 原始链接
        url_like = 'https://user.qzone.qq.com/proxy/domain/users.qzone.qq.com/cgi-bin/likes/get_like_list_app?'
        # 进行拼接
        data_like = {
            'uin': uin,
            'unikey': 'http://user.qzone.qq.com/' + str(qq) + '/mood/' + str(tid) + '.1',
            'begin_uin': 0,
            'query_count': 60,
            'if_first_page': 1,
            'g_tk': g_tk
        }
        data_like_encode = urllib.parse.urlencode(data_like)
        url_like = url_like + data_like_encode
        res = requests.get(url_like, headers=header, cookies=cookie)
        res.encoding = 'UTF-8'
        like_data = re.findall('\((.*)\)', res.text, re.S)[0]
        like_message = json.loads(like_data)
        # 数据量太大,请求繁忙导致部分页码可能无法请求到,错误跳出
        try:
            for l in like_message['data']['like_uin_info']:
                file_like.write(name + '<-' + str(l['nick']) + '\n')
        except KeyError:
            print(name)
            print(like_message)

    # 多线程辅助函数
    def get(self, f_list):
        self.locate(f_list[0], f_list[1])

    # 开始运行端口
    # 使用多线程threadpool进行实现,提升效率
    def start(self):
        r_list = self.refine()
        # 开启15个线程
        pool = threadpool.ThreadPool(10)
        # 提交任务到线程池
        requests = threadpool.makeRequests(self.get, r_list)
        # 开始执行任务
        for req in requests:
            pool.putRequest(req)  # 提交
        pool.wait()

    # name和remark相互转化,为后续统计做准备,存入一个txt文件中
    def trans_name(self):
        friend_list = self.get_friend()
        for f in friend_list:
            if f[1] != '':
                file_trans.write(f[0] + '<-' + f[1] + '\n')
            else:
                file_trans.write(f[0] + '<-' + f[0] + '\n')


if __name__ == '__main__':
    qzone = Qzone()
    # 设置请求头(根据自己浏览器来设定)
    header = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
        "accept-language": "zh-CN,zh;q=0.9",
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    }
    # 打开上一个程序中所得到的cookie,包含了登录信息
    with open('cookie_dict.txt', 'r') as f:
        cookie = json.load(f)
    # 得到好友信息
    qzone.get_friend()
    uin_list = qzone.uinlist()
    # 获取你需要的人的QQ空间点赞数据
    file_like = open('like.txt', 'w', encoding='UTF-8')
    # 获取名称昵称相互转换数据
    file_trans = open('trans.txt', 'w', encoding='UTF-8')
    # 开始执行
    qzone.start()
    qzone.trans_name()

三,数据分析

通过第二部分得到的like.txt文本,数据分析部分首先通过get_content函数,获得文本中的内容;而后通过like_analyze和like_ananlyze2两个函数,分别获得谁给TA点赞最多和TA给谁点赞最多的数据,以字典形式返回。

注意的是:TA给谁点赞最多的数据往往不够16人,这里需要来补齐,不然后续Qt展示的时候会出bug

这部分功能由data_analysis.py实现,这个文件不需要运行,仅提供函数。

代码如下:

# 得到txt文件内容
def get_content(txtfile):
    file = open(txtfile, encoding='UTF-8')
    content = file.read()
    file.close()
    return content


# 计算点赞最多人
def like_analyze(name):
    data = get_content('like1.txt')
    dic = {}
    data_list = data.split('\n')
    for element in data_list:
        data = element.split('<-')
        # 开始收集
        if data[0] == name:
            if data[1] in dic.keys():
                dic[data[1]] += 1
            else:
                dic[data[1]] = 1
        # 最后一个是空
        if data[0] == '':
            break
    dic_sorted = sorted(dic.items(), key=lambda item: item[1], reverse=True)
    return dic_sorted


# 计算给谁点赞最多
def like_analyze2(name):
    remark = get_remark(name)
    data = get_content('like1.txt')
    dic = {}
    data_list = data.split('\n')
    for element in data_list:
        data = element.split('<-')
        # 最后一个是空
        if data[0] == '':
            break
        # 开始收集
        if data[1] == remark:
            if data[0] in dic.keys():
                dic[data[0]] += 1
            else:
                dic[data[0]] = 1
    dic_sorted = sorted(dic.items(), key=lambda item: item[1], reverse=True)
    if len(dic_sorted) < 16:
        for i in range(len(dic_sorted), 16):
            dic_sorted.append('')
    return dic_sorted


# 从name获取remark
def get_remark(name):
    data = get_content('trans.txt')
    data_list = data.split('\n')
    for element in data_list:
        data = element.split('<-')
        if data[0] == name:
            return data[1]
    return '此昵称不存在'


# 主函数,调试用
if __name__ == '__main__':
    # content = get_content('like1.txt')
    # qzone_analyze.content_analyze(content)
    print(like_analyze('我不是戬氏'))
    # print(get_remark('破特的魔法饼干'))
    print(like_analyze2('我不是戬氏'))

四,UI展示——PyQt5

受同学启发,尝试了用PyQt5做一个简单的页面。

相比于以前用的easyx复杂繁琐的经历,PyQt5简单明了,效果甚好。

首先用Qt Designer设计出自己想要的界面,并设置好接口和槽,这里的槽随便选一个,后续还要在代码中对槽根据自己的需求引入函数。

将其保存,得到like_analysis.ui

编辑

 之后将like_analysis.ui通过PyUIC转换为like_analysis.py文件,代码如下:

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

# Form implementation generated from reading ui file 'like_analysis.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(753, 615)
        self.showtext = QtWidgets.QPlainTextEdit(Form)
        self.showtext.setGeometry(QtCore.QRect(70, 110, 291, 401))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.showtext.setFont(font)
        self.showtext.setObjectName("showtext")
        self.searchbutton = QtWidgets.QPushButton(Form)
        self.searchbutton.setGeometry(QtCore.QRect(450, 40, 101, 31))
        self.searchbutton.setObjectName("searchbutton")
        self.clearbutton = QtWidgets.QPushButton(Form)
        self.clearbutton.setGeometry(QtCore.QRect(310, 550, 101, 31))
        self.clearbutton.setObjectName("clearbutton")
        self.inputtext = QtWidgets.QPlainTextEdit(Form)
        self.inputtext.setGeometry(QtCore.QRect(160, 30, 191, 61))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.inputtext.setFont(font)
        self.inputtext.setObjectName("inputtext")
        self.showtext_2 = QtWidgets.QPlainTextEdit(Form)
        self.showtext_2.setGeometry(QtCore.QRect(390, 110, 291, 401))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.showtext_2.setFont(font)
        self.showtext_2.setObjectName("showtext_2")

        self.retranslateUi(Form)
        self.searchbutton.clicked.connect(Form.get_list)
        self.clearbutton.clicked.connect(Form.clear)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "like_analysis"))
        self.showtext.setPlaceholderText(_translate("Form", "谁给TA点赞最多(取前16名)"))
        self.searchbutton.setText(_translate("Form", "查询"))
        self.clearbutton.setText(_translate("Form", "清空"))
        self.inputtext.setPlaceholderText(_translate("Form", "请输入要查询的好友QQ昵称"))
        self.showtext_2.setPlaceholderText(_translate("Form", "TA给谁点赞最多(取前16名)"))

而后通过固定的模板设计方法,写出展示的文件,这里命名为show_page.py

代码如下:

import sys
import like_analysis
import data_analysis
from PyQt5.QtWidgets import QApplication, QDialog


class MainDialog(QDialog):

    def __init__(self, parent=None):
        super(QDialog, self).__init__(parent)

        self.ui = like_analysis.Ui_Form()

        self.ui.setupUi(self)

    def get_list(self):
        querry_name = self.ui.inputtext.toPlainText()
        if data_analysis.get_remark(querry_name) == '此昵称不存在':
            self.ui.showtext.setPlainText('此昵称不存在')
            self.ui.showtext_2.setPlainText('此昵称不存在')
            return 0
        showdic = data_analysis.like_analyze(querry_name)
        showMsg = '1:{}\n2:{}\n3:{}\n4:{}\n5:{}\n6:{}\n7:{}\n8: {}\n9:{}\n10:{}\n11:{}\n12:{}\n13:{}\n14:{}\n15:{}\n16: {}\n'.format(
            showdic[0],
            showdic[1],
            showdic[2],
            showdic[3],
            showdic[4],
            showdic[5],
            showdic[6],
            showdic[7],
            showdic[8],
            showdic[9],
            showdic[10],
            showdic[11],
            showdic[12],
            showdic[13],
            showdic[14],
            showdic[15]
        )
        self.ui.showtext.setPlainText(showMsg)

        showdic2 = data_analysis.like_analyze2(querry_name)
        showMsg2 = '1:{}\n2:{}\n3:{}\n4:{}\n5:{}\n6:{}\n7:{}\n8: {}\n9:{}\n10:{}\n11:{}\n12:{}\n13:{}\n14:{}\n15:{}\n16: {}\n'.format(
            showdic2[0],
            showdic2[1],
            showdic2[2],
            showdic2[3],
            showdic2[4],
            showdic2[5],
            showdic2[6],
            showdic2[7],
            showdic2[8],
            showdic2[9],
            showdic2[10],
            showdic2[11],
            showdic2[12],
            showdic2[13],
            showdic2[14],
            showdic2[15]
        )
        self.ui.showtext_2.setPlainText(showMsg2)

    def clear(self):
        self.ui.showtext.clear()
        self.ui.showtext_2.clear()


if __name__ == '__main__':
    myapp = QApplication(sys.argv)

    myDlg = MainDialog()

    myDlg.show()

    sys.exit(myapp.exec_())

运行这个文件,就可以得到最终效果

编辑

五,代码过程与遇到的问题

首先就是登录问题,本来想做一个扫描二维码的登录方式,先是对二维码url通过正则表达式寻找定位花了很长时间,而后又发现urlretrive下载下来的二维码是过期的二维码,看网上类似教程,更改方式获取图片后仍然无效。这个过程耗费了大量时间,最后改成了最基础的selenium方法登录,效果出奇的好。

之后是寻找需要数据的url,QQ空间真是奇特,在点赞数据的url寻找上还算顺利,就是会又说说出现如下界面

编辑

没有什么规律,,,数据就获取不到了,很头疼。

而后是整体获得整页说说的过程,很重要的接口是emotion_cgi_msglist_v6,但在一个好友的空间中苦苦翻寻却怎么也找不到,换了其它好友却一下子就找到了,中途让我一度想放弃去改道交以前爬微信公众号的程序...

一切完事具备,跑起来也可以,好耶,总该ok了吧,然后一天夜里我调试程序的时候,发现运行过后like.txt中空空如也,心急如焚的我确认代码没有改过,打开QQ空间一看:

哦,我访问不了任何人的QQ说说了

编辑

编辑

腾讯我... ...

好在第二天又可以了,不知道是腾讯给我解封了还是我真的把网址跑崩了... ...

好在不同于以往爬取网站信息单纯就是寻找正则表达式,模拟浏览器操作selenium就是找借口,此次项目从寻找参数,观察url,python文件使用读取,等多方面都有练习,同时意识到了自己基础字典列表使用上不熟带来的各种bug...还学到了threadpool和PyQt5新技巧。

更重要的是,“喂喂喂,你想不想知道谁给你点赞最多,和你给谁点赞最多呢”

 

 


posted @   Gustavo09  阅读(528)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示