由于个人经常在空闲时间在b站看些小视频欢乐一下,这次就想到了爬取b站视频的弹幕。

这里就以番剧《我的妹妹不可能那么可爱》第一季为例,抓取这一番剧每一话对应的弹幕。

1. 分析页面

这部番剧的第一季就有15话,所以我们首先需要找到每一话对应的url,然后再去爬取每一话的弹幕。

1.1 找到每一话对应的url

打开番剧的首页,可以看到每一话的信息就展示在图中位置。

照惯例,我们首先对当前请求网页返回的数据进行查看,发现请求该url返回的只有一点简略的番剧信息,根本没有每一话的信息。

但是我们在浏览器中又确实能够看到每一话的信息,所以推测,这些信息应该是通过AJAX异步加载方式获取到的。接下来我们就查看“XHR”标签内的网络请求。

当前这一网页中XHR标签内的网络请求并不多,最简单的方法就是每一个网络请求都查看一番。但是我们可以发现,这里的每个网络请求看起来都有一定的命名规则,像info/nav/review/recommend这些,似乎都很容易理解。我们发现其中有一个请求命名为'section?season_id=...',那就先看它了。

(对于异步加载的网页,相比于随机命名,规范命名有助于程序员进行高效开发和维护。所以我们从网络请求的命名入手,一定程度上能够提高找到对应数据来源的速度和准确度

点击Preview一看,这个网络请求返回的是一个json文件,而内容恰好能够对应到这个番剧每一话的信息,打开这个请求的网页也确实发现了每一话的名称、url等信息。

那么我们就已经找到了这部番剧每一话的播放地址url。

1.2 找到当前视频对应的弹幕来源

以第一话为例,我们打开第一话的url。毫无悬念的是,请求当前url的返回信息里并没有弹幕信息。

所以我们继续查看"XHR"标签。这时候,问题来了,"XHR"标签内少说也有好几十个网络请求,它们的命名好像也不是很清晰,那我们岂不是要把每个网络请求都查看一遍才能找到弹幕对应的来源。

这里要介绍一个小技巧:不管当前页面有多少个网络请求,不管这些数量繁多的网络请求是为了反爬虫还是为了页面复杂功能的实现,我们只需要记住一个宗旨:程序员是不会舍得把资源过多浪费在无关紧要的地方的

所以这里我们将各个请求按Size进行倒叙排列,从上往下尝试几次就可以发现,弹幕是来源于这个url的:https://api.bilibili.com/x/v1/dm/list.so?oid=17737533

而通过查看这个网络请求的headers信息可以发现,弹幕是通过请求接口获取的,请求参数是17737533,它是这个视频的编号。

但是,当前视频的url里面明明是ep65128,这两个参数是很明显对不上的。

既然加载弹幕的请求是访问主url后才会继续的,那么通过访问主url就肯定能拿到对应的视频编号,然后加载弹幕的请求才可以通过这个编号进行加载弹幕。

那我们接下来就分析当前页面的源代码,搜索17737533,它属于cid字段。现在我们就找到了每个视频请求弹幕时它所对应的编号。

(回头查看时发现,cid这个参数在1.1中通过'section?season_id=...'也可以获取到)

1.3 抓取流程

1)通过番剧首页获取每一话对应的url和cid编号

'根据1.2,其实cid参数可以从两个地方获取到。这里我们就用简单的方法,直接在'section?season_id=...'中获取。

2)将cid编号放入“https://api.bilibili.com/x/v1/dm/list.so?oid=”后,构建url,保存每一话的弹幕信息。

2. 代码实现

import requests
from bs4 import BeautifulSoup

header = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}

# 通过番剧首页获取每一话对应的cid编号,存入section_sid
def get_cid(index_url):
    try:
        index_response = requests.get(index_url, headers=header)
        index_json = index_response.json() # 返回一个json文件
        section_cid = []

        for each in index_json['result']['main_section']['episodes']:
            section_cid.append({
                'title': each['long_title'],
                'cid': each['cid'],
                'id': each['id'],
                'url': each['share_url']
            })
    except:
        print('index pass')

    return section_cid

# 通过cid编号获取这一话的所有弹幕信息
def get_danmu(cid):
    try:
        danmu_response = requests.get('https://api.bilibili.com/x/v1/dm/list.so?oid='+str(cid), headers=header)
        danmu_soup = BeautifulSoup(danmu_response.content, 'lxml')

        for each in danmu_soup.findAll('d'):
            danmu_info = each['p'].split(",")
            danmu_detail.append({
                'cid': cid, # 弹幕对应视频cid
                'danmu': each.get_text(), # 弹幕内容
                'time': danmu_info[0], # 弹幕出现时间(秒)
                'type': danmu_info[1], # 弹幕模式
                'size': danmu_info[2], # 字号
                'color': danmu_info[3], # 颜色
                'timestamp': danmu_info[4], # 时间戳
                'pool': danmu_info[5], # 弹幕池
                'sender': danmu_info[6], # 发送者ID
                'row': danmu_info[7] # 弹幕rowID,用于“历史弹幕”功能
            })
        print(cid, 'done')
    except:
        print(cid, 'pass')

danmu_detail = [] # 所有弹幕存入danmu_detail
section_cid = get_cid(index_url)
[get_danmu(each_section['cid']) for each_section in section_cid]

爬虫练习四:爬取b站番剧字幕的更多相关文章

  1. Python 网络爬虫实战:爬取 B站《全职高手》20万条评论数据

    本周我们的目标是:B站(哔哩哔哩弹幕网 https://www.bilibili.com )视频评论数据. 我们都知道,B站有很多号称“镇站之宝”的视频,拥有着数量极其恐怖的评论和弹幕.所以这次我们的 ...

  2. Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取

    很多网页的信息都是通过异步加载的,本文就举例讨论下此类网页的抓取. <工作细胞>最近比较火,bilibili 上目前的短评已经有17000多条. 先看分析下页面 右边 li 标签中的就是短 ...

  3. python 爬虫入门案例----爬取某站上海租房图片

    前言 对于一个net开发这爬虫真真的以前没有写过.这段时间开始学习python爬虫,今天周末无聊写了一段代码爬取上海租房图片,其实很简短就是利用爬虫的第三方库Requests与BeautifulSou ...

  4. <爬虫>用正则爬取B站首页图片

    import re import requests headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Apple ...

  5. Python爬虫实例:爬取猫眼电影——破解字体反爬

    字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...

  6. Python爬虫实例:爬取豆瓣Top250

    入门第一个爬虫一般都是爬这个,实在是太简单.用了 requests 和 bs4 库. 1.检查网页元素,提取所需要的信息并保存.这个用 bs4 就可以,前面的文章中已经有详细的用法阐述. 2.找到下一 ...

  7. scrapy进阶(CrawlSpider爬虫__爬取整站小说)

    # -*- coding: utf-8 -*- import scrapy,re from scrapy.linkextractors import LinkExtractor from scrapy ...

  8. 爬虫---爬取b站小视频

    前面通过python爬虫爬取过图片,文字,今天我们一起爬取下b站的小视频,其实呢,测试过程中需要用到视频文件,找了几个网站下载,都需要会员什么的,直接写一篇爬虫爬取视频~~~ 分析b站小视频 1.进入 ...

  9. 爬虫之爬取B站视频及破解知乎登录方法(进阶)

    今日内容概要 爬虫思路之破解知乎登录 爬虫思路之破解红薯网小说 爬取b站视频 Xpath选择器 MongoDB数据库 爬取b站视频 """ 爬取大的视频网站资源的时候,一 ...

随机推荐

  1. 自定义收索View

    1 .h文件 @interface SearchNavView : UIView @property (nonatomic, copy) void(^cancleBtnBlock)(void); @p ...

  2. Codeforces Round #497 (Div. 2) C. Reorder the Array

    Bryce1010模板 http://codeforces.com/contest/1008/problems #include <bits/stdc++.h> using namespa ...

  3. 理解C#系列 / 前言

    前言 索引 写什么? 为什么写? 怎么写? 写什么? 写和C#编程相关的知识. 写知识的定义,附加对知识的理解. 写知识的作用,使用的场景,使用的条件. 写知识的本质,技术的结构,工作的原理. 写知识 ...

  4. DockerSwarm 集群环境搭建

    一.简介 1. 什么是docker swarm? Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 ...

  5. scrapy安装遇到的Twisted问题

    贴上大佬的博客地址:https://blog.csdn.net/a19990412/article/details/78849881 电脑一直在爆下面这一堆的信息 Command”c:\users\l ...

  6. this/super/static/final/匿名对象/继承/抽象类/访问权限修饰符

    1.this关键字的作用     1)调用本类中的属性;     2)调用本类中的构造方法;且只能放首行,且必须留一个构造方法作为出口,即不能递归调用     3)表示当前对象; 2.匿名对象     ...

  7. PaaS基础学习(1)

    PaaS基础学习(1) PaaS学习笔记目录 PaaS基础学习(1) 在PaaS上开发Web.移动应用(2) PaaS优点与限制(3) 1. 基础单元,一个基础单元就是所研究实体的最小的不可分割的单元 ...

  8. UVM之uvm_phase

    UVM中的phase机制很有意思,它能让UVM启动之后,自动执行所有的流程.UVM 的user guide 中对uvm_phase的定义如下: This base class defines ever ...

  9. COGS 1144. [尼伯龙根之歌] 精灵魔法

    ★   输入文件:alfheim.in   输出文件:alfheim.out   简单对比时间限制:1 s   内存限制:128 MB [题目背景] 『谜题在丛林中散发芳香绿叶上露珠跳跃着歌唱火焰在隐 ...

  10. 洛谷 1164 小A点菜

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...