最近受人之托研究了下b站的数据爬取做个小工具,最后朋友说不需要了,本着开源共享的原则,将研究成果与大家分享一波,话不多说直接上干货

需求分析

给定up主uid和用户uid,爬取用户在该up主所有视频中发的所有弹幕

需求拆解

获取up主所有视频

打开b站,随便搜索一个up主,打开所有视频页面,f12看异步请求就一目了然了

接口地址:https://space.bilibili.com/ajax/member/getSubmitVideos?mid=up主的uid&pagesize=30&tid=0&page=1&keyword=&

直接通过GET请求访问,该接口限制pagesize为100,数目超过就会返回错误,但是该接口会返回一个总数与页数,所以我们首先请求一次,获取相关参数再分批次请求,获取到数据后对vlist进行json数据解析就可以,我们主要获取的是aid,也就是av号

获取视频所有弹幕

使用firefox浏览器打开视频,f12后搜索list.so请求会发现弹幕xml文件,同样也是GET请求

接口地址:https://api.bilibili.com/x/v1/dm/list.so?oid=112062851  http://comment.bilibili.com/{cid}..xml

但是在百度的过程中发现了一个直接读取xml文件的地址,更加方便

接口地址:http://comment.bilibili.com/{cid}.xml

这个cid就是弹幕xml的文件编号,通过分析异步请求,发现了返回这个cid的返回接口

接口地址:https://api.bilibili.com/x/player/pagelist?aid=视频av号&jsonp=jsonp

需要注意的是返回的是一个数组,这说明如果视频弹幕过多的话可能有多个xml文件,我们需要遍历获取

弹幕xml文件分析

文件格式内容如下所示

可以看到里面d标签的文字内容就是发送的弹幕,但是我们还需要对弹幕的发送者与我们给定的用户进行对比,所以需要对d标签的属性p进行分析,p属性使用逗号隔开的一系列数据,其中各个参数属性如下

<d p=”弹幕出现时间,模式,字体大小,颜色,发送时间戳,弹幕池,用户Hash,数据库ID”>123123</d>

我们只需要获取里面的第7个参数用户的唯一标识即可

难点分析

用户id转换

在弹幕xml文件中获取的用户标识是用户uid经过hash后的编码,所以我们需要进行转换后才能对比校验,经过使用在线hash网站中的一个个hash函数尝试比对,发现hash算法为crc32b,crc32是一个常见算法,用于文件校验,但是crc32b百度了一圈也搜索不到是个啥东西,无奈出国google了一下,crc32b只是将crc32算法加密后的结果转换成了16进制,下面提供c#实现的功能函数

        /// <summary>
/// CRC32校验算法
/// </summary>
protected static ulong[] Crc32Table;
//生成CRC32码表
public static void GetCRC32Table()
{
ulong Crc;
Crc32Table = new ulong[];
int i, j;
for (i = ; i < ; i++)
{
Crc = (ulong)i;
for (j = ; j > ; j--)
{
if ((Crc & ) == )
Crc = (Crc >> ) ^ 0xEDB88320;
else
Crc >>= ;
}
Crc32Table[i] = Crc;
}
}
//获取字符串的CRC32校验值
public static ulong GetCRC32Str(string sInputString)
{
//生成码表
GetCRC32Table();
byte[] buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(sInputString); ulong value = 0xffffffff;
int len = buffer.Length;
for (int i = ; i < len; i++)
{
value = (value >> ) ^ Crc32Table[(value & 0xFF) ^ buffer[i]];
}
return value ^ 0xffffffff;
} public static string GetCRC32bStr(string sInputString)
{
return GetCRC32Str(sInputString).ToString("x");
}

通过代码GET请求保存xml文件

在保存xml文件的过程中发现输出流转为文字永远是乱码,经过查看请求网页中header中的值,发现返回的xml数据流是压缩格式的

所以我们对GET请求的方法进行了一些设置,首先Accept-Encoding需要与真正的访问请求保持一致,然后设置自动解压,下面提供c#示例

        public static String HttpGet_BiliBiliXmlFile(string Url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate, br";
request.Headers[HttpRequestHeader.AcceptLanguage] = "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";
//自动解压
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close(); return retString;
}

功能到这里就全部分析完毕了,最后打个广告,自己写的ASP.NET MVC快速开发框架,希望支持一波

地址:https://gitee.com/grassprogramming/FastExecutor

bilibili弹幕爬取与比对分析的更多相关文章

  1. bilibili弹幕爬取

    随便进入一个视频页面,打开开发者工具,清空network空间,进入XHR,刷新抓包. 双击查看弹幕

  2. Java爬虫——B站弹幕爬取

    如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号,cid=14295428 弹幕存放位置为  h ...

  3. python预课05 爬虫初步学习+jieba分词+词云库+哔哩哔哩弹幕爬取示例(数据分析pandas)

    结巴分词 import jieba """ pip install jieba 1.精确模式 2.全模式 3.搜索引擎模式 """ txt ...

  4. B站弹幕爬取

    B站弹幕爬取 单个视频弹幕的爬取 ​ B站弹幕都是以xml文件的形式存在的,而xml文件的请求地址是如下形式: http://comment.bilibili.com/233182992.xml ​ ...

  5. [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】

    [python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...

  6. B站弹幕爬取 / jieba分词 - 全站第一的视频弹幕都在说什么?

    前言 本次爬取的视频av号为75993929(11月21的b站榜首),讲的是关于动漫革命机,这是一部超魔幻现实主义动漫(滑稽),有兴趣的可以亲身去感受一下这部魔幻大作. 准备工作 B站弹幕的爬取的接口 ...

  7. 使用Python爬取、清洗并分析前程无忧的大数据职位

    爬取前程无忧的数据(大数据职位) # -*- coding: utf-8 -*- """ Created on Wed Nov 1 14:47:27 2019 @auth ...

  8. 04爬取拉勾网Python岗位分析报告

    # 导入需要的包import requestsimport time,randomfrom openpyxl import Workbookimport pymysql.cursors#@ 连接数据库 ...

  9. b站弹幕的爬取以及词云的简单使用

    一.B站弹幕的爬取 1.分析发现,其弹幕都是通过list.so?=cid这个文件加载出来的,所以我们找到这个文件的请求头的请求url, 2. 打开url就能看到所有的评论 3. 上代码,解析 #!/u ...

随机推荐

  1. JAVA通过URL链接获取视频文件信息(无需下载文件)

    最近项目碰到一个大坑:APP上需要在获取视频列表时就获取视频的时长,但早期上传的时候数据库都没有保存这个数据,所以前段时间添加一个时长字段,在上传时手动输入视频时长,但是之前库中有上万条数据没这个信息 ...

  2. C语言入门6-选择结构--f语句-switch

    一.     什么是选择结构? 选择结构,也称为分支结构!! 选择结构就是根据    给定的判定条件,判断结果, 并根据  判断的结果   来控制程序的流程 (流程图中,   菱形框 是有来判断的 , ...

  3. php_review_day1

    php中的小知识点(小白笔记整理):-----------------------------------------------------读取本地文件内的数据: file_get_contents ...

  4. hdu6395 Sequence(分段矩阵快速幂)

    Sequence 题目传送门 解题思路 可以比较容易的推出矩阵方程,但是由于p/i向下取整的值在变,所以要根据p/i的变化将矩阵分段快速幂.p/i一共有sqrt(p)种结果,所以最多可以分为sqrt( ...

  5. 七、SQL 高级语法一

    Case when Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE ...

  6. k8s1.9.0安装--基础集群部署

    二.基础集群部署 - kubernetes-simple 1. 部署ETCD(主节点) 1.1 简介 kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运 ...

  7. java练习---12

    public class L1106 { public static void main(String[] args) { // TODO Auto-generated method stub Tes ...

  8. PHP与ECMAScript_4_常用数学相关函数

    PHP ECMAScript 向上取整 ceil($number) Math.ceil( number ) 向下取整 floor($number) Math.floor( number ) 绝对值 a ...

  9. Java集合系列(三):HashSet、LinkedHashSet、TreeSet的使用方法及区别

    本篇博客主要讲解Set接口的三个实现类HashSet.LinkedHashSet.TreeSet的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 1. HashSe ...

  10. CSS开启硬件加速来提高网站性能

    原文永久链接 CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行. 那我们怎样才可以切换到GPU模式呢, ...