脚本地址:
提要
适用于: 任意 B 站视频弹幕 XML 文件下载. 如不能, 请提交 issues 联系我. 支持指定屏蔽词.
1 秒即可完成自动解析任意 B 站视频的视频弹幕 XML 文件请求链接, 并下载.
使用方法
- 克隆或下载项目代码。
- 安装依赖:
pip install requests lxml
, 或者克隆项目代码后pip install -r requirements.txt
- 脚本顶部: 指定常量
FOLDER_PATH
, 脚本默认为E:\Gazer\BilibiliGaze\data
, 作为保存 XML 文件路径. 如指定屏蔽词, 会生成两份 XML 文件, 文件结构见下. - 主函数处: 指定 XML 文件名
file_name
- 主函数处: 指定
url
, 要下载弹幕的视频 URL - 主函数处: (可选) 指定
words
弹幕屏蔽词
文件保存结构:
BilibiliGaze
└── data
├── processed
│ └── comment
│ └── clean_dan_mu.xml
└── raw
└── comment
└── dan_mu.xml
代码结构
get_url
从 HTML 中的window.__playinfo__
提取解析视频的 cid 参数get_xml
接收get_url
的返回 cid, 构造 XML 页面链接write_xml
写入保存未修改的弹幕 XML 文件block_shits
如指定了屏蔽词, 另保存一份清理后的弹幕 XML 文件
cid 的获取
使用脚本自动获取 B 站视频 cid
的思路一般是使用 bs4 来解析:
示例 (Python + requests
+ BeautifulSoup
):
import requests
from bs4 import BeautifulSoup
import re
def get_cid_from_html(url):
"""从 B 站视频页面 HTML 源代码中提取 cid"""
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get(url, headers=headers)
response.raise_for_status() # 检查请求是否成功
soup = BeautifulSoup(response.text, 'html.parser')
cid_script = soup.find('script', text=re.compile(r'"cid":'))
if cid_script:
match = re.search(r'"cid":(\d+)', cid_script.string)
if match:
return match.group(1)
return None
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
except Exception as e:
print(f"解析失败: {e}")
return None
if __name__ == '__main__':
video_url = 'https://www.bilibili.com/video/BV1i3411w7m3' # 替换成你的视频 URL
cid = get_cid_from_html(video_url)
if cid:
print(f"视频的 CID 是: {cid}")
else:
print("未能找到视频的 CID")
但我发现 cid 其实就在 HTML 里面的 script 标签 window.__playinfo__
里面. 根据上一篇中写到的使用正则表达式找到 window.__playinfo__
的值,
window\.__playinfo__\s*=\s*({.*?"video":.*?"audio":.*?"session":.*?})\s*
, 然后选取['data']['dash']['video'][0]['baseUrl']
得到这个
https://xy60x163x162x138xy240eyf7ye000y660yy1bxy.mcdn.bilivideo.cn:4483/upgcxcode/99/38/1109485925/1109485925-1-100022.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1740721988&gen=playurlv2&os=mcdn&oi=2104662226&trid=00004af14e75c1fa489794b0c1129a26c41eu&mid=0&platform=pc&og=cos&upsig=d9494a1a248c855fea3d23418a267e22&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform,og&mcdnid=50015422&bvc=vod&nettype=0&orderid=0,3&buvid=23327D6A-D1D8-11E7-0808-4DEDFA843F7716556infoc&build=0&f=u_0_0&agrr=0&bw=19818&logo=A0020000
url字符串, 然后我再url.split('/')[6]
就能拿到它的 cid 为 1109485925.
这种方法直接从 JavaScript 对象中提取数据,避免对整个 HTML 页面进行解析,避免使用 soup.prettify(),直接在原始 HTML 字符串中搜索, 速度更快.
XML 文件解析
直接使用 bs4 解析 XML 文件会报错 bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: xml
.
错误原因:
BeautifulSoup
默认没有安装 XML 解析器- 需要手动安装 XML 解析器,例如
lxml
或xml.etree.ElementTree
解决方案:
-
安装
lxml
:lxml
是一个高性能的 XML 和 HTML 解析库,支持 XPath 和 CSS 选择器。- 使用 pip 安装:
pip install lxml
- 安装完成后,重新运行代码。
-
指定
lxml
解析器:-
在
BeautifulSoup
构造函数中,将features
参数设置为"xml"
:soup = BeautifulSoup(response.content.decode('utf-8'), features="xml")
-
XML 文件转 ASS 文件
无友情链接 👉🏻 bilibili ASS 弹幕在线转换
下面是一些说明, 方便自定义 ASS 样式.
ASS 文件 style 说明
[Script Info]
详解:
[Script Info]
部分包含了 ASS 文件的基本信息。
ScriptType: v4.00+
: 脚本类型,表示该 ASS 文件的脚本类型为 “v4.00+”。WrapStyle: 0
: 换行样式,表示该 ASS 文件的换行样式为 “0”。0
:智能换行,根据窗口大小自动换行。1
:强制换行,在指定位置强制换行。2
:不换行,不进行任何换行处理。3
:与0
类似,但是在换行时会保留空格。
ScaledBorderAndShadow: yes
: 缩放边框和阴影,表示该 ASS 文件是否缩放边框和阴影。yes
:缩放边框和阴影。no
:不缩放边框和阴影。
YCbCr Matrix: None
: YCbCr 矩阵,表示该 ASS 文件的 YCbCr 矩阵。None
:使用默认的 YCbCr 矩阵。TV.601
:使用 TV.601 YCbCr 矩阵。TV.709
:使用 TV.709 YCbCr 矩阵。PC.601
:使用 PC.601 YCbCr 矩阵。PC.709
:使用 PC.709 YCbCr 矩阵。
ASS 文件 style 详解:
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,SimHei,12,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,134
-
Format:
: 定义了 style 的格式。Name
:style 的名称。Fontname
:字体名称。Fontsize
:字体大小。PrimaryColour
:主要颜色 (文本颜色)。SecondaryColour
:次要颜色 (卡拉 OK 效果)。OutlineColour
:轮廓颜色。BackColour
:背景颜色。Bold
:粗体 (1 表示是,0 表示否)。Italic
:斜体 (1 表示是,0 表示否)。Underline
:下划线 (1 表示是,0 表示否)。StrikeOut
:删除线 (1 表示是,0 表示否)。ScaleX
:X 轴缩放比例。ScaleY
:Y 轴缩放比例。Spacing
:字符间距。Angle
:旋转角度。BorderStyle
:边框样式 (1 表示轮廓,3 表示阴影)。Outline
:轮廓宽度。Shadow
:阴影深度。Alignment
:对齐方式。MarginL
:左边距。MarginR
:右边距。MarginV
:垂直边距。Encoding
:编码方式。
-
Style:
: 定义了一个具体的 style。Default,SimHei,12,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,134
:Name
:Default
。Fontname
:SimHei
(SimHei 字体)。Fontsize
:12
(12 像素)。PrimaryColour
:&H00FFFFFF
(白色)。SecondaryColour
:&H000000FF
(蓝色)。OutlineColour
:&H00000000
(黑色)。BackColour
:&H00000000
(透明)。Bold
:-1
(是)。Italic
:0
(否)。Underline
:0
(否)。StrikeOut
:0
(否)。ScaleX
:100
(100%)。ScaleY
:100
(100%)。Spacing
:0
(0 像素)。Angle
:0
(0 度)。BorderStyle
:1
(轮廓)。Outline
:2
(2 像素)。Shadow
:2
(2 像素)。Alignment
:2
(居中)。MarginL
:10
(10 像素)。MarginR
:10
(10 像素)。MarginV
:10
(10 像素)。Encoding
:134
(GB2312 编码)。
可以根据自己的需要修改 Style:
行的值来定制 ASS 文件的 style。
例如:
- 修改字体为
Microsoft YaHei
:Style: Default,Microsoft YaHei,24,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,134
- 修改字体大小为
30
:Style: Default,SimHei,30,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,134
- 修改字体颜色为
红色
:Style: Default,SimHei,24,&H000000FF,&H000000FF,&H00000000,&H00000000,-1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,134