爬取qq好友说说并对数据简单分析

看了网上大神和相关书本的操作,自己实践并改变了一些。我把我的思路和细节写出来。写的不好多多指教。
我用了两种方法爬取数据重点内容,一个是直接爬取,另一个是利用Selenium模拟
第一种:使用Google Chrome浏览器,打开网页版qq登录界面,在登录之前按F12

这里写图片描述

输入账号密码登录后点击说说,在右侧Google Chrome开发者工具中选择Network,Filter右侧选择XHR,可以筛选掉很多加载的文件,在Name下面查看一个前缀为”emotion_cgi_msglist_v6“的文件,点击后在右侧Headers中找到Request Headers,复制下面所有的内容(标签前面的:去掉),关掉Request Headers,在下面Query String Parameters中复制uin和g_tk。这样我们就把爬取所需要的三个关键东西准备好了,更换这三个东西就可以爬取不同qq号的好友说说。

这里写图片描述

说明一下在写脚本之前的功课,在Query String Parameters的format中可以看到是jsonp,说明这个网页返回的是json格式的数据,点击Headers的右侧的Preview查看返回的数据

这里写图片描述

我们需要爬取的数据包括msglist(发表说说的信息),total(只需要爬取一次就可以,total代表发表说说的总数量,和真实数量有区别,因为有些说说已经被删除)。提一句,num为网页返回的说说的数量信息,单次请求超过40后会只返回10条。点开msglist,里面包含数量为num的说说的信息,点开其中的某一个,有若干信息,我们需要爬取的包括cmtnum(评论的数量),commentlist(评论人的信息),content(说说的内容),createTime(创建说说的时间),name(发表人name),uin(*发表人qq,后
面构建url时需要用到),tid(构造获取点赞信息的url*)。这样返回的json数据是一页的,我们需要构建不同页的好友说说的url。观察并去掉一些字符后,最终我们可以得到这样的格式:
https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin= A &pos=B&num=20&g_tk=C
A填我们上面的得到的uin,C填复制的g_tk,B的填法(和num的值有关)是:0代表第一页(即从第一条说说到第二十条说说),20代表第二页,以此类推

返回的信息不包括点赞的信息,点赞的信息有另外的网页返回返回数据。
我们看一下啊,首先在某一条说说中点击”某某多少人觉得很赞”,出现如下图的内容

这里写图片描述

在右侧出现了一个前缀为”get_like_list_app“的文件,点击Preview查看返回的数据格式,data是返回的点赞信息,点开data,需要爬取的信息包括total_number(点赞数量,和显示的点赞有区别,原因可能是有些点赞被撤回),like_uin_info(点赞人的信息),点开后可以看到addr(地址),constellation(星座),fuin(点赞人的qq),gender(性别),if_qq_friend(是否是好友),if_special_care(不大清楚是什么),if_special_vip(是否是vip),nick(昵称)

构建点赞信息的url,方法与上面类似,最终得到格式如下:
https://user.qzone.qq.com/proxy/domain/users.qzone.qq.com/cgi-bin/likes/get_like_list_app?uin=A&unikey=B&begin_uin=0&query_count=60&if_first_page=1&g_tk=C
A填我们复制的uin(注意不是爬取的),B填构造好的点赞url(构造格式为:http://user.qzone.qq.com/D/mood/E.1,D填爬取的uin,E填爬取的tid),C填复制的g_tk。

在爬取之前还需要一件准备工作,需要得到好友列表,这样我们才知道要爬取那些人的说说。介绍两种方法。在这里先介绍第一种,在第二种爬取方法中介绍第二种。
这时候看Google Chrome 开发者工具Name下面有一个前缀为”friend_hat_get.cgi“的文件,复制Headers中General下Request URL的值,这就是我们爬取好友列表信息需要的url。查看它的Preview,会发现它返回的是好友列表,我们需要爬取的包括data下面的列表名(即qq号)和realname(应该是备注)。

这里写图片描述

使用的软件是PyCharm,需要的库为requests(请求网页),json(解析返回的json格式的数据),multiprocessing(多进程),pymongo(存储说说的数据库)

#导入依赖的库
import requests
import json
from multiprocessing import Pool
import pymongo
#浏览器的头
headers = {
#填写复制的信息
}
ownQQ = '
#复制的uin
'
g_tk = '
#复制的g_tk
'
url = '
#复制的url
'
#本地数据库
client = pymongo.MongoClient('localhost',27017)
#数据库名 Qzone2
mydb = client['Qzone2']

#好友列表
QQs = mydb[ownQQ+'QQs']
#存取说说信息
qzone = mydb[ownQQ+'qzone']

#第一步 爬取好友列表
def getFriends(url):
    html = requests.get(url,headers=headers)
    #因为返回的数据格式不符合json,需要处理一下
    #91可能会有所变化 如果格式不对 自己打印查看然后改进一下
    #测试json格式是否正确的网站:http://www.bejson.com/
    response = '[' + html.text[10:][:-90] + '}}}]'
    # print(response)
    #解析json数据
    json_Data = json.loads(response)[0]
    for d in json_Data['data']:
        qq = d
                try:
            name = json_Data['data'][qq]['realname']
            info = {
                'qq':d,
                'realname':name
            }
        except:
            info = {
                'qq':d,
                'realname':''
            }
        QQs.insert_one(info)

#第二步 爬取信息
def getInfos(qq):
    #没有权限的跳过
    try:
        url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=' + qq + '&pos=0&num=20&g_tk='+ g_tk
        html = requests.get(url, headers=headers)
        # 格式处理
        response = '[' + html.text[10:][:-2] + ']'
        json_Data = json.loads(response, encoding='utf-8')[0]
        total = json_Data['total']
        for pos in range(0, int(total), 20):
            url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?uin=' + qq + '&pos=' + str(
                pos) + '&num=20&g_tk=' + g_tk
            html = requests.get(url, headers=headers)
            # 格式处理
            response = '[' + html.text[10:][:-2] + ']'
            json_Data = json.loads(response, encoding='utf-8')[0]
            msglist = json_Data['msglist']
            if msglist != None:
                for msg in msglist:
                    # 评论数量
                    cmtnum = msg['cmtnum']
                    # 说说内容
                    Scontent = msg['content']
                    # 发表时间
                    timeShuo = msg['createTime']
                    comments = []
                    if cmtnum:
                        # 评论人员列表
                        commentlist = msg['commentlist']
                        for comment in commentlist:
                            # 评论人qq
                            qq_comment = comment['uin']
                            # nickname
                            # name = comment['name']
                            # 评论时间
                            createTime = comment['createTime']
                            createTime2 = comment['createTime2']
                            # 内容
                            # content = comment['content']
                            comments.append('{ "qq_comment":"' + str(
                                qq_comment) + '","createTime":"' + createTime + '","createTime2":"' + createTime2 + '"}')
                    tid = msg['tid']
                    # 构造说说url
                    Surl = 'http://user.qzone.qq.com/' + qq + '/mood/' + tid + '.1'
                    Like = get_likes(Surl)
                    data = {
                        'qq': qq,
                        'content': Scontent,
                        'createTime': timeShuo,
                        'cmtnum': cmtnum,
                        'comment': comments,
                        'like_number': Like['like_number'],
                        'like_info': Like['like_info']
                        }
                    qzone.insert_one(data)
    except:
        print('error')
        pass

#获取点赞信息
def get_likes(url):
    #根据传入的说说地址 构造获取点赞信息的url
    url = 'https://user.qzone.qq.com/proxy/domain/users.qzone.qq.com/cgi-bin/likes/get_like_list_app?uin='+ownQQ+'&unikey='+\
          url+'&begin_uin=0&query_count=60&if_first_page=1&g_tk='+g_tk
    html = requests.get(url,headers=headers)
    #网页编码转换为unicode
    html.encoding='unicode'
    # 格式处理
    response = '[' + html.text[10:][:-3] + ']'
    json_Data = json.loads(response)[0]['data']
    total_number = json_Data['total_number']
    likes = []
    if total_number:
        like_uin_info = json_Data['like_uin_info']
        for info in like_uin_info:
            addr = info['addr']
            constellation = info['constellation']
            fuin = info['fuin']
            gender = info['gender']
            if_qq_friend = info['if_qq_friend']
            if_special_care = info['if_special_care']
            is_special_vip = info['is_special_vip']
            # nick = info['nick']
            likes.append('{ "addr":"'+addr+'","constellation":"'+constellation+'","fuin":"'+str(fuin)+'","gender":"'+gender+
                         '","if_qq_friend":"'+str(if_qq_friend)+'","if_special_care":"'+str(if_special_care)+'","is_special_vip":"'+str(is_special_vip)+'"}')
            likes.append('{ "fuin":"'+str(fuin)+'"}')
    data = {
        'like_number':total_number,
        'like_info':likes
    }
    return data
if __name__ == '__main__':
# 每次使用,更新headers中的cookie或者全部更新headers 和 g_tk
#换号时更新headers ownQQ 和g_tk
    getFriends(url)
    QQ = [item['qq'] for item in QQs.find()]
    pool = Pool(processes=4)
    pool.map(getInfos,QQ)

下篇再续

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值