先Po效果图,这是去年9月某期逗鱼时刻的弹幕词频分析,就是吾王巨经典的“我给XXX做牛做马”体刚刚兴起的那阵做的词云。
这个程序在我去年9月份左右的时候就写好了,时隔半年威力依旧不减当年,现在回头看这段代码已经完全不知所云了,所以想在彻底忘掉之前记录在万能的互联网上。
运行必要库:urllib.request,re,io,gzip,selenium
必要浏览器:火狐(版本不能太新)
主体代码如下,因为selenium中的page_source参数得到的网页源码和urllib.requests有时候不一样,所以我在这里都用了。。因此代码显得有些冗长,使用gzip的原因是b站页面貌似是gzip编码的方式,需要额外进行处理(这部分我也不懂,我google出来的解决方案就是导入gzip包然后这个那个的)。主要思路就是获取网页源码,用正则表达式找到CID号,然后进到对应的存放有所有弹幕的页面,继续用正则表达式把时间戳和弹幕内容筛出来,输入用户所希望的天数后,再简单处理一下弹幕内容就可以导出成文件了。经过测试一般视频可行,番剧弹幕还是不能下载。
用户需要自行改动的部分包括如下两个路径,上面那个系统路径是用户希望存放弹幕的位置,下面那个链接改成想要抓取的视频即可。
OK,抓取成功后随便在网上找个词云网站,导入你的文本就可以做出自己想要的模样了。有其他需求的同学还可以利用结巴分词来分析词频等,做一些图表之类的来做一些另类的研究什么的。= =。
#不加encoding的话有可能会报错
with open('C:/PythonProjects/data/'+ str(i) + 'DayAgoDanmu.txt','w',encoding='utf-8') as NDaysDanmuFile:
NDaysDanmuFile.write(RipeDanmu)
print('Done!')
#要抓取的视频
url = 'https://www.bilibili.com/video/av22945597'
-------------------------以下为主代码------------------------------------------
import urllib.request as ur
import re
import io
import gzip
from selenium import webdriver
def url_open(url):
req = ur.Request(url) # 添加一个文件头,需要先用Request,Request存在的意义是便于在请求的时候传入一些信息,而urlopen则不能
req.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36')
response = ur.urlopen(req)
if response.info().get('Content-Encoding') == 'gzip':
buf = io.BytesIO(response.read())
gzip_f = gzip.GzipFile(fileobj=buf)
html = gzip_f.read()
else:
html = response.read()
return html
def Get_History_DanMu(days=1):
#获取弹幕时间戳和数量信息
Days_Num = len(TimeAndNumber)
while int(days) > Days_Num:
print('所输入时间大于该视频的年龄')
days = input('请重新输入')
else:
print('网页的CID号为' + cidNumber)
for i in range(int(days)):
if i == 0:
print('今天的时间戳为' + TimeAndNumber[Days_Num - 1][0] + ' | ' + '今天的弹幕数量为' + TimeAndNumber[Days_Num - 1][1])
else:
print(str(i) + '天前的时间戳为' + TimeAndNumber[-1 - i][0] + ' | ' + str(i) + '天前的弹幕数量为' +
TimeAndNumber[-1 - i][1])
#下载弹幕
# 下载N天前的弹幕并且处理和存放
for i in range(int(days)):
if i == 0:
print('正在下载今天的弹幕……')
else:
print('正在下载' + str(i) + '天前的弹幕……')
NDays_DanMu_Url = 'http://comment.bilibili.com/' + 'dmroll,' + TimeAndNumber[-1 - i][0] + ',' + cidNumber
browser = webdriver.Firefox()
browser.get(NDays_DanMu_Url)
Raw_NDays_Danmu = browser.page_source
browser.close()
NDaysDanmuPattern = re.compile('(.+?)', re.S)
RipeDanmu = re.findall(NDaysDanmuPattern, Raw_NDays_Danmu)
RipeDanmu = '\n'.join(RipeDanmu)
#不加encoding的话有可能会报错
with open('C:/PythonProjects/data/'+ str(i) + 'DayAgoDanmu.txt','w',encoding='utf-8') as NDaysDanmuFile:
NDaysDanmuFile.write(RipeDanmu)
print('Done!')
#要抓取的视频
url = 'https://www.bilibili.com/video/av22945597'
#获取网页内容
html = url_open(url).decode('utf-8')
#寻找当前网页CID号
pattern = re.compile(r'cid=(.+?)&aid=.+?&pre_ad')
cidNumber1 = re.findall(pattern,html)
print(cidNumber1)
cidNumber = cidNumber1[0]
#找到存放所有弹幕时间戳的网页
AllDanmuUrl = 'http://comment.bilibili.com/rolldate,' + cidNumber
#DanMu = url_open(AllDanmuUrl).decode('utf-8'),这个方法不行
#设置浏览器
browser = webdriver.Firefox()
#读取上述网页内容
browser.get(AllDanmuUrl)
DanMu = browser.page_source
browser.close()
print(DanMu)
#正则表达式匹配全部时间戳和对应弹幕数量
pattern = re.compile(r'{"timestamp":"(.+?)","new":"(.+?)"}')
TimeAndNumber = re.findall(pattern,DanMu)
days = input('你希望下载几天的弹幕?')
Get_History_DanMu(int(days))
我自己也很清楚代码写的超级乱,因为是新手,初学python之后开脑洞写的东西,大佬们如果有兴趣的话还望指点一下,感谢!