代码部分
获得弹幕
import re
import requests
import bs4
from bs4 import BeautifulSoup
#获取弹幕
def getDM(oid):
r=requests.get('https://api.bilibili.com/x/v1/dm/list.so?oid='+oid)
r.encoding=r.apparent_encoding
return r.text
#截取有效弹幕部分
def cutDM(html):
soup=BeautifulSoup(html,'html.parser')
ls=soup.find_all('d')
danmu=''
for i in ls:
content=''.join(i.string)
danmu+=content
#content=str(ls)
#pattern=re.compile('<d.*?>(.*?)</d>')
#danmu=pattern.findall(content)
return danmu
def saveDM(danmu):
f=open('danmu.txt','wt',encoding='utf-8')
danmu=str(danmu)
f.write(danmu)
def main():
oid=input('请输入oid:')
html=getDM(oid)
danmu=cutDM(html)
saveDM(danmu)
main()
制作词云
import wordcloud
from matplotlib.pyplot import imread
import jieba
txt=open('danmu.txt','r',encoding='UTF-8').read()
ls=jieba.lcut(txt)
content=' '.join(ls)
print(content)
mk=imread('C:/Users/ASUS/Pictures/sui1.jpg')
w=wordcloud.WordCloud(font_path='msyh.ttc',width=700,height=1000,background_color='white',mask=mk)
w.generate(content)
w.to_file('sui.png')
任务分析
首先爬取弹幕制作词云任务很明显的分为两个部分:数据爬取和数据分析。数据爬取时我们需要爬取B站的弹幕信息,但是由于弹幕信息并非直接显示在当前视频页面的html下,所以我们必须使用’检查‘来寻找存放弹幕信息的xml。爬取好了的弹幕我们需要进行处理,裁取出有效的部分,再进行词频的统计以及词云的制作。
弹幕爬取
在这个程序中,我们首先使用requests库进行网页爬取,但是由于这个例子比较简单,你也可以使用python自带的网络爬虫工具来完成。
由于B站弹幕页面header的编码格式并不是支持中文的utf-8,所以我们要更改页面编码格式,你可以把编码格式手动改为utf-8,也可以将编码格式改成页面实际编码格式。
然后我们可以使用r.text获得页面的所有信息。如果你还想再看一次的话,使用print()函数。
import requests
r=requests.get('https://api.bilibili.com/x/v1/dm/list.so?oid='+oid)
r.encoding=r.apparent_encoding
html=r.text
print(html)
弹幕裁取
在爬取好页面信息html后,我们使用BeautifulSoup库进行html页面的解析。将html解析成beautifulsoup类。
soup=BeautifulSoup(html,'html.parser')
在任务执行前对页面的分析或者刚刚我们用print()函数所看到的页面信息中,我们可以发现:弹幕内容被存放到了d标签中的字符串中。所以我们可以通过soup.find_all()来获得所有d标签。然后我们使用一个for循环获得单个标签,再通过tag.string 来获得b标签的字符串内容,即我们所需要的弹幕内容。
ls=soup.find_all('d')
danmu=''
for i in ls:
content=''.join(i.string)
danmu+=content
当然,你要是不嫌烦的话,可以按照网上许多教程所说的那样获得d标签的所有内容,然后再用正则表达式截取出弹幕内容。当然这样就比较麻烦,显然辜负了B站程序员们清楚的代码风格。但是这锻炼了你正则表达式的熟练度。
content=str(ls)
pattern=re.compile('<d.*?>(.*?)</d>')
danmu=pattern.findall(content)
词云制作
最后我们需要制作词云,由于B站弹幕绝大部分是中文,我们可以使用jieba库对弹幕内容进行分词。如果你想要更好的分词结果:比如支持日文和其他语言,你可能需要其他的工具支持。
import jieba
txt=open('danmu.txt','r',encoding='UTF-8').read()
ls=jieba.lcut(txt)
content=' '.join(ls) #空格分隔词语,方便下一步词云的制作
print(content) #检查
分词后我们就可以使用Wordcloud库进行词云制作了。如果你想要制作一个特别的词云,你可能需要mask的支持。mask可以理解为蒙版,可以使你的词云呈现特定的形状。你需要使用matplotlib.pyplot库来读取你的图片mask。最后将词云文件保存,任务完成。最后我们得到的结果如下:词云效果
import wordcloud
from matplotlib.pyplot import imread
mk=imread('C:/Users/ASUS/Pictures/sui1.jpg')
w=wordcloud.WordCloud(font_path='msyh.ttc',width=700,height=1000,background_color='white',mask=mk)
w.generate(content)
w.to_file('sui.png')
当然,这个任务还有很多可以优化的地方,比如我们可以直接通过BV号获得oid,而不用去寻找视频的oid;我们可以批量获得一个用户的所有视频的数据,制作数据量更大的词云;我们还可以支持多语言的分词,设置词表来达到更好的分词效果。有空我会继续更新。
优化1:直接通过BV号获得oid(4.4完成)
如果直接使用requests库的get去爬取页面的话,我们无法看到视频的oid,所以为了模拟人真实的行为来获得我们所需要的数据,我们需要使用selenium库来模仿一个浏览器进行操作。
from selenium import webdriver
driver=webdriver.Firefox()
driver.get('https://www.bilibili.com/video/'+bv)
上面我们模拟了火狐浏览器对url进行访问,这时候我们就可以做到所见即所得了。
对视频url进行爬取之后我们需要对我们获得的无比复杂的视频源页面的oid进行分析,具体过程如下:
soup=BeautifulSoup(html,'html.parser')
content=soup.find(string=re.compile(r'.bilivideo.com/upgcxcode'))
a=''
a+=content
b=a.split('base_url')
c=''
c+=b[0]
d=c.split('upgcxcode')
e=''
e+=d[1]
content=e.split('/',4)
oid=content[3]
这里的思路就是用split不断进行切割,最后得到视频的oid。
接下来的步骤就和之前一样了。
优化2:批量获得一个用户的所有视频的数据(4.4完成)
想了想很简单,其实优化1和2对之前的我的关键难点就是无法模拟人的操作,在掌握了selenium之后这些难题就迎刃而解了。
这个优化可以这样实现:
1.获取用户的uid并访问其空间
2.获取空间中的视频bv号
3.沿用优化1的方法