bilibili弹幕爬取与比对分析
最近受人之托研究了下b站的数据爬取做个小工具,最后朋友说不需要了,本着开源共享的原则,将研究成果与大家分享一波,话不多说直接上干货
需求分析
给定up主uid和用户uid,爬取用户在该up主所有视频中发的所有弹幕
需求拆解
获取up主所有视频
打开b站,随便搜索一个up主,打开所有视频页面,f12看异步请求就一目了然了
直接通过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弹幕爬取与比对分析的更多相关文章
- bilibili弹幕爬取
随便进入一个视频页面,打开开发者工具,清空network空间,进入XHR,刷新抓包. 双击查看弹幕
- Java爬虫——B站弹幕爬取
如何通过B站视频AV号找到弹幕对应的xml文件号 首先爬取视频网页,将对应视频网页源码获得 就可以找到该视频的av号aid=8678034 还有弹幕序号,cid=14295428 弹幕存放位置为 h ...
- python预课05 爬虫初步学习+jieba分词+词云库+哔哩哔哩弹幕爬取示例(数据分析pandas)
结巴分词 import jieba """ pip install jieba 1.精确模式 2.全模式 3.搜索引擎模式 """ txt ...
- B站弹幕爬取
B站弹幕爬取 单个视频弹幕的爬取 B站弹幕都是以xml文件的形式存在的,而xml文件的请求地址是如下形式: http://comment.bilibili.com/233182992.xml ...
- [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】
[python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...
- B站弹幕爬取 / jieba分词 - 全站第一的视频弹幕都在说什么?
前言 本次爬取的视频av号为75993929(11月21的b站榜首),讲的是关于动漫革命机,这是一部超魔幻现实主义动漫(滑稽),有兴趣的可以亲身去感受一下这部魔幻大作. 准备工作 B站弹幕的爬取的接口 ...
- 使用Python爬取、清洗并分析前程无忧的大数据职位
爬取前程无忧的数据(大数据职位) # -*- coding: utf-8 -*- """ Created on Wed Nov 1 14:47:27 2019 @auth ...
- 04爬取拉勾网Python岗位分析报告
# 导入需要的包import requestsimport time,randomfrom openpyxl import Workbookimport pymysql.cursors#@ 连接数据库 ...
- b站弹幕的爬取以及词云的简单使用
一.B站弹幕的爬取 1.分析发现,其弹幕都是通过list.so?=cid这个文件加载出来的,所以我们找到这个文件的请求头的请求url, 2. 打开url就能看到所有的评论 3. 上代码,解析 #!/u ...
随机推荐
- JAVA通过URL链接获取视频文件信息(无需下载文件)
最近项目碰到一个大坑:APP上需要在获取视频列表时就获取视频的时长,但早期上传的时候数据库都没有保存这个数据,所以前段时间添加一个时长字段,在上传时手动输入视频时长,但是之前库中有上万条数据没这个信息 ...
- C语言入门6-选择结构--f语句-switch
一. 什么是选择结构? 选择结构,也称为分支结构!! 选择结构就是根据 给定的判定条件,判断结果, 并根据 判断的结果 来控制程序的流程 (流程图中, 菱形框 是有来判断的 , ...
- php_review_day1
php中的小知识点(小白笔记整理):-----------------------------------------------------读取本地文件内的数据: file_get_contents ...
- hdu6395 Sequence(分段矩阵快速幂)
Sequence 题目传送门 解题思路 可以比较容易的推出矩阵方程,但是由于p/i向下取整的值在变,所以要根据p/i的变化将矩阵分段快速幂.p/i一共有sqrt(p)种结果,所以最多可以分为sqrt( ...
- 七、SQL 高级语法一
Case when Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE ...
- k8s1.9.0安装--基础集群部署
二.基础集群部署 - kubernetes-simple 1. 部署ETCD(主节点) 1.1 简介 kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运 ...
- java练习---12
public class L1106 { public static void main(String[] args) { // TODO Auto-generated method stub Tes ...
- PHP与ECMAScript_4_常用数学相关函数
PHP ECMAScript 向上取整 ceil($number) Math.ceil( number ) 向下取整 floor($number) Math.floor( number ) 绝对值 a ...
- Java集合系列(三):HashSet、LinkedHashSet、TreeSet的使用方法及区别
本篇博客主要讲解Set接口的三个实现类HashSet.LinkedHashSet.TreeSet的使用方法以及三者之间的区别. 注意:本文中代码使用的JDK版本为1.8.0_191 1. HashSe ...
- CSS开启硬件加速来提高网站性能
原文永久链接 CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行. 那我们怎样才可以切换到GPU模式呢, ...