鱼C论坛

 找回密码
 立即注册
查看: 833|回复: 5

爬取B站评论,下面代码只能爬取一级评论,求指导以下如何爬取交互回复信息哇.

[复制链接]
发表于 2023-11-10 20:19:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import requests
import re
import time
import csv

# 消息头信息
header = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
}

# 获取评论API
original_url = 'https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next={}&type=1&oid={}&mode=3'

# 时间戳转换成日期
def get_time(ctime):
    timeArray = time.localtime(ctime)
    otherStyleTime = time.strftime("%Y.%m.%d", timeArray)
    return str(otherStyleTime)

# 获取aid
def get_oid(bvid):
    video_url = 'https://www.bilibili.com/video/' + bvid
    page = requests.get(video_url, headers=header).text
    aid = re.search(r'"aid":[0-9]+', page).group()[6:]
    return aid

# 边爬取评论边保存文件
def online_save(bvid):
    all_count = 0
    oid = get_oid(bvid)
    page = 1
    url = original_url.format(page, oid)
    html = requests.get(url, headers=header)
    data = html.json()
    count = int(data['data']['cursor']['all_count'])
    fname = bvid + '_评论.csv'
    with open(fname, 'w+', newline='', encoding='utf_8_sig') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow(["时间", "点赞", "用户名", "评论"])  # Added "用户名" header
        for i in data['data']['replies']:
            message = i['content']['message']
            message = re.sub('\s+', '', message)
            ctime = get_time(i['ctime'])
            like = i['like']
            username = i['member']['uname']  # Added to get username
            csv_writer.writerow([ctime, str(like), username, message])  # Added username
            all_count = all_count + 1
            
            # Check for and collect reply comments
            if 'replies' in i:
                for reply in i['replies']:
                    reply_message = reply['content']['message']
                    reply_message = re.sub('\s+', '', reply_message)
                    reply_like = reply['like']
                    reply_username = reply['member']['uname']
                    csv_writer.writerow(["REPLY", str(reply_like), reply_username, reply_message])

        print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
        time.sleep(5)
        while all_count < count:
            page += 1
            url = original_url.format(page, oid)
            try:
                html = requests.get(url, headers=header)
                data = html.json()
                for i in data['data']['replies']:
                    message = i['content']['message']
                    ctime = get_time(i['ctime'])
                    like = i['like']
                    username = i['member']['uname']
                    csv_writer.writerow([ctime, str(like), username, message])
                    all_count = all_count + 1
                    
                    # Check for and collect reply comments
                    if 'replies' in i:
                        for reply in i['replies']:
                            reply_message = reply['content']['message']
                            reply_message = re.sub('\s+', '', reply_message)
                            reply_like = reply['like']
                            reply_username = reply['member']['uname']
                            csv_writer.writerow(["REPLY", str(reply_like), reply_username, reply_message])

                print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
                time.sleep(5)
            except:
                break
        f.close()

if __name__ == '__main__':
    bvid = input('输入视频Bvid:')
    online_save(bvid)
    print('完成!')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-10 20:20:08 | 显示全部楼层
这段代码存在一个问题,即它只能爬取一级评论而无法获取交互回复信息。要解决这个问题,你需要在获取一级评论后,检查每个评论是否有回复,如果有的话,再获取回复的内容。你可以修改代码如下:
# 边爬取评论边保存文件
def online_save(bvid):
    all_count = 0
    oid = get_oid(bvid)
    page = 1
    url = original_url.format(page, oid)
    fname = bvid + '_评论.csv'
    with open(fname, 'w+', newline='', encoding='utf_8_sig') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow(["时间", "点赞", "用户名", "评论", "回复类型", "回复点赞", "回复用户名", "回复内容"])  # 添加回复信息的表头
        while True:
            html = requests.get(url, headers=header)
            data = html.json()
            count = int(data['data']['cursor']['all_count'])
            for i in data['data']['replies']:
                message = i['content']['message']
                message = re.sub('\s+', '', message)
                ctime = get_time(i['ctime'])
                like = i['like']
                username = i['member']['uname']
                csv_writer.writerow([ctime, str(like), username, message, "", "", "", ""])  # 将回复信息留空
                all_count += 1

                # Check for and collect reply comments
                if 'replies' in i:
                    for reply in i['replies']:
                        reply_message = reply['content']['message']
                        reply_message = re.sub('\s+', '', reply_message)
                        reply_like = reply['like']
                        reply_username = reply['member']['uname']
                        csv_writer.writerow(["", "", "", "", "回复", str(reply_like), reply_username, reply_message])  # 添加回复信息
                        all_count += 1

            print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
            if all_count >= count:
                break
            page += 1
            url = original_url.format(page, oid)
            time.sleep(5)
    print('完成!')

这样修改后,代码将会在爬取一级评论的同时,检查是否有回复评论,如果有的话,也会将回复的内容一起保存到csv文件中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-10 20:33:07 | 显示全部楼层
isdkz 发表于 2023-11-10 20:20
这段代码存在一个问题,即它只能爬取一级评论而无法获取交互回复信息。要解决这个问题,你需要在获取一级评 ...
import requests
import re
import time
import csv

# 消息头信息
header = {
    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
}

# 获取评论API
original_url = 'https://api.bilibili.com/x/v2/reply/main?jsonp=jsonp&next={}&type=1&oid={}&mode=3'

# 时间戳转换成日期
def get_time(ctime):
    timeArray = time.localtime(ctime)
    otherStyleTime = time.strftime("%Y.%m.%d", timeArray)
    return str(otherStyleTime)

# 获取aid
def get_oid(bvid):
    video_url = 'https://www.bilibili.com/video/' + bvid
    page = requests.get(video_url, headers=header).text
    aid = re.search(r'"aid":[0-9]+', page).group()[6:]
    return aid

# 边爬取评论边保存文件
def online_save(bvid):
    all_count = 0
    oid = get_oid(bvid)
    page = 1
    url = original_url.format(page, oid)
    fname = bvid + '_评论.csv'
    with open(fname, 'w+', newline='', encoding='utf_8_sig') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow(["时间", "点赞", "用户名", "评论", "回复类型", "回复点赞", "回复用户名", "回复内容"])  # 添加回复信息的表头
        while True:
            html = requests.get(url, headers=header)
            data = html.json()
            count = int(data['data']['cursor']['all_count'])
            for i in data['data']['replies']:
                message = i['content']['message']
                message = re.sub('\s+', '', message)
                ctime = get_time(i['ctime'])
                like = i['like']
                username = i['member']['uname']
                csv_writer.writerow([ctime, str(like), username, message, "", "", "", ""])  # 将回复信息留空
                all_count += 1

                # Check for and collect reply comments
                if 'replies' in i:
                    for reply in i['replies']:
                        reply_message = reply['content']['message']
                        reply_message = re.sub('\s+', '', reply_message)
                        reply_like = reply['like']
                        reply_username = reply['member']['uname']
                        csv_writer.writerow(["", "", "", "", "回复", str(reply_like), reply_username, reply_message])  # 添加回复信息
                        all_count += 1

            print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
            if all_count >= count:
                break
            page += 1
            url = original_url.format(page, oid)
            time.sleep(5)
    
if __name__ == '__main__':
    bvid = input('输入视频Bvid:')
    online_save(bvid)
    print('完成!')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-10 20:34:06 | 显示全部楼层
isdkz 发表于 2023-11-10 20:20
这段代码存在一个问题,即它只能爬取一级评论而无法获取交互回复信息。要解决这个问题,你需要在获取一级评 ...

按照这样子,,我发现代码停不下来了
输入视频Bvid:BV1Hw411q7PV
总评论数:170,当前评论数:38,爬取Page1完毕。
总评论数:170,当前评论数:61,爬取Page2完毕。
总评论数:170,当前评论数:83,爬取Page3完毕。
总评论数:170,当前评论数:103,爬取Page4完毕。
总评论数:170,当前评论数:123,爬取Page5完毕。
总评论数:170,当前评论数:141,爬取Page6完毕。
总评论数:170,当前评论数:141,爬取Page7完毕。
总评论数:170,当前评论数:141,爬取Page8完毕。
总评论数:170,当前评论数:141,爬取Page9完毕。
总评论数:170,当前评论数:141,爬取Page10完毕。
总评论数:170,当前评论数:141,爬取Page11完毕。
总评论数:170,当前评论数:141,爬取Page12完毕。
总评论数:170,当前评论数:141,爬取Page13完毕。
总评论数:170,当前评论数:141,爬取Page14完毕。
总评论数:170,当前评论数:141,爬取Page15完毕。
总评论数:170,当前评论数:141,爬取Page16完毕。
总评论数:170,当前评论数:141,爬取Page17完毕。
总评论数:170,当前评论数:141,爬取Page18完毕。
总评论数:170,当前评论数:141,爬取Page19完毕。
总评论数:170,当前评论数:141,爬取Page20完毕。
总评论数:170,当前评论数:141,爬取Page21完毕。
总评论数:170,当前评论数:141,爬取Page22完毕。
总评论数:170,当前评论数:141,爬取Page23完毕。
总评论数:170,当前评论数:141,爬取Page24完毕。
总评论数:170,当前评论数:141,爬取Page25完毕。
总评论数:170,当前评论数:141,爬取Page26完毕。
总评论数:170,当前评论数:141,爬取Page27完毕。
总评论数:170,当前评论数:141,爬取Page28完毕。
总评论数:170,当前评论数:141,爬取Page29完毕。
总评论数:170,当前评论数:141,爬取Page30完毕。
总评论数:170,当前评论数:141,爬取Page31完毕。
总评论数:170,当前评论数:141,爬取Page32完毕。
总评论数:170,当前评论数:141,爬取Page33完毕。
总评论数:170,当前评论数:141,爬取Page34完毕。
总评论数:170,当前评论数:141,爬取Page35完毕。
总评论数:170,当前评论数:141,爬取Page36完毕。
总评论数:170,当前评论数:141,爬取Page37完毕。
总评论数:170,当前评论数:141,爬取Page38完毕。
总评论数:170,当前评论数:141,爬取Page39完毕。
总评论数:170,当前评论数:141,爬取Page40完毕。
总评论数:170,当前评论数:141,爬取Page41完毕。
总评论数:170,当前评论数:141,爬取Page42完毕。
总评论数:170,当前评论数:141,爬取Page43完毕。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-17 21:51:33 | 显示全部楼层
如果要把爬取的数据存入Mongodb数据库该怎么处理呢@FishC
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-17 21:51:51 | 显示全部楼层
梅开朗基罗 发表于 2023-12-17 21:51
如果要把爬取的数据存入Mongodb数据库该怎么处理呢@Fi ...

要将爬取的数据存入MongoDB数据库,你需要首先安装MongoDB和Python的MongoDB驱动程序(pymongo)。下面是一个简单的示例代码,展示了如何将数据存入MongoDB数据库:

首先,确保你已经安装好了MongoDB和pymongo。你可以使用以下命令来安装pymongo:
pip install pymongo
接下来,导入pymongo库并连接到MongoDB数据库:
from pymongo import MongoClient# 连接到MongoDB数据库client = MongoClient('mongodb://localhost:27017/')# 选择或创建一个数据库db = client['mydatabase']# 选择或创建一个集合(类似于关系数据库中的表)collection = db['mycollection']
现在,你可以将爬取的数据转换为字典,然后使用`insert_one()`方法将数据插入到集合中:
# 假设你有一条爬取到的数据data = {'name': 'Alice', 'age': 25, 'city': 'Shanghai'}# 将数据插入到集合中collection.insert_one(data)
这样就把一条数据存入到MongoDB数据库中了。如果你有多个数据需要插入,可以使用`insert_many()`方法。

另外,如果你想读取数据,可以使用`find()`方法来查询集合中的数据。例如:
# 查询集合中的所有数据results = collection.find()# 遍历结果集打印数据for result in results:    print(result)
希望这个例子对你有所帮助!请记得在使用之前先安装好MongoDB和pymongo库。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 23:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表