本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

以下文章源于Python干货铺子 ,作者:不正经的kimol君

刚接触Python的新手、小白,可以复制下面的链接去免费观看Python的基础入门教学视频

https://v.douyu.com/author/y6AZ4jn9jwKW

前言

想必小破站大家都很熟悉叭,里面充满了各种神奇的视频,其中的「弹幕」成为了许多人的快乐源泉。关于它的爬虫也有很多,但大部分都受限于弹幕池的数量,只能爬取到其中很少一部分的弹幕。

那么,有没有办法可以爬取到B站更多的弹幕呢?

一、弹幕抓取(有数量限制)

首先,我们需要找到B站视频弹幕的接口,通过浏览器的F12调试工具抓包可以发现,其接口为:

https://api.bilibili.com/x/v1/dm/list.so?oid={oid/cid}

其实,除了这个接口之外,还有另外一个接口同样是可以获取到弹幕的:

https://comment.bilibili.com/{oid/cid}.xml

其中「oid」「cid」是iB站给每个视频分配的一个id号,但是通常我们在浏览器地址看到的是「bvid」,因此需要做个转换:

这里相关的接口有很多,可以定义如下函数:

def get_cid(bvid):'''通过视频的bvid获得视频的cid输入:视频的bvid输出:视频的cid'''url = 'https://api.bilibili.com/x/player/pagelist?bvid=%s&jsonp=jsonp'%bvidres = requests.get(url)data = res.json()return data['data'][0]['cid']

有了「cid」之后,我们便可以通过刚才发现的弹幕接口爬取弹幕了,代码如下:

oid = get_cid(bvid) # 这里的cid和oid是一样的
url = 'https://api.bilibili.com/x/v1/dm/list.so?oid=%d'%oid
res = requests.get(url)
res.encoding = 'utf-8'
text = res.text

注意:这里需要指定res的编码方式为utf-8,否则会出现乱码现象。

我们得到的请求为一个xml文件,其格式大致如下:

因此,需要将其中的信息提取出来,「p」标签对应的字段分别为:

那么,利用正则可以它们都提前出来:

def parse_dm(text):'''解析视频弹幕输入:视频弹幕的原数据输出:弹幕的解析结果'''result = [] # 用于存储解析结果data = re.findall('<d p="(.*?)">(.*?)</d>',text)for d in data:item = {} # 每条弹幕数据dm = d[0].split(',') # 弹幕的相关详细,如出现时间,用户等item['出现时间'] = float(dm[0])item['模式'] = int(dm[1])item['字号'] = int(dm[2])item['颜色'] = int(dm[3])item['评论时间'] = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(int(dm[4])))item['弹幕池'] = int(dm[5])item['用户ID'] = dm[6] # 并非真实用户ID,而是CRC32检验后的十六进制结果item['rowID'] = dm[7] # 弹幕在数据库中的ID,用于“历史弹幕”功能item['弹幕内容'] = d[1]result.append(item)    return result

通过解析requests的请求,便能得到相应的弹幕:

dms = parse_dm(text) # 解析弹幕

但是,这里受到弹幕池的限制,每次只能抓取一小部分,当弹幕数量很多时,显然这个办法行不通。

那么,我们得另寻它路了~

二、弹幕抓取(无数量限制)

通过分析,我们可以找到另外一个接口,用于获取每天的弹幕历史数据:

https://api.bilibili.com/x/v2/dm/history?type=1&oid={oid/cid}&date=xx-xx

「date」为日期,通过遍历日期便可获得更多的弹幕。需要注意的是,这个接口需要登陆,因此在请求的时候必须得加入cookies,可以定义如下函数:

def get_history(bvid,date): '''获取视频历史弹幕输入:视频bvid,日期输出:视频某一日期开始的弹幕'''oid = get_cid(bvid)url = 'https://api.bilibili.com/x/v2/dm/history?type=1&oid=%d&date=%s'%(oid,date)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0','Accept': '*/*','Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2','Origin': 'https://www.bilibili.com','Connection': 'keep-alive','Referer': 'https://www.bilibili.com/video/BV1k54y1U79J','TE': 'Trailers'}# 此接口需要登陆,因此需要cookiescookies = {}res = requests.get(url,headers=headers,cookies=cookies)res.encoding = 'utf-8'text = res.textdms = parse_dm(text) # 解析弹幕return dms

想要获得更多的弹幕,遍历每一天的弹幕数据即可,但是这样存在两个问题:「效率太低」「数据重复」。因为,每次获取通常可以得到跨越几天的数据,所以我们无需每天都去访问,而是根据结果逐步往前推即可:

def get_dms(bvid):'''获取视频弹幕(此方法获取的弹幕数量更多)输入:视频的bvid输出:视频的弹幕'''print('视频解析中...')info = get_info(bvid)print('视频解析完成!')print('【视频标题】: %s\n【视频播放量】:%d\n【弹幕数量】:  %d\n【上传日期】:  %s'%(info[0],info[1],info[2],info[3]))dms = get_dm(bvid) # 存储弹幕if len(dms) >= info[2]: # 如果弹幕数量已抓满return dmselse:dms = []date = time.strftime('%Y-%m-%d',time.localtime(time.time())) # 从今天开始while True:dm = get_history(bvid,date)dms.extend(dm)print('"%s"弹幕爬取完成!(%d条)'%(date,len(dm)))if len(dm) == 0: # 如果为空breakend = dm[-1]['评论时间'].split()[0] # 取最后一条弹幕的日期if end == date: # 如果最后一条仍为当天,则往下推一天end = (datetime.datetime.strptime(end,'%Y-%m-%d')-datetime.timedelta(days=1)).strftime('%Y-%m-%d')if end == info[3]: # 如果已经到达上传那天breakelse:date = enddm = get_history(bvid,info[3]) # 避免忽略上传那天的部分数据dms.extend(dm)print('弹幕爬取完成!(共%d条)'%len(dms))print('数据去重中...')dms = del_repeat(dms,'rowID') # 按rowID给弹幕去重print('数据去重完成!(共%d条)'%len(dms))return dms

运行主函数:

if __name__ == '__main__':dms = get_dms('BV1HJ411L7DP')dms = pd.DataFrame(dms)dms.to_csv('一路向北.csv',index=False)

爬取过程如下:

可以看到,一共「11471条」弹幕,我们获取到了「11000条」,占比已经很高了,而且csv文件已经安静地躺在了我的电脑中,打开它:

至此,大功告成,舒坦了~~

受限于弹幕池的数量,没有办法可以爬取到B站更多的弹幕呢?相关推荐

  1. 协程池gevent实现糗事百科爬取

    标题 -协程池gevent实现糗事百科爬取 import gevent.monkey gevent.monkey.patch_all() from gevent.pool import Pool im ...

  2. python—简单数据抓取七(采取蘑菇API代理设置scrapy的代理IP池并利用redis形成队列依次使用,利用ip池访问网页并将scrapy爬取转移到items的数据存入到数据库)

    学习目标: Python学习二十七-简单数据抓取七 学习内容: 1.采取蘑菇API代理设置scrapy的代理IP池并利用redis形成队列依次使用 2.利用ip池访问网页并将scrapy爬取转移到it ...

  3. 利用python对b站某GPT-4解说视频的近万条弹幕进行爬取、数据挖掘、数据分析、弹幕数量预测及情绪分类

    目录 一.利用Python爬取弹幕 二.利用几行代码直接生成词云 三.将弹幕属性和内容放入mysql当中 四.分析弹幕在视频各节点的数量 1.分析视频各个片段出现的弹幕数量 2.分析视频各大章节出现的 ...

  4. Python爬取腾讯视频16978条弹幕,发现弹幕比剧还精彩

    东北民间流传着关于"皇围猎人"的神秘传说 他们世代生存于深山,为帝王守护兴安岭这片龙兴之地的气脉运转.传闻猎人除了精通狩猎之法,更知晓驱鬼通神之术. 在东北一处偏僻的山村里,悄然发 ...

  5. 清除string内容_python爬取哔哩哔哩网页弹幕内容,并将爬取的内容以五角星的形式显示出来...

    转载:03 爬虫实例-获取网页弹幕内容 思路: 向哔哩哔哩网站发送请求 请求成功后,解析爬取的弹幕内容保存到一个文件中 读取文件并分析弹幕内容中词组或文字出现的频率 将这些词组或文字组成五角星图形 组 ...

  6. python爬取去哪网数据_python最强的代理池,突破IP的封锁爬取海量数据(送项目源码)...

    一个强大到超乎你的想象的异步IP池项目--async-proxy-pool 随着大型网站反扒机制的增强,更改IP登陆已经成为一种最高效的方式,为此打造一款超强IP池项目,采用最新最快的Python技术 ...

  7. Python爬取《隐秘的角落》弹幕数据,实现简单可视化(附源码)

    工具使用 开发环境: win10.python3.6 开发工具: pycharm 相关模块 : requests,stylecloud 思路分析 1.爬虫获取数据 爱奇艺的弹幕数据是以 .z 形式的压 ...

  8. python爬取哔哩哔哩网页弹幕内容,并将爬取的内容以五角星的形式显示出来

    思路: 向哔哩哔哩网站发送请求 请求成功后,解析爬取的弹幕内容保存到一个文件中 读取文件并分析弹幕内容中词组或文字出现的频率 将这些词组或文字组成五角星图形 组成五角星图形后,以图片的形式输出 使用到 ...

  9. beautifulsoup爬取网页中的表格_python爬取哔哩哔哩网页弹幕内容,并将爬取的内容以五角星的形式显示出来...

    转载:03 爬虫实例-获取网页弹幕内容 思路: 向哔哩哔哩网站发送请求 请求成功后,解析爬取的弹幕内容保存到一个文件中 读取文件并分析弹幕内容中词组或文字出现的频率 将这些词组或文字组成五角星图形 组 ...

最新文章

  1. pygame学习和python巩固——字体显示
  2. [外文理解] DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构。
  3. 【MySQL】Java对SQL时间类型的操作(获得当前、昨天、前年。。时间)
  4. DataNode逻辑结构
  5. python的实例属性_python 实例属性和类属性
  6. Vista下将Area效果应用到整个窗体
  7. Android Studio 关联源码
  8. VS2005透过SourceOffSite访问VSS2005的设置方法
  9. 小米手机开启开发者模式以及INSTALL_FAILED_USER_RESTRICTED报错处理
  10. 最详细的IIS发布站点步骤
  11. 乌合之众-大众心理研究(六)
  12. 采样频率Hz 采样率KSPS或MSPS,两种单位的换算关系
  13. 5千字长文:KeePass完全入门指南(附已经配置好的版本)
  14. java获取pfx证书私钥_从PFX文件中读取私钥
  15. API Design for ios 译文
  16. 联想win10系统忘记开机密码解决方式
  17. Android动画特效第二弹——QQ聊天彩蛋蹦蹦哒
  18. php mysql 聊天室_聊天室phpmysql(二)_php
  19. 如何成功实施结对编程
  20. 【正点原子I.MX6U-MINI应用篇】1、编写第一个应用App程序helloworld

热门文章

  1. amd一键超频怎么用_AMD新版显卡驱动为“肾上腺素 2019”:支持一键超频,语音截屏...
  2. java中文乱码的原因及解决方法
  3. c语言段页式存储地址转换,页式存储和段页式存储的地址转换过程
  4. 艾默生质量流量计2700/1700调试说明
  5. 0*3038在c语言中的意义,电工学试题及答案3套(电工部分)
  6. 计算机网络 实验:配置VLAN
  7. (转)程序员不爱读书,但这很不明智
  8. Python---涂鸦跳跃
  9. ClearType 的原理:Windows 上文本的亚像素控制
  10. [转载]复旦女博士于娟——为啥是我得癌症? (转)