Skip to content

Latest commit

 

History

History
96 lines (67 loc) · 3.27 KB

3.md

File metadata and controls

96 lines (67 loc) · 3.27 KB

微博评论爬取

评论爬取当然也要范围,比如说某一条微博下面的所有评论。这里我挑选一篇汶川10周年的微博,bidGgdfidjFm进行爬取。

链接分析

随便点一篇微博进行评论,会发现链接是这样的。

https://weibo.cn/comment/GgdfidjFm?uid=2803301701&rl=0#cmtfrm 而点“下页”会变成这样。

https://weibo.cn/comment/GgdfidjFm?uid=2803301701&rl=0&page=2

其中的#cmtfrm应该是锚链到comment form,不用管它。

rl=0就是普通的评论列表,热门列表是rl=1。这两个列表并没有什么区别,都是50页左右就爬不到了,可以结合使用。

uid=2803301701是人民日报的用户id。这些好像都是可以不带的。

所以只要遍历https://weibo.cn/comment/GgdfidjFm?page=1~n就可以了。

于此同时,评论一共44281页。

函数构造

同样的,我们构造一个名为get_comments的函数。值得注意的是,第一个参数不再是'rmrb'这样的name,而是'GgdfidjFm'这样的微博bid

def get_comments(bid,page,start=1):
    print(bid,page,start)

get_comments('GgdfidjFm',44281)

然后,针对每一页,我们构造一个函数叫做get_comments_from_page,并与get_comments进行拼接。

def get_comments(bid,page,start=1):
    for current_page in range(start,page+1):
        print(current_page)
        url = 'https://weibo.cn/comment/%s?page=%d' % (bid,current_page)
        get_comments_from_page(url,bid) # 这里建议把bid也传进去,便于从各种微博的评论里筛选出某条微博的评论

请求的发送和页面的解析是和微博爬取时一样的。

import requests
from bs4 import BeautifulSoup
import re

headers = {'cookie':'XXX'}

def get_comments_from_page(url,bid):
    r = requests.get(url,headers=headers)
    r.encoding = 'utf-8'
    soup = BeautifulSoup(r.text, 'html5lib')

    comments = soup.select("div[id^='C_']") # 不一样的是,这里是'C_'开头的div
    for comment in comments:
        comment_manage(comment,bid)

get_comments_from_page('https://weibo.cn/comment/GgdfidjFm?page=1')

清理的时候稍微有点不一样。多了一个bid,微博的bid对应评论的cid,转发和评论都没有了。

def comment_manage(comment,bid):
    temp = {
        'bid': bid, # 这里传了bid用于识别是哪篇微博下的评论
        'cid': comment['id'].split("_")[1],
        'content': comment.find("span",class_="ctt").text,
        'attitudes_count': re.split(r"[\[\]]",comment.find("a",string=re.compile(r"^赞\[")).text)[1],
        'created_at': comment.find("span",class_="ct").text
    }
    save_comment(temp)

储存的时候也只是collection和唯一识别符不一样。

import pymongo

myclient = pymongo.MongoClient("mongodb://XXX:[email protected]:27017/")
mydb = myclient["weibo_DB"]

def save_comment(temp):
    mycol = mydb["weibo_comments"] # 存放到评论的集合collection
    flag = mycol.find_one({"cid":temp['cid']}) # 用cid保证评论不重复
    if flag:
        print('已存在')
    else:
        mycol.insert_one(temp)

至此,评论爬取也会了,不过好像突破不了50页的限制,只能获取300-500条,就算是人工访问,结果也是一样的,这个待处理。