爬虫(三)生成qq好友关系网(2)—获取好友空间评论点赞情况

二. 获取好友空间评论点赞情况

到了最麻烦的一步了

github地址:嘤嘤嘤我就是那个地址,点我点我

上一篇看这里: 看我看我看我


首先我们得想好数据如何存储,是写进数据库呢,还是按照一定的格式存储为txt文件保存在本地,本文采取的是后者

那么问题又来了,按照一定的格式存储,那么按照怎样的格式会让后面处理数据起来比较方便

那么问题又双叒叕来了,我们后面想要怎么处理数据

这些必须事先想好,不然做着做到后面发现不对啊,又要改改改

重点来了!!!!!!!

思路如下:

comment.txt 和 like.txt 分别存储评论和点赞的情况,只要好友之间在qq空间有评论或者点赞,那么在对应文件中加一行,把两个人的备注写进去,中间有个特殊符号分开,如$|$,以便于后面处理,后期处理数据则读这两个文件,评论了两人的关系+3,点赞关系+1,数据处理放在第三篇说。


好了,现在有了思路那么撸起袖子开始干吧


1.1首先得得到一个好友的每一条说说,再得到这个好友的说说的评论点赞情况,再用好友列表循环这个过程即可

先进入一个好友空间,进入说说页面,在开发者工具里看发送的http请求和他的响应,找到这个

看他需要的数据

 

看他返回的响应内容

 观察下发现有这么个特点:

返回的是20条说说在msglist里面,每条说说还带着10条评论,这样解析json数据把我们想要的内容取出来即可,假设A评论了B的QQ,B是我们的好友,那么我们看A是不是我和B的共同好友,如果是的话那就把A和B的信息写入comment.txt,即判断A的qq号是否在第一步得到的qq_list就行了


那么思路就来了!!!!!!!!!

要得到一个好友的所有说说那么就,不断改变pos的值,循环发送http请求

因为还返回了十条评论,那么我们就顺带把这十条评论记下来

    #找到说说模块
    #pos是当前页面第一个说说的排序,一页20个
    #这里的qq是单个好友的qq,这里的单个name是好友的备注
    def find_topic(self, qq, name):
        page = 1
        #conti循环的标志,当为false时退出循环
        conti = True
        pos = 0
        g_tk = self.get_gtk()
        uin = self.get_uin()
        while conti:
            #url必须在循环内,每次循环必须重置
            url = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msglist_v6?'
            data = {
                'uin': qq,
                'pos': pos,
                'num': 20,
                'hostUin': uin,
                'replynum': 100,
                'callback': '_preloadCallback',
                'code_version': 1,
                'format': 'jsonp',
                'need_private_comment': 1,
                'g_tk': g_tk,
            }
            #下次翻页
            #下次翻页
            pos += 20
            #构造访问说说页面的HTTP报文内容
            url += urllib.parse.urlencode(data)
            res = requests.get(url,headers=header,cookies=cookie)
            print('读取 '+name+' 的第 '+str(page)+' 页说说成功')
            page += 1
            #匹配出_preloadCallback之后的内容
            #如果啥都没有那么就是没有权限,file_denied在这个函数外面打开
            if len(re.findall('\((.*)\)', res.text)) == 0:
                记录下没有权限的
                file_denied.write(name + ': ' + str(qq) + '\n')
                continue
            r = re.findall('\((.*)\)', res.text)[0]
            #将json数据变成字典格式
            msg = json.loads(r)

            #如果没有说说就返回
            if 'msglist' not in msg:
                return 0

            #这里爬说说结束,注意和上面的区别,一个是不存在键值,一个是存在键,但值类型为None
            if msg['msglist'] == None:
                print('\n'+name+'的空间无更多说说'+'\n')
                return 0

            #得到的说说相关内容都在msglist(list类型)里面,msglist[i]是字典类型,可利用keys方法查看结构
            #说说内容conlist[0]['con'],另外转发的说说在conlist[1/2/3....]
            #每一条说说就是m
            for m in msg['msglist']:

                #记录共同好友点赞记录
                self.write_like(m, qq, name)

                #如果评论数大于10,则需要点进查看全部评论
                if m['cmtnum'] < 10:
                    ##这里特殊,如果转发了说说并且没有配文字,而且原说说被删了,就会出现错误
                    if m['conlist'] is None:
                        continue
                    #写入评论信息
                    self.write_comment(m,qq, name)

那么又有了新的问题:因为这样子只能得到十条评论,想要更多评论那得更进一步

即点击这个

,在开发者中心查看http请求和响应,一样的套路解析,只不过发送的数据不一样了,在后面跟上一个else语句

# 如果评论数大于10,则需要点进查看全部评论
                else:
                    data_more = {
                        'uin': qq,
                        'tid': m['tid'],
                        'ftype': 0,
                        'sort': 0,
                        'pos': 0,
                        'num': 20,
                        't1_source': 'undefined',
                        'callback': '_preloadCallback',
                        'code_version': 1,
                        'format': 'jsonp',
                        'need_private_comment': 1,
                        'g_tk': g_tk,
                    }
                    url_more = 'https://user.qzone.qq.com/proxy/domain/taotao.qq.com/cgi-bin/emotion_cgi_msgdetail_v6?'
                    url_more += urllib.parse.urlencode(data_more)
                    res_more = requests.get(url_more, headers=header, cookies=cookie)
                    # print(url_more)
                    # 匹配出_preloadCallback之后的内容
                    r_more = re.findall('\((.*)\)', res_more.text)[0]
                    # print(res_more.text)
                    m_more = json.loads(r_more)
                    # 写入txt文件
                    self.write_comment(m_more, qq, name)

1.2 那么再定义号写入txt的两个函数,

得到说说的点赞情况需要点击 ,和上面一样的套路,这里就不再赘述了

这里又因为评论有了新的问题,我们上一部只得到了20条评论,评论如果多于20条呢,那我们再评论的的写入函数里再进行判断,如果大于20条,那么再请求后面的,但比较麻烦的是这里发送的数据,响应的json数据格式和前20条的又不一样,所以不能直接套用前面的,如果评论大于20条需要在写入函数内重新发送请求,在git上去的源码里查看,这里就不展开了

写入时遍历说说下的每一条评论记得先查看该评论是否是自己的好友发的:

for comment in data['comments']: 
   #判断共同好友,是的话则写入
    if comment['uin'] in qq_list:
        file_comment.write(name+'$|$'+comment['name']+'\n')

对于点赞也是

for like in r['data']['like_uin_info']:
    #判断共同好友
    if like['fuin'] in qq_list:
        file_like.write(name + '$|$' + like['nick'] + '\n')

只要评论或者点赞就把两个人的备注都写进去

然后再用第一部得到的friend_list循环这个即可

    #定义入口
    def start(self):
        friend_list = self.get_friend()
        #开启多线程爬数据
        pool_size = 15
        pool = threadpool.ThreadPool(pool_size)
        # 创建工作请求,这里他自己会把list分开
        reqs = threadpool.makeRequests(self.get_data,friend_list)
        # 将工作请求放入队列
        [pool.putRequest(req) for req in reqs]
        pool.wait()

    def get_data(self, friend_list):
        self.find_topic(friend_list[1], friend_list[0])

现在已经得到数据了,就像下面

然后就是到了最最有意思的第三部分数据处理部分了

猜你喜欢

转载自blog.csdn.net/qq_40691208/article/details/81480384