欢迎关注」,唯一笔者是 BuyiXiao,又名小布衣、肖不已。 BuyiXiao,何许人也?本衡州一乡野村夫,身高八尺不足,年方二十有余;弱冠之年曾求学于潭州,为谋生计,背井离乡,远赴京畿,我本南人,不习北土,兼有故友,威逼利诱,急于星火,遂下岭南,打工未半,中道创业,所为何业?赛博朋克,智能硬件;假工程师之名,行农民工之实,满腹经纶,无用书生,善于自黑,贻笑大方。 笔者水平有限,可能暂时无法将非常干货的教程讲的不拖泥带水又不哗众取宠,公众号文章诸多遗漏或不妥之处。 另外,文末点下「赞」和「在看」,这样每次新文章推送,就会第一时间出现在你的订阅号列表里。
转眼又到年关,不知不觉距离 2023 bilibili 视频评论爬虫 发布已经过去 6 个月了,当时一并分享了 python 3 源代码和 windows 打包软件,收到了不少反馈。
然后陆陆续续收到了一些代码无法运行、软件双击崩溃之类的 bug 反馈,应该是要更新了,本着不拖到 2024 再更新的原则,就有了今天这次推送。
其实报错的原因就一个:
errors.JSONDecodeError: Expecting value
一个请求的响应解析错误,而这个请求又是冗余的,直接把请求发起和响应全部删除掉就行,即原来的代码 58-62 行全部删除,又加了屏蔽代理等小改动,于是代码变成了下面这样:
# -*- coding: utf-8 -*-
# 作者: inspurer(月小水长)
# 创建时间: 2020/10/30 23:48
# 运行环境 Python3.6+
# github https://github.com/inspurer
# qq邮箱 2391527690@qq.com
# 微信公众号 月小水长(ID: inspurer)
# 文件备注信息 回复没有展开
import requests
import os
from time import sleep
import json
import time
import pandas as pd
import re
os.environ['NO_PROXY'] = 'bilibili.com'
def intToStrTime(a):
b = time.localtime(a) # 转为日期字符串
c = time.strftime("%Y/%m/%d %H:%M:%S", b) # 格式化字符串
return c
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3970.5 Safari/537.36',
'Referer': 'https://www.bilibili.com/'
}
def validateTitle(title):
re_str = r"[\/\\\:\*\?\"\<\>\|]" # '/ \ : * ? " < > |'
new_title = re.sub(re_str, "_", title) # 替换为下划线
return new_title
def main():
save_folder = 'Comment'
if not os.path.exists(save_folder):
os.mkdir(save_folder)
# bvs = ['BV1Zo4y1N7f1']
input_bvs = input('请输入 bv 号,多个 bv 号以空格分隔:')
bvs = input_bvs.split(' ')
for bv in bvs:
print(bv)
response = requests.get(url='https://www.bilibili.com/video/{}'.format(bv), headers=headers)
res = re.findall('<script>window.__INITIAL_STATE__=(.*)?;\(function\(\)', response.text, re.S)
json_data = json.loads(res[0])
if 'message' in json_data['error']:
print(json_data['error']['message'])
continue
aid = json_data['aid']
title = json_data['videoData']['title']
title = validateTitle(title)
comment_url = 'https://api.bilibili.com/x/v2/reply?callback=jQueryjsonp=jsonp&pn={}&type=1&oid={}&sort=2&_=1594459235799'
response = requests.get(url=comment_url.format(1, aid), headers=headers)
total_page = json.loads(response.text)['data']['page']['count'] // 20 + 1
page = 1
is_root, uname, comments, times, likes = [], [], [], [], []
while True:
data = json.loads(response.text)['data']['replies']
print(data)
if not data:
data = json.loads(response.text)['data']
if 'hots' in data.keys():
data = data['hots']
else:
break
for row in data:
print('根评论', row['member']['uname'], row['content']['message'])
is_root.append('是')
times.append(intToStrTime(row['ctime']))
uname.append(row['member']['uname'])
comments.append(row['content']['message'])
likes.append(row['like'])
if row.get('replies'):
for crow in row['replies']:
is_root.append('否')
times.append(intToStrTime(crow['ctime']))
uname.append(crow['member']['uname'])
comments.append(crow['content']['message'])
likes.append(crow['like'])
print('---子评论', crow['member']['uname'], crow['content']['message'])
page += 1
if page > total_page:
break
sleep(1)
response = requests.get(url=comment_url.format(page, aid), headers=headers)
# 边爬取边保存
df = pd.DataFrame(
{'评论时间': times, '评论者': uname, '评论内容': [''.join(comment.split()) for comment in comments], '点赞数': likes})
df.to_csv(f'{save_folder}/{title}.csv', encoding='utf-8-sig', index=False)
print(f'\n\n已经保存 {df.shape[0]} 条评论到 {save_folder}/{title}.csv\n\n')
sleep(1)
# 每抓完 1 条视频的评论休眠 10s
sleep(10)
if __name__ == '__main__':
main()
直接将上述代码保存到 py 文件中,无需任何修改,可以在 cmd 中调用 python 环境或者直接在 Pycharm 运行该文件,输入待抓取的 b 站 bv 号就可开始采集该视频的评论~
同时考虑到很多读者朋友们没有 Python 环境,或者根本不想安装 Python 环境,一如既往地提供了 windows exe 版本。
年底老板让你写公司的 B 站账号总结的时候,
直接拿出这个工具,一顿操作,把公司账号的视频下面的评论采集到本地,
然后 Excel 打开分析,或者用本号分析过的一些在线分析工具,
同事还在肉眼总结的时候,你已经得出漂亮的分析结果了,一跃成为办公室最靓的仔,来年开工的升职加薪,铁定少不了你;
如果你把这个工具发给同事,同事成为靓仔升职加薪了,他能忘得了你嘛,提拔你也是分分钟的事好吧。
In a word,有需求的用好这个工具,赢麻了
多多点赞评论转发,读者朋友的支持是更新的最大动力