鱼C论坛

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

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

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

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

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

x
  1. import requests
  2. import re
  3. import time
  4. import csv

  5. # 消息头信息
  6. header = {
  7.     'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  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',
  9. }

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

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

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

  23. # 边爬取评论边保存文件
  24. def online_save(bvid):
  25.     all_count = 0
  26.     oid = get_oid(bvid)
  27.     page = 1
  28.     url = original_url.format(page, oid)
  29.     html = requests.get(url, headers=header)
  30.     data = html.json()
  31.     count = int(data['data']['cursor']['all_count'])
  32.     fname = bvid + '_评论.csv'
  33.     with open(fname, 'w+', newline='', encoding='utf_8_sig') as f:
  34.         csv_writer = csv.writer(f)
  35.         csv_writer.writerow(["时间", "点赞", "用户名", "评论"])  # Added "用户名" header
  36.         for i in data['data']['replies']:
  37.             message = i['content']['message']
  38.             message = re.sub('\s+', '', message)
  39.             ctime = get_time(i['ctime'])
  40.             like = i['like']
  41.             username = i['member']['uname']  # Added to get username
  42.             csv_writer.writerow([ctime, str(like), username, message])  # Added username
  43.             all_count = all_count + 1
  44.             
  45.             # Check for and collect reply comments
  46.             if 'replies' in i:
  47.                 for reply in i['replies']:
  48.                     reply_message = reply['content']['message']
  49.                     reply_message = re.sub('\s+', '', reply_message)
  50.                     reply_like = reply['like']
  51.                     reply_username = reply['member']['uname']
  52.                     csv_writer.writerow(["REPLY", str(reply_like), reply_username, reply_message])

  53.         print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
  54.         time.sleep(5)
  55.         while all_count < count:
  56.             page += 1
  57.             url = original_url.format(page, oid)
  58.             try:
  59.                 html = requests.get(url, headers=header)
  60.                 data = html.json()
  61.                 for i in data['data']['replies']:
  62.                     message = i['content']['message']
  63.                     ctime = get_time(i['ctime'])
  64.                     like = i['like']
  65.                     username = i['member']['uname']
  66.                     csv_writer.writerow([ctime, str(like), username, message])
  67.                     all_count = all_count + 1
  68.                     
  69.                     # Check for and collect reply comments
  70.                     if 'replies' in i:
  71.                         for reply in i['replies']:
  72.                             reply_message = reply['content']['message']
  73.                             reply_message = re.sub('\s+', '', reply_message)
  74.                             reply_like = reply['like']
  75.                             reply_username = reply['member']['uname']
  76.                             csv_writer.writerow(["REPLY", str(reply_like), reply_username, reply_message])

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

  82. if __name__ == '__main__':
  83.     bvid = input('输入视频Bvid:')
  84.     online_save(bvid)
  85.     print('完成!')
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-10 20:20:08 | 显示全部楼层
这段代码存在一个问题,即它只能爬取一级评论而无法获取交互回复信息。要解决这个问题,你需要在获取一级评论后,检查每个评论是否有回复,如果有的话,再获取回复的内容。你可以修改代码如下:

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

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

  32.             print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
  33.             if all_count >= count:
  34.                 break
  35.             page += 1
  36.             url = original_url.format(page, oid)
  37.             time.sleep(5)
  38.     print('完成!')
复制代码


这样修改后,代码将会在爬取一级评论的同时,检查是否有回复评论,如果有的话,也会将回复的内容一起保存到csv文件中。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  5. # 消息头信息
  6. header = {
  7.     'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  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',
  9. }

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

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

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

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

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

  54.             print('总评论数:{},当前评论数:{},爬取Page{}完毕。'.format(count, all_count, page))
  55.             if all_count >= count:
  56.                 break
  57.             page += 1
  58.             url = original_url.format(page, oid)
  59.             time.sleep(5)
  60.    
  61. if __name__ == '__main__':
  62.     bvid = input('输入视频Bvid:')
  63.     online_save(bvid)
  64.     print('完成!')
复制代码
小甲鱼最新课程 -> https://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完毕。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-17 21:51:33 | 显示全部楼层
如果要把爬取的数据存入Mongodb数据库该怎么处理呢@FishC
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

首先,确保你已经安装好了MongoDB和pymongo。你可以使用以下命令来安装pymongo:
  1. pip install pymongo
复制代码

接下来,导入pymongo库并连接到MongoDB数据库:
  1. from pymongo import MongoClient
  2. # 连接到MongoDB数据库
  3. client = MongoClient('mongodb://localhost:27017/')
  4. # 选择或创建一个数据库
  5. db = client['mydatabase']
  6. # 选择或创建一个集合(类似于关系数据库中的表)
  7. collection = db['mycollection']
复制代码

现在,你可以将爬取的数据转换为字典,然后使用`insert_one()`方法将数据插入到集合中:
  1. # 假设你有一条爬取到的数据
  2. data = {'name': 'Alice', 'age': 25, 'city': 'Shanghai'}
  3. # 将数据插入到集合中
  4. collection.insert_one(data)
复制代码

这样就把一条数据存入到MongoDB数据库中了。如果你有多个数据需要插入,可以使用`insert_many()`方法。

另外,如果你想读取数据,可以使用`find()`方法来查询集合中的数据。例如:
  1. # 查询集合中的所有数据
  2. results = collection.find()
  3. # 遍历结果集打印数据
  4. for result in results:
  5.     print(result)
复制代码

希望这个例子对你有所帮助!请记得在使用之前先安装好MongoDB和pymongo库。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-24 00:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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