python3爬取新浪微博所有评论数据

python3爬取新浪微博所有评论数据


该项目主要根据具体某篇微博的网址,得到其下所有评论的信息,包括评论用户名,评论人的主页网址,评论时间,内容;然后存储在csv中(仅供学习)

原理:微博的评论数据是通过服务器异步传输过来的,并且是分多页的,相信很多小伙伴有了分页的网址,就能把评论数据解析出来,但是微博的评论数据是通过瀑布流分页,获取下一页的url也就是此次爬取的难点。

通过评论页的url,以及掉我头发的分析之后,

首页评论url:https://weibo.com/aj/v6/comment/big?ajwvr=6&id=4441135474874422&filter=all&from=singleWeiBo&__rnd=1574405759566
第二页评论url:https://weibo.com/aj/v6/comment/big?ajwvr=6&id=4441135474874422&root_comment_max_id=4441415025138397&root_comment_max_id_type=&root_comment_ext_param=&page=2&filter=all&sum_comment_number=11&filter_tips_before=1&from=singleWeiBo&__rnd=1574405986800

可以看出第二页url比第一页多了几个参数,其中root_comment_max_idsum_comment_number决定这能否获取下一页评论数据
root_comment_max_id是上一页最后一条评论的comment_id-1
sum_comment_number是已经展示的评论数。
(简单吧,拿头发换的)
这样我们就能通过首页url构造出下一页的url,如此循环得到所有评论页的url

在这里插入图片描述

以下是其评论数据:
在这里插入图片描述
爬取流程如下:
首先,从文件中读取要爬取的微博的网址

if __name__ == '__main__':
    # 创建一个保持会话的session
    s = requests.Session()
    with open('wb_url.txt','r') as f:
        for url in f:
            # print(url)
            spider = Spider(url,s)
            spider.run()

有了具体某篇微博的网址后,可以得到该微博评论的id,然后拼出评论首页的url

# 得到第一页评论网址,和该博客评论id
    def get_first_comment(self):
        res = self.get_response(self.page_url)
        # 得到该微博的id
        com_id = re.search(r'按热度.*?id=(.*?)&filter=all.*?">按时间', res.text).group(1)
        # 然后拼出其首页评论的网址
        com_url = 'https://weibo.com/aj/v6/comment/big?ajwvr=6&id=%s&filter=all&from=singleWeiBo&__rnd=1574358480600' % com_id
        return com_url, com_id

有了评论首页地址,我们就可以通过其源码提取到我们需要的root_comment_max_id并计算出sum_comment_number。这样我们就可以拼出下一评论页的url

	#通过评论源码得到下一页的url
    def get_next_comment(self,com_data,com_id):
        # 得到最后一个评论的comment_id
        # print(com_data)
        html = etree.HTML(com_data)
        com_ls = html.xpath('//div[@node-type="root_comment"]')
        # 评论为空时的容错
        try:
            com_max_id = com_ls[-1].xpath('./@comment_id')[0]
        except:
            return 'NO'

        com_max_id = str(int(com_max_id)-1)
        length = len(com_ls)
        self.sum_comment_number += length
        # print(com_max_id, length)
        next_url = 'https://weibo.com/aj/v6/comment/big?ajwvr=6&id={cid}&root_comment_max_id={mid}&root_comment_max_id_type=&root_comment_ext_param=' \
                   '&page={page_num}&filter=all&sum_comment_number={count_num}&filter_tips_before=1&from=singleWeiBo&__rnd=1574357153056'.format(cid=com_id,mid=com_max_id,page_num=self.page_num,count_num=self.sum_comment_number)
        return next_url

有了评论页的url,我们只需解析一下服务器返回的评论数据,得到我们需要的数据,并保存

def save_comment_data(self,com_data):
    # 提取干净评论   用户名+内容+时间+主页url
    html = etree.HTML(com_data)
    # 得到该评论源码的所有评论
    uls = html.xpath('//div[@class="list_con"]')
    for ul in uls:
        user = ul.xpath('./div[@class="WB_text"]/a/text()')[0]
        comment = ul.xpath('./div[@class="WB_text"]/text()')[1]
        # 去除中文冒号:
        comment = comment.split(':',maxsplit=1)[-1]
        tim = ul.xpath('./div[contains(@class,"WB_func")]/div[contains(@class,"WB_from")]/text()')[0]
        user_url = 'https:'+ul.xpath('./div[@class="WB_text"]/a/@href')[0]
        try:
            self.writer.writerow([user, comment, tim,user_url])
        except Exception as e:
            print(e)
        # print(user, comment, tim,user_url)

评论数据

主要流程就是如此,此次最花时间的就是下一页评论url的获取,新浪微博采用瀑布流,鼠标下滑或点击查看更多服务器才会返回数据,通过上一页的数据,推算出下一页url的参数~

以前新浪微博,通过page参数就能得到下一页,现在升级,后浪在推前浪,而我还想再浪,加油

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章