源代码和软件 | 采集 1w+ B 站视频评论(年底更新版)

2023-12-30 14:37:28 浏览数 (2)

欢迎关注」,唯一笔者是 BuyiXiao,又名小布衣、肖不已。 BuyiXiao,何许人也?本衡州一乡野村夫,身高八尺不足,年方二十有余;弱冠之年曾求学于潭州,为谋生计,背井离乡,远赴京畿,我本南人,不习北土,兼有故友,威逼利诱,急于星火,遂下岭南,打工未半,中道创业,所为何业?赛博朋克,智能硬件;假工程师之名,行农民工之实,满腹经纶,无用书生,善于自黑,贻笑大方。 笔者水平有限,可能暂时无法将非常干货的教程讲的不拖泥带水又不哗众取宠,公众号文章诸多遗漏或不妥之处。 另外,文末点下「」和「在看」,这样每次新文章推送,就会第一时间出现在你的订阅号列表里。

转眼又到年关,不知不觉距离 2023 bilibili 视频评论爬虫 发布已经过去 6 个月了,当时一并分享了 python 3 源代码和 windows 打包软件,收到了不少反馈。

然后陆陆续续收到了一些代码无法运行、软件双击崩溃之类的 bug 反馈,应该是要更新了,本着不拖到 2024 再更新的原则,就有了今天这次推送。

其实报错的原因就一个:

errors.JSONDecodeError: Expecting value

一个请求的响应解析错误,而这个请求又是冗余的,直接把请求发起和响应全部删除掉就行,即原来的代码 58-62 行全部删除,又加了屏蔽代理等小改动,于是代码变成了下面这样:

代码语言:javascript复制
# -*- 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'nn已经保存 {df.shape[0]} 条评论到 {save_folder}/{title}.csvnn')

            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,有需求的用好这个工具,赢麻了

多多点赞评论转发,读者朋友的支持是更新的最大动力

0 人点赞