浅分析weibo评论导

目标网站

找合适的微博地址(一级和二级评论):https://weibo.com/5039775130/QcD89eXtz

获取cookie:

评论链接分析

一级评论

按热度排序

观察第一页链接的预览,max_id为红框中下一页的链接参数


按时间排序

 二级评论

多页结构和一级评论类似

总结:(QcD89eXtz等价转换5230103573565221(mid),为微博帖子的mid,uid是可以随便写的目测不影响,每一页加载完的预览max_id提供了下一页的链接参数,flow:0热度排序,1时间排序。fetch_level、is_mix:0评论,1评论回复)
https://weibo.com/ajax/statuses/buildComments?is_reload=1&id=5230103573565221&is_show_bulletin=2&is_mix=0&count=10&uid=5039775130&fetch_level=0&locale=zh-CN

https://weibo.com/ajax/statuses/buildComments?is_reload=1&id={weibo_id}&is_show_bulletin=2&is_mix=0&count=20&page=

评论格式分析

data 0:               

dr = re.compile(r'<[^>]+>', re.S)  # 用正则表达式清洗评论数据
text2 = dr.sub('', data['text'])
text_list.append(text2)  # 评论内容
time_list.append(trans_time(v_str=data['created_at']))  # 评论时间
like_count_list.append(data['like_count'])  # 评论点赞数
source_list.append(data['source'])  # 评论者IP归属地
user_name_list.append(data['user']['screen_name'])  # 评论者姓名
user_id_list.append(data['user']['id'])  # 评论者id
user_gender_list.append(tran_gender(data['user']['gender']))  # 评论者性别
follow_count_list.append(data['user']['follow_count'])  # 评论者关注数
followers_count_list.append(data['user']['followers_count'])  # 评论者粉丝数

转发评论同理

base_url = "https://weibo.com/ajax/statuses/repostTimeline"
params = {
    "id": mid,
    "page": str(page),
    "moduleID": "feed",
    "count": "20"
}

注:page控制一级评论翻页也行。

import requests
import csv
import time
# https://weibo.com/2644975784/5229613988188573#repost
# https://weibo.com/5039775130/QcD89eXtz
# 配置参数
weibo_id = "QcD89eXt"  # 替换为目标微博的ID(从网页URL中可获得)
cookie = "XSRF-TOKEN=XU8_AFjrLY5a4AAqjbR1FwxN; SCF=Aup057BA3pnLYH3D_0o6kVlBMaUmbvrxluPNRHktBUa77nl6_SIicN7p16uYwSrHtJ79tT6XLB3s5X3ITsL4DNw.; SUB=_2A25EC1O-DeRhGeFG7lEV8yzIyjmIHXVnael2rDV8PUNbmtANLUrWkW9NeUX04Hh4MYjuKPIb-ySjLlZXoMyduuFY; SUBP=0033WrSXqPxfM725Ws9jqgMF55529P9D9WFGK.uvaVIOqmnF7.QfyYUY5JpX5KzhUgL.FoMRSKeXe0zXeK-2dJLoIEBLxKnL12zL12qLxKqLBozLBoeLxKnL1K.L12-LxKqLB.2L1K5t; ALF=02_1765191918; WBPSESS=KfgmRchBqZijkVmYGCR-4izA5O32g3S-h3KzCpbmoPeG6aNxzukxIVcw2PmOTRAULZYtUSHame9bxDKBv1IAhTPzSDdHa2R1FhyAUXqKfbfuerxt6Vwz8gxmwnAR8m-pscvUnl_t9RsX58u2cn8ABA=="  # 替换为浏览器登录后的Cookie,用于身份验证

# 请求头,包含用户代理、Cookie 和 Referer(来源页面)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Cookie": cookie,
    "Referer": f"https://weibo.com/2803301701/{weibo_id}"  # 2803301701 为人民日报微博的UID
}


# 定义获取微博一级评论的函数
def get_comments(weibo_id, max_page=5):
    comments = []  # 存储评论内容
    # 构造评论接口的URL模板,每页包含20条评论
    url_template = f"https://weibo.com/ajax/statuses/buildComments?flow=0&is_reload=1&id={weibo_id}&is_show_bulletin=2&is_mix=0&count=20&page=" # 按热度排序下载一级评论

    # 遍历页数,逐页爬取
    for page in range(1, max_page + 1):
        try:
            # 发送 GET 请求获取当前页的评论数据
            response = requests.get(url_template + str(page), headers=headers)
            data = response.json()  # 将响应内容解析为 JSON 格式

            # 如果没有数据字段,说明已无更多评论,提前结束
            if not data.get("data"):
                print(f"第 {page} 页无数据,可能已爬完所有评论")
                break

            # 遍历每条评论,提取原始文本并清洗(去除换行符)
            for comment in data["data"]:
                text = comment["text_raw"].strip().replace("\n", " ")
                comments.append([text])  # 加入列表,格式为嵌套列表以便写入CSV

            print(f"已爬取第 {page} 页,当前总计 {len(comments)} 条评论")

            time.sleep(2)  # 每次请求后暂停2秒,防止触发反爬机制

        except Exception as e:
            print(f"第 {page} 页出错: {e}")
            break  # 若出错(如网络异常或请求被拒),提前终止爬取

    return comments  # 返回所有爬取到的评论列表


# 执行评论爬取
comments = get_comments(weibo_id)

# 将评论保存为 CSV 文件
with open("weibo_comments.csv", "w", encoding="utf-8-sig", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["评论内容"])  # 写入表头
    writer.writerows(comments)  # 写入评论内容

print(f"爬取完成!共 {len(comments)} 条评论已保存到 weibo_comments.csv")

参考

使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算) / 张生荣

python爬虫爬取微博评论--完整版(超详细,大学生不骗大学生)_python爬取网页评论-CSDN博客

Python爬虫—爬取微博评论数据_微博评论爬取-CSDN博客

https://mp.weixin.qq.com/s/8ccbzjIUA7xf3yzKTlVIyQ

多级评论参考 代码

# https://mp.weixin.qq.com/s/iVy-oo25xlawkI-XS6JtUg



# https://m.weibo.cn/detail/4813628149072458
import requests
import re
import sys
import pymysql
import time
import random
from jsonpath import jsonpath


class WeiBo():
    def __init__(self):
        # 一级评论的接口信息
        self.first_url = 'https://m.weibo.cn/comments/hotflow'
        self.first_data = {
            'id': '4813628149072458',
            'mid': '4813628149072458',
            'max_id': None,
            'max_id_type': '0'
        }

        # 二级评论的接口信息
        self.second_url = 'https://m.weibo.cn/comments/hotFlowChild'
        self.second_data = {
            'cid': '4813643344774141',
            'max_id': '0',
            'max_id_type': '0'
        }

        self.headers = {
            'referer': 'https://m.weibo.cn/detail/4813628149072458',
            'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
            'cookie': '你的cookie'
        }

        # 数据库
        self.db = pymysql.connect(
            host='localhost',  # 连接数据库
            user='数据库账号',
            passwd='数据库密码',
            database='数据库名'
        )
        self.cursor = self.db.cursor()

    # 获取一级评论
    def get_first_data(self):
        self.first_response = requests.get(self.first_url, params=self.first_data, headers=self.headers)
        self.first_data_json = self.first_response.json()    # json数据类型
        
        # 根据网页数据包结构,获取以及评论的内容以及评论者
        self.first_names = jsonpath(self.first_data_json, '$..data[:].user.screen_name')
        self.first_textss = jsonpath(self.first_data_json, '$..data[:].text')
        
        # 3.2 获取一级评论的cid,以匹配二级评论。放入for循环中遍历
        self.cids = jsonpath(self.first_data_json, '$..data[:].rootid')
        
        # 1.1获取网页max_id作为下一页的翻页参数
        self.max_id = jsonpath(self.first_data_json, '$..data.max_id')
        
        for self.first_name, self.first_texts, self.cid in zip(self.first_names, self.first_textss, self.cids):
            print('=========一级评论=========')    # 分隔符
            self.first_text = re.sub('<.*?>', '', self.first_texts)   # 正则处理表情包
            print(self.first_name, '----->', self.first_text)
            
            # 3.3 将循环遍历得到的cid改写二级评论初始化字典值
            self.second_data['cid'] = self.cid
            
            # 3.1 调用二级评论方法
            time.sleep(random.uniform(5, 9))
            try:        # 异常处理:如果没有二级评论还调用二级方法,json()解析不到数据就会报错:requests.exceptions.JSONDecodeError
                self.get_second_data()
            except:
                print('\t\t\t\t=========没有二级评论=========')
        
        # 1.2 要等第一页爬完之后才能递归调用
        self.first_data['max_id'] = self.max_id
        
        # 2.5 根据2.4添加条件判断
        if self.first_data['max_id'] == 0:
            print('一级评论获取完毕')
        else:
            # 1.3 递归调用,递归肯定会有程序报错的时候,所以我们要异常处理
            time.sleep(random.uniform(6, 9))
            self.get_first_data()

    # 获取二级评论
    def get_second_data(self):
        second_response = requests.get(self.second_url, params=self.second_data, headers=self.headers)
        self.second_data_json = second_response.json()  # json数据类型
        
        self.second_names = jsonpath(self.second_data_json, '$..data[:].user.screen_name')
        self.second_textss = jsonpath(self.second_data_json, '$..data[:].text')
        
        # 2.1获取二级网页max_id作为下一页的翻页参数
        self.second_max_id = jsonpath(self.second_data_json, '$..max_id')[0]
        
        # print(self.second_max_id)
        # print('\t\t\t\t', '-----------二级评论-----------')  # 分隔符
        
        for self.second_name, self.second_texts in zip(self.second_names, self.second_textss):
            self.second_text = re.sub('<.*?>', '', self.second_texts)  # 正则处理表情包
            print('\t\t\t\t', self.second_name, '----->', self.second_text)
            
            # 4 保存
            self.save_data()
        
        # 2.2递归调用
        self.second_data['max_id'] = self.second_max_id
        
        # 2.4 max_id=0时翻页结束,不等于0才递归
        if self.second_data['max_id'] == (0 | 186494897570):  # 第一条评论的最后一条跟评的数据报的max_id不知道怎么会使变了,所以只能加进来,否则程序报错
            print('------------二级评论获取完毕------------')
            self.second_data['max_id'] = 0
        else:
            time.sleep(random.uniform(7, 11))
            self.get_second_data()

    # 保存方法
    def save_data(self):
        sql = "insert into weibo_comments(first_author, first_comment, second_author, second_comment) values(%s, %s, %s, %s)"     # 占位符
        data = [self.first_name, self.first_text, self.second_name, self.second_text]      # 使用占位符插入数据,之前所有的代码前加self就是为了方便在类中共用变量,方便保存
        self.cursor.execute(sql, data)  # data要tuple、list、dict类型
        self.db.commit()

    def main(self):
        self.get_first_data()
        # self.get_second_data()


if __name__ == '__main__':
    weibo = WeiBo()
    weibo.main()

搜索:https://mp.weixin.qq.com/s/PPl8Ij229Qnb-WU4K3BWkwhttps://mp.weixin.qq.com/s/UzDBZzaLZox67y0ge2Y2tghttps://mp.weixin.qq.com/s/mMiVehzTsW-rTNbPGRnoqw

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值