1课题背景
目前视频行业可以分为爱优腾为代表的长视频赛道,快手抖音为代表的短视频赛道,以及B站,B站的视频内容非常的丰富,由于奇特的社区属性和基于UP主们的原创内容,塑造了一个通过内容交流给用户带来愉悦感的社区型平台。
本项目基于Python+flask+pyecharts实现了对哔哩哔哩排名榜大数据的可视化剖析。
2实现疗效
3数据获取
本次数据来始于哔哩哔哩排名榜,服务器后台中每5min对排名榜数据爬取,通过jQueryAjax+flask实时更新到网页上。
python爬虫简介
网路爬虫是一种根据一定的规则,手动地抓取万维网信息的程序或则脚本。爬虫对某一站点访问,假如可以访问就下载其中的网页内容,但是通过爬虫解析模块解析得到的网页链接,把那些链接作为以后的抓取目标,而且在整个过程中完全不依赖用户,手动运行。若不能访问则依照爬虫预先设定的策略进行下一个URL的访问。在整个过程中爬虫会手动进行异步处理数据恳求,返回网页的抓取数据。在整个的爬虫运行之前,用户都可以自定义的添加代理,伪装恳求头便于更好地获取网页数据。爬虫流程图如下:
爬虫相关代码
import requests
from bs4 import BeautifulSoup
import xlwt
import time
import urllib3
import requests
import json
# 爬取B站热榜排行
# 格式解析,[0-当前排名,1-视频标题,2-播放数目,3-弹幕数量,4-综合得分,5-作者,6-视频地址,7-时长,8-评论数,9-收藏数,10-投币数,11-分享数,12-点赞数]
# 格式化
def whitespace(st):
st = st.replace('\n', '')
st = st.strip()
st = st.replace(' ', '')
return st
# 详情页
def info_Page(bv):
url = 'http://api.bilibili.com/x/web-interface/view?bvid=' + bv
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36"
} # 请求头,模拟浏览器的运行
urllib3.disable_warnings() # 从urllib3中消除警告
response = requests.get(url, headers=headers)
content = json.loads(response.text)
# 很迷,获取到的是str字符串 需要解析成json数据
statue_code = content.get('code')# print(statue_code)
if statue_code == 0:
duration = content['data']['duration'] # 时长
reply = content['data']['stat']['reply'] # 评论
favorite = content['data']['stat']['favorite'] # 收藏
coin = content['data']['stat']['coin'] # 投币
share = content['data']['stat']['share'] # 分享
like = content['data']['stat']['like'] # 点赞
return duration,reply,favorite,coin,share,like
while(True):
url = 'https://www.bilibili.com/v/popular/rank/all'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36'}
rank = requests.get(url, headers=headers) # 请求页面
soup = BeautifulSoup(rank.text, 'lxml')
all_rank = soup.find_all('li', class_='rank-item')
num = 0
lst=[]
for i in all_rank:
record = []
rank_num = i.find('div', class_='num').text # 获取排名
info = i.find('div', class_='info') # 筛选出视频详细信息的标签
href = info.find('a', class_='title').attrs['href'] # 获取链接
title = info.find('a', class_='title').text # 获取标题
play_num = info.find('i', class_='b-icon play').parent.text # 获取播放量
view_num = info.find('i', class_='b-icon view').parent.text # 获取弹幕数
author = info.find('i', class_='b-icon author').parent.text # 获取作者名
scores = info.find('div', class_='pts').find('div').text # 获取综合得分
# 播放,弹幕,作者
play_num = whitespace(play_num)
view_num = whitespace(view_num)
author = whitespace(author)
bv = href.split('/')[-1]
duration,reply,favorite, coin,share,like = info_Page(bv)
record.append(rank_num)
record.append(title)
record.append(play_num)
record.append(view_num)
record.append(scores)
record.append(author)
record.append(href)
record.append(duration)
record.append(reply)
record.append(favorite)
record.append(coin)
record.append(share)
record.append(like)
num += 1
lst.append(record)
# 爬取的数据存入文件,避免多次爬取且提高响应速度
with open('./bilibili.txt', 'w',encoding='utf-8') as f:
for line in lst:
for i in line:
f.write(str(i)+',')
f.write('\n')
time.sleep(300)
#print(lst[0])
4数据可视化
可视化呈现方案
综合得分估算指标:哔哩哔哩综合得分快手热门视频排行榜,是视频是否能排上排名榜的根据,若能晓得其规则,对于视频内容的倾向,up主是否须要恳求“一键三连”快手热门视频排行榜,听众们需不须要小气手中的币,是有很大的价值的,所以在此首先进行综合得分估算指标的剖析及其可视化,此处采取蓝色关联度剖析(GreyRelationAnalysis,GRA)来进行数据的处理。
首先是要确定子母序列,母是结果,子是影响因子,这么,毫无疑惑,综合得分就是母,其他均为影响因子。将其分别存入mom_以及son_中,代码如下:
with open('./bilibili.txt', 'r+',encoding='utf-8') as f1:
lst2=[]
for line in f1.readlines():
lst2.append(line.split(','))
mom_ = [int(i[4]) for i in lst2[0:50:]]
view = []
reply = []
favorite = []
coin = []
share = []
like = []
for i in lst2[0:50]:
view.append(float(i[2].strip("万"))*10000)
reply.append(int(i[8]))
favorite.append(int(i[9]))
coin.append(int(i[10]))
share.append(int(i[11]))
like.append(int(i[12]))
son_ = [view,reply,favorite,coin,share,like]
之后要对数据进行预处理,由于我们的这种要素是不同质的东西的指标,因而可能会有的数字很大有的数字很小,而且这并不是因为它们内禀的性质决定的,而只是因为量纲不同造成的,因而我们须要对它们进行无量纲化。这个操作通常在数据处理领域称作归一化(normalization),也就是降低数据的绝对数值的差别,将它们统一到近似的范围内,之后重点关注其变化和趋势。按公式归一化即可。
mom_ = np.array(mom_)
son_ = np.array(son_)
son_ = son_.T / son_.mean(axis=1)
mom_ = mom_/mom_.mean()
for i in range(son_.shape[1]):
son_[:,i] = abs(son_[:,i]-mom_.T)
Mmin = son_.min()
Mmax = son_.max()
cors = (Mmin + 0.5*Mmax)/(son_+0.5*Mmax)
Mmean = cors.mean(axis = 0)