forked from DrRyanHuang/bilibiliTool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdanMuDownload.py
142 lines (107 loc) · 3.75 KB
/
danMuDownload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# -*- coding: utf-8 -*-
"""
@author: RyanHuang
@github: DrRyanHuang
@updateTime: 2020.5.8
@brife: 用于获取B站给定url视频的弹幕(无需登录, 无需cookie)
@notice:
If you have suggestions or find bugs, please be sure to tell me. Thanks!
"""
import requests
import re
from bs4 import BeautifulSoup
import pandas as pd
def getXMlUrl(reponse_text):
'''
@brife:
获得B站弹幕xml的url
(为了使代码可拓展性更好, 将此函数单独写出)
@para:
reponse_text : 响应的内容(Content of the response)
@notice:
弹幕所需要的oid和评论所需要的oid竟然不是一个oid
'''
match_rule = r'cid=(.*?)&aid'
oid = re.search(match_rule ,reponse_text).group().replace('cid=','').replace('&aid','')
# 通过该 `oid` 参数获得xml的链接
xml_url = 'https://api.bilibili.com/x/v1/dm/list.so?oid='+oid
return xml_url
def get_df_DanMuFromXML(xml_url, headers=None, save_bool=False, save_path=None):
'''
@brife:
从XML链接中, 获得B站弹幕, 并返回df
(为了使代码可拓展性更好, 将此函数单独写出)
@para:
xml_url : 响应的内容(Content of the response)
headers : 请求头字典
save_bool : 是否保存
save_path : 保存路径
'''
if headers is None:
headers = {
'User-Agent':'Mozilla/5.0',
}
resp = requests.get(xml_url, headers=headers)
# 改为推荐编码
resp.encoding = resp.apparent_encoding
# 煲汤
soup = BeautifulSoup(resp.text, 'html.parser')
# 获得当前的所有弹幕
danmu_list = soup.findAll('d')
# 处理所有的 XML
all_danmu = []
for item in danmu_list:
item_list = item.attrs['p'].split(',')
item_list.append(item.text)
all_danmu.append(item_list)
# 出现时间
# 弹幕类型 1为滚动弹幕 4位底部弹幕 5为顶部弹幕
# 字的大小 分别为 18 和 25
# 颜色 : FF FF FF为最大值, 转换为了 16 进制
# 添加弹幕时间戳
# 是否被保护 ??
# 用户 id ??
# 弹幕 id ?? (其在XML中为递增, 与时间戳同为递增)
columns = ['出现时间',
'弹幕类型',
'字的大小',
'颜色',
'弹幕添加时间戳',
'unknown_5',
'unknown_6',
'unknown_7',
'弹幕内容']
danmu_df = pd.DataFrame(all_danmu, columns=columns)
if save_bool:
if save_path is None:
save_path = 'danmu.csv'
danmu_df.to_csv(save_path, index=False)
return danmu_df
def getDanMu(bv_url, headers=None, getXMlUrlFun=None, getDanmuFunc=None, save_bool=False, save_path=None):
'''
@brife:
从B站链接中下载弹幕
(为了使代码可拓展性更好, 可将处理函数传入)
@para:
bv_url : B站视频链接
headers : 请求头, 详见 `requests.request` 参数解析
getXMlUrlFun : 获得XML链接的函数
getDanmuFunc : 处理弹幕数据的函数
save_bool : 是否保存
save_path : 保存路径
注: 若 `getXMlUrlFun` 和 `getDanmuFunc` 参数需要修改, 则推荐使用 `lambda` 表达式
'''
if headers is None:
headers = {
'User-Agent':'Mozilla/5.0',
}
if getXMlUrlFun is None:
getXMlUrlFun = getXMlUrl
if getDanmuFunc is None:
getDanmuFunc = get_df_DanMuFromXML
resp = requests.get(bv_url, headers=headers)
# 得到弹幕XML链接
danmuXML_url = getXMlUrlFun(resp.text)
# 得到弹幕数据
danmu_df = getDanmuFunc(danmuXML_url, save_bool=save_bool, save_path=save_path)
return danmu_df