不能忘却的记忆| B站弹幕爬虫
本文作者:任 哲,中南财经政法大学经济学院
本文编辑:王子一
技术总编:张馨月
爬虫俱乐部云端课程
提及2020年,每个人都无法忘却新冠疫情,也不会忘记武汉这所英雄城市。在2020年的最后一天,小编爬取了B站《武汉UP实拍,封城后的24小时,“空城”武汉的物价、交通 、生活状态》的弹幕。up主林晨同学在武汉封城之后上传了这段视频,让全国人民在谣言与真相充斥的社交网络之中了解到封城后的武汉以及英雄的武汉人民是什么样子。下面,让我们通过爬取弹幕,来寻找那段日子里我们留下的共同记忆。
一、观察网站
在爬取弹幕之前,要先找到B站的弹幕列表在哪里。打开视频,我们能清楚看到视频窗口的右边有一个弹幕列表,展开后就能看到一些弹幕的内容。
这些红框里的内容可以用xpath定位的,但只显示了3000条数据,而视频共有18.1万条弹幕。通过查看历史弹幕选项,可以查找到历史弹幕。在点击该选项之前,我们先打开Chrome浏览器的开发者模式,寻找储存历史弹幕的真实链接,如下图所示:
依次点击之后红框之后,就能看到蓝框之中的Request URL,把它复制下来如下:
https://api.bilibili.com/x/v2/dm/history?type=1&oid=145104388&date=2020-04-08
其中oid=145104388
就是该视频对应的弹幕编号,date=2020-04-08
指查询日期。点击该url后会出现如下网站:
这样,我们就能用requests获取所有的历史弹幕了,下面开始具体爬虫。
二、具体操作
找到能够指向历史弹幕的url之后,弹幕的爬取就变得异常简单了。我们首先导入所需要的库:
import requests
import time
import os
import random
import datetime
from datetime import datetime as dt
import re
单独一天的弹幕爬虫非常简单,利用requests直接获取网页源代码即可,该网页的源代码和显示内容完全一致。获取到源代码之后,我们可以将其写入到txt文本中。代码如下:
url = "https://api.bilibili.com/x/v2/dm/history?type=1&oid=145104388&date=2020-04-08"
headers = {
"authority": "api.bilibili.com",
"method": "GET",
"scheme": "https",
"accept-encoding": "gzip, deflate, br",
"accept-language": "zh-CN,zh;q=0.9",
"cache-control": "no-cache",
"cookie": "这里包含视频和账号信息,就不提供了~请输入你自己的cookies。"
"pragma": "no-cache",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
response = requests.get(url=url, headers=headers) #headers请根据实际情况自己设定
response.encoding = 'utf-8'
text = response.text
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write("\n弹幕\n")
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write("\n-------------------------------------我是分割线-----------------------------------------\n")
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write(text)
得到的结果如下:
为了获取全部日期的历史弹幕,我们需要生成一个包含视频上传至今所有日期的列表,然后循环爬取即可。具体代码如下:
#先定义一个日期列表
import pandas as pd
list_daterange = [x.strftime('%Y-%m-%d') for x in list(pd.date_range(start='2020-01-24', end='2020-12-21'))]
#对各个日期进行循环
for date in list_daterange :
url = "https://api.bilibili.com/x/v2/dm/history?type=1&oid=145104388&date=%s"%date
response = requests.get(url=url, headers=headers)
response.encoding = 'utf-8'
text = response.text
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write("\n弹幕\n")
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write("\n-------------------------------------我是分割线------------------------\n")
with open("145104388弹幕.txt","a",encoding="utf8") as f:
f.write(text)
t = random.randint(15,30)
time.sleep(t)
这样,就可以得到全部的历史弹幕了。接下来,使用正则表达式,即可提取弹幕的具体内容,代码如下:
f = open("145104388弹幕.txt","r",encoding="utf8")
content = f.read()
f.close()
words=re.findall('">(.*?)</d>',content,re.S)
三、绘制词云图
在得到全部的历史弹幕后,我们就可以根据这些弹幕绘制词云图了。绘制词云图的方法,我们已经讲过多次了,如果您还有需要请前往《用词云图看2020社科基金课题~》。根据历史弹幕绘制了词云图,从图中可以看到,在疫情期间全国各地的小伙伴都以独特的方式为武汉加油打气,送来了真挚的关切和祝福。
2020年不容忘却,在珍视和反思的同时,也祝愿每个人都可以带着勇气和希望重新出发。
最后,祝大家新年快乐,早日摘掉口罩~
工作中一切困难的解决途径——motivatedolly
【爬虫实战】喜茶的门店都开在了哪里?
如何简洁地列出指定属性的变量?ds命令来了!
如何在Python中进行描述性统计分析?
分析师和他们的雇主重视与管理层接触吗?——分析师参与盈余电话会议的研究
爬虫俱乐部开发的命令更新及常见问题说明
Seminar | 道德培训真的有用吗?
统计年鉴数据整理小技巧
Seminar | 作为飞行员,我比别的CEO多了什么?
利用TensorFlow构建前馈神经网络
推文合集(1)| Stata学习者必看的n篇推文!
微信公众号“Stata and Python数据分析”分享实用的stata、python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。