bilibili(1)-爬取视频信息进行数据分析

B站作为近两年,二次元流行文化的执大旗者,其网站上视频信息已超过2000W(截止2018-04-10)。到目前为止,B站更多的成为了多元化文化的载体,其年轻活力的氛围,在各个视频网站或者论坛都不曾能看到的。故产生兴趣爬取视频信息,看是否可以有所挖掘。

感谢@雄哥和@逊哥的帮助才得以完成这篇文章,不然,还不知怎么应对IP限制。
项目地址:https://github.com/UranusLee/bilibili_spider

爬虫爬取数据

1.爬虫

通过chrome可以看出来B站视频统计信息是通过js加载,打开开发者工具可以到stat?aid=31的json文件。


再分析json文件的加载方式,基本可以得到所需要的headers参数。



因为之前一直都在爬取豆瓣、知乎、拉勾这些有特殊headers的网站,所以,为了省事,还是全部headers都加上。

编写代码
import requests
import time
import pymysql
import random
from multiprocessing import Pool

#通过pymysql链接mysql
conn = pymysql.connect(host = '127.0.0.1' , port = 3306 , user = 'root' , passwd = '921522' , db = 'practice')
cur = conn.cursor()
result = []
video_list = []

#加载User_Agent函数
def LoadUserAgent(uafile):
    uas = []
    with open(uafile,'rb') as uaf:
        for ua in uaf.readlines():
            if ua:
                uas.append(ua.strip()[1:-1])
    random.shuffle(uas)
    return uas

#加载user_agents.txt文件
uas = LoadUserAgent("user_agents.txt")

def getHtmlInfo(url):
    #随机选择user_agent
    ua = random.choice(uas)
    #加载headers
    headers = {
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
        'Connection': 'keep-alive',
        'Host': 'api.bilibili.com',
        'Origin': 'https://www.bilibili.com',
        # 'Referer': 'https://www.bilibili.com/video/' + str(i) + '?spm_id_from=333.338.recommend_report.3',
        'User-Agent': ua
    }
    # 通过requests.get来请求数据,再通过json()解析
    response = requests.get(url, headers=headers, timeout=6).json()
    try:
        data = response['data']
        video = (
            data['aid'], data['view'], data['danmaku'],
            data['reply'], data['favorite'], data['coin'], data['share'])
        video_list.append(video)
        print(video_list)
        save_db()
        # time.sleep(0.4)
    except:
        print('-----')


# 将数据保存至mysql
def save_db():
    global video_list, cur, conn
    sql = "insert into bili_video values(%s, %s, %s, %s, %s, %s, %s);"
    for row in video_list:
        try:
            # print(row)
            cur.execute(sql, row)
        except:
            conn.rollback()
    conn.commit()
    video_list = []

if __name__ == '__main__':
    for i in range(10, 2000):
        pool = Pool(10)
        begin = (i-1)*10000
        urls = ['https://api.bilibili.com/x/web-interface/archive/stat?aid={}'.format(j) for j in range(begin, begin+10000)]
        try:
            pool.map(getHtmlInfo, urls)
        except:
            print("错误")
            pool.close()
            pool.join()
            time.sleep(0.2)
            pool = Pool(10)
            pool.map(getHtmlInfo, urls)

    conn.close()

进行爬取的时候,发生了一点问题,通过不断测试,基本可以断定B站有IP访问限制,基本上是1分钟150次以下不会封IP,封闭IP一次为5分钟,所以考虑用代理IP,拿着买好的稳定的IP,刻不容缓的加入进来。

#加载代理IP函数
def LoadProxies(ipfile):
    ips = []
    with open(ipfile,'r') as ipf:
        for ip in ipf.readlines():
            if ip:
                isf.append(ua.strip())
    #随机打乱列表
    random.shuffle(ips)
    return ips

#加载proxies.txt文件
ips = LoadProxies("proxies.txt")

def getHtmlInfo(url):
    #随机选择user_agent
    ua = random.choice(uas)
    ip = random.choice(ips)
    #加载headers
    headers = {
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7',
        'Connection': 'keep-alive',
        'Host': 'api.bilibili.com',
        'Origin': 'https://www.bilibili.com',
        # 'Referer': 'https://www.bilibili.com/video/' + str(i) + '?spm_id_from=333.338.recommend_report.3',
        'User-Agent': ua
    }
    # 通过requests.get来请求数据,再通过json()解析
    response = requests.get(url, headers=headers, timeout=6,proxies={'https':'https://'+ip}).json()
    try:
        data = response['data']
        video = (
            data['aid'], data['view'], data['danmaku'],
            data['reply'], data['favorite'], data['coin'], data['share'])
        video_list.append(video)
        print(video_list)
        save_db()
        # time.sleep(0.4)
    except:
        print('-----')

总共爬取下来710多W条数据,用了三四天的时间,期间网络断掉,或者IP地址停用,一直耽搁,之所以不准备继续下去是因为数据还准备做一个B站每年数据分析,所以选用了aid=11883351这条数据作为截止可以比较好的对应上每年7月初的一个数据对比分析

2.读取数据
  import pandas as pd
  import numpy as np
  import matplotlib.pyplot as plt
  %matplotlib inline

  filename = 'bili_video.csv'
  data = pd.read_csv(filename)

发现有播放数为-1的值,总共占数据总量的2%,故而删除。

  data = data.drop(data[data.view == -1].index,axis = 0)
3.统计分析
  data.describe()

可以看出基本上播放量,弹幕,评论回复,收藏,硬币,分享基本就是长尾数据,有大量的小数值的数据,但是整体的平均值受极值的影响较大。相比较而言view播放量更加有研究性。

4.分析报告

1.播放量占比分析



总共分为<500,500-1000,1000-5000,5000-20000,>20000。
播放量整体还是大量的淹没视频,播放量小于500的达到了整体视频的48.8%,而播放量20000以上的只占到5.4%,按照“二八原则”,视频达到3338以上的播放量即达到B站视频实际效用的界限。

2.分年份分析B站视频增长速度


以每年7月份为周期分析

通过aid可以查到所有爬下的数据所属的时间,再按照概率分析大概的时间就可以得出每一年7月份的视频量。

整体的视频数量增长速度实际上是大致按照每年翻倍的速度来增长,整体增长曲线抛开10-11年,整体增长平和。

2010-2011年之间,必定是发生了事才会导致视频量突增,才会导致视频总量增长率超过800%。通过查询,基本确实如之前所假设一样,10年因为Ac fun(A站)确实发生了严重的几次弹幕冲突,A站关闭了弹幕系统,加上很多人打出“ACG滚出ac”的标语,大量的A站up主转移至B站,开始了B站的逆袭。

14年一年视频增长率唯一一次跌至94%,是因为14年动画版权问题,禁止了私自上传动画,视频量比预期下跌了大概8W左右。今年更加夸张的是2018年还没有到07月份,视频总量已经达到2200W左右。

3.参与率分析用户活跃度


弹幕成本是最低的,大概平均27.8人次观看,就会出现一次弹幕(包括非会员的观看次数,但是无法发弹幕,提高了弹幕成本),分享成本不仅仅是会员,非会员没有登陆也可以分享,这确实42.58人次的成本仅仅高于弹幕成本,说明B站整体视频风格更加多元化。121.58的投币成本受限于B站的投币系统,B币少,并且获得有难度,导致投币成本远高于其他几项。

4.投币分析

B站投币有“不牛不投,不服不投”的潜性规则,往往一个视频的投币量可以反应视频的质量和B站的流行趋势。
排名第一的是 【哔哩哔哩2017拜年祭】,94.1W投币
排名第二的是 【古筝】千本樱——你可见过如此凶残的练习曲,79.6W投币
排名第三的是【哔哩哔哩2016拜年祭】,77.2W投币
然后是敖厂长的两连击
【敖厂长】让你耳朵怀孕的FC游戏,74.6W投币
【敖厂长】打脸!魂斗罗水下八关存在,73.0W投币

其实可以看出前三名中,两次拜年祭以及用户群体的自发投币,整个拜年祭已经成为B站文化的一部分,是每年最核心的一部分。当然也不缺乏敖厂长这种良心up主,每一次对于过往游戏的解疑和介绍,还有那无所不能的哥们,宅男但不失真心,牛逼但非常人亲。

文化的多元化才是整个B站撑起一片天的本质原因,我曾经在B站中过《极乐净土》的毒,看过外国人在中国成了网红,听过古筝弹奏魂斗罗、弹奏日本电音。这是一个大熔炉,每个人都可以找到自己喜欢的东西,我突然想起了广告模块的一个高分视频,弹幕量只有300,但是播放量有2000多万次,我不知道是B站运营人员清空了一部分的弹幕和评论,但是一个广告在B站,在这个无数个平时看都不看广告的年轻人,能够看上2000多万次,几乎人均一次。我才觉得我真正的知道。

这个时代的年轻人是最沉得住气的,心里再急,也不停的想活出自己想要的样子,背着装着自己的背包、还不停的说找不到自己。

----------------------------------------------------分割线-------------------------------------------
数据分析的部分有点意犹未尽,今天实在是困了,今天稍晚或者明天会继续对于B站各个模块继续进行深挖,包括弹幕的语义分析、通过弹幕揣摩剧情、哪种视频可以火、up主的影响力、视频质量建模等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容