python爬取微博事件评论

Neo
Neo
2020-09-20 / 0 评论 / 245 阅读

爬取内容

本次实验爬取的微博用户评论来自8月7号环球网报道的特朗普对微信的打压事件,该事件被1.8万人转发,5.5万人评论,95万人点赞,算是一个非常热门的事件。如下图所示。
image.png

爬取流程

  • 获取评论页面的链接,通过浏览器的开发者工具找到用户评论页面的链接
url = "https://m.weibo.cn/comments/hotflow?id=4535245979782011&mid=4535245979782011"+max_id+max_id_type

其中max_id和max_id_type只能从上个页面返回的信息中获取,初始化分别为0和空值。

  • 用户的登陆,微博评论信息必须是用户登陆之后才能看到,所以可以通过先在网页上登陆后获取到cookie,再以cookie模拟用户的登陆过程
cookie = "XSRF-TOKEN=2b913b; WEIBOCN_FROM=1110006030; MLOGIN=1; M_WEIBOCN_PARAMS=oid%3D4535245979782011%26luicode%3D20000061%26lfid%3D4535245979782011%26uicode%3D20000061%26fid%3D4535245979782011; loginScene=102003; SUB=_2A25yKvh0DeRhGeFM61YZ9S7LwziIHXVR1Jg8rDV6PUJbkdANLXjbkW1NQOQxqU7wOHonOS4OZBmx9DQm972hjBLi; SUHB=0102RhFGaA-zOR; _T_WM=29575410521"
  • 浏览器的伪装,通过配置请求头来模拟浏览器访问的过程以减少被微博发现的可能性。
    headers = {
        # cookie的获取:登录微博后到request headers内找到cookie复制粘贴
        "cookie": cookie,
        "User-Agent": 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'
    }
  • 获取评论内容,先请求获取到评论的页面,再解析出其中的评论内容以及下一个页面的id。
response = requests.get(url, headers=headers)

    content = json.loads(response.text)  # 把获得数据转换成字典格式

    for i in content['data']['data']:
        text = i['text']
        label_filter = re.compile(r'<span class="url-icon">.*?</span>', re.S)

        comment = re.sub(label_filter, '', text)  # 把一些链接去掉,保留纯文本内容。
        rm_url = re.compile(r"回复<a href=.*?</a>:", re.S)  # 去掉回复的链接内容。
        rm = re.sub(rm_url, '', comment)
        rmherf = re.compile(r'<a href=.*?</a>', re.S)  # 去除链接内容
        rm1 = re.sub(rmherf, '', rm)
        print(rm1)

        with open('%s.txt' % file_name, "a", encoding="utf8") as f:
            f.write(rm1 + '\n')

    max_id = content["data"]["max_id"]
    max_id_type = content["data"]["max_id_type"]
  • 迭代获取全部的评论信息,在迭代的过程中要注意控制好请求的频率,再此模拟用户浏览一个页面所需要的随机时间2-5秒,以减少被微博后台发现的可能性。
    for i in tqdm(range(2770)):
        url = "https://m.weibo.cn/comments/hotflow?id=4535245979782011&mid=4535245979782011"+max_id+max_id_type
        next_max_id, next_max_id_type = get_comment(url, max_id)
        print("i="+str(i), " next_max_id="+next_max_id, " next_max_id_type="+next_max_id_type)
        max_id = "&max_id="+next_max_id
        max_id_type = "&max_id_type="+next_max_id_type
        sleep(random.randint(2, 5))

本次实验即便做了如上所述的一些防止被微博发现的措施,但是最终信息在获取到1.5万条评论时还是被微博给禁了(有一个冷冻时间),后面又做了几次实验,也调整了一些参数,还是没能获取全部的数据,其最大的可能在于微博进行了双重反爬保护,即IP检测与用户ID检测。对于IP检测可以采取建一个IP池动态代理来进行有效保护,但是对于用户ID的监测却是一个难题,网上看到有些博客说可以在某宝上购买一定数量的微博小号,构建一个账号池来处理。

完整代码

import requests
import json
import re
from time import sleep
from tqdm import tqdm
import random

file_name = '4535245979782011_2_1'
cookie = "XSRF-TOKEN=2b913b; WEIBOCN_FROM=1110006030; MLOGIN=1; M_WEIBOCN_PARAMS=oid%3D4535245979782011%26luicode%3D20000061%26lfid%3D4535245979782011%26uicode%3D20000061%26fid%3D4535245979782011; loginScene=102003; SUB=_2A25yKvh0DeRhGeFM61YZ9S7LwziIHXVR1Jg8rDV6PUJbkdANLXjbkW1NQOQxqU7wOHonOS4OZBmx9DQm972hjBLi; SUHB=0102RhFGaA-zOR; _T_WM=29575410521"


def get_comment(url, max_id):

    headers = {
        # cookie的获取:登录微博后到request headers内找到cookie复制粘贴
        "cookie": cookie,
        "User-Agent": 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'
    }
    response = requests.get(url, headers=headers)

    content = json.loads(response.text)  # 把获得数据转换成字典格式

    for i in content['data']['data']:
        text = i['text']
        label_filter = re.compile(r'<span class="url-icon">.*?</span>', re.S)

        comment = re.sub(label_filter, '', text)  # 把一些链接去掉,保留纯文本内容。
        rm_url = re.compile(r"回复<a href=.*?</a>:", re.S)  # 去掉回复的链接内容。
        rm = re.sub(rm_url, '', comment)
        rmherf = re.compile(r'<a href=.*?</a>', re.S)  # 去除链接内容
        rm1 = re.sub(rmherf, '', rm)
        print(rm1)

        with open('%s.txt' % file_name, "a", encoding="utf8") as f:
            f.write(rm1 + '\n')

    max_id = content["data"]["max_id"]
    max_id_type = content["data"]["max_id_type"]
    return str(max_id),str(max_id_type)


if __name__ == '__main__':

    max_id = ""
    max_id_type = "&max_id_type=0"

    for i in tqdm(range(2770)):
        url = "https://m.weibo.cn/comments/hotflow?id=4535245979782011&mid=4535245979782011"+max_id+max_id_type
        next_max_id, next_max_id_type = get_comment(url, max_id)
        print("i="+str(i), " next_max_id="+next_max_id, " next_max_id_type="+next_max_id_type)
        max_id = "&max_id="+next_max_id
        max_id_type = "&max_id_type="+next_max_id_type
        sleep(random.randint(2, 5))

爬取的部分内容

懂王已经疯了
退朗普是一天天不作会死嘛,自己国家啥样,心里没点AC数呀
腾讯准备在南山起诉美国
连锁反应来了 字节下跪成功开了个头
估计尝到甜头了,越来越过分
这是为了维持美国的信息传播霸权,控住了信息传播就可以控制普通民众的思维方式,世界上除了中国,基本信息传播都牢牢掌控在美国手里,现在中国的不受美国控制的信息传播方式逐渐渗入世界各个地区,这是美国霸权决不允许存在的。
让不让留学生活了…………
特朗普需不需要精神检测一下
自由美利坚 枪战每一天
总感觉这是特普朗的为了连任的策略,把美国搅成一锅粥,怎么乱怎么来,让后面的无法接盘
牛逼人家说禁用禁用,苹果手机我们做得到?果咀总有千万种理由去舔
TT从500亿美国业务到300亿全球业务再加1600亿的索赔金额用了多久?丹麦都不敢想
坐看腾讯操作
总统当成国王了。
霸权主义!
特朗普每次都给自己留足了反悔的时间
懂王已经疯了
退朗普是一天天不作会死嘛,自己国家啥样,心里没点AC数呀
腾讯准备在南山起诉美国
连锁反应来了 字节下跪成功开了个头
估计尝到甜头了,越来越过分
这是为了维持美国的信息传播霸权,控住了信息传播就可以控制普通民众的思维方式,世界上除了中国,基本信息传播都牢牢掌控在美国手里,现在中国的不受美国控制的信息传播方式逐渐渗入世界各个地区,这是美国霸权决不允许存在的。
让不让留学生活了…………
特朗普需不需要精神检测一下
自由美利坚 枪战每一天
总感觉这是特普朗的为了连任的策略,把美国搅成一锅粥,怎么乱怎么来,让后面的无法接盘
牛逼人家说禁用禁用,苹果手机我们做得到?果咀总有千万种理由去舔
TT从500亿美国业务到300亿全球业务再加1600亿的索赔金额用了多久?丹麦都不敢想