一、选题的背景
1.背景:哔哩哔哩(www.bilibili.com,英文名称:bilibili,简称B站)现为中国年轻世代高度聚集的文化社区和视频平台,该网站于2009年6月26日创建。
B站早期是一个ACG(动画、漫画、游戏)内容创作与分享的视频网站。经过十年多的发展,围绕用户、创作者和内容,构建了一个源源不断产生优质内容的生态系统,B站已经涵盖7000多个兴趣圈层的多元文化社区。
哔哩哔哩作为目前国内最大的动画作品平台,已上线了3000多部来自日本、美国以及国内的动画作品,具有大量的播放、点赞、弹幕、评分等数据可供分析。
2.目的:B站近几年的不断增长,涌现出的头部UP主越来越多。作为抢占Z世代的内容营销主阵地,品牌方对B站也愈发重视。
二、主题式网络爬虫设计方案
1.主题式网络爬虫名称
【Python爬虫课程设计】bilibili UP主数据分析——绘制数据柱状图和词云
2.主题式网络爬虫爬取的内容与数据特征分析
爬取相关up数据,包含UP主号,投稿视频数,投币数,弹幕数,最高点赞数,播放数,涨粉数新榜指数。并通过数据可视化表现出来。
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
实现思路: 1. 数据采集。具体来源于
https://www.newrank.cn/nr/bili/rank/complexMainRank
2. 进行数据的清洗,对需要的数据进行定位和提取,并进行存取。
3. 传入数据,绘制词云和进一步数据可视化。
三、主题页面的结构特征分析
1.寻找所需的数据。登录网站,右键网络源代码。
2.数据清洗
对所需的库进行导入:
import datetime import json import time import pandas as pd import requests from lxml import etree import openpyxl from matplotlib import pyplot as plt from pyecharts.charts import Bar from pyecharts.globals import ThemeType from pyecharts import options as opts import shelve # 引入shelve做数据持久化 import seaborn as sns from wordcloud import WordCloud 爬虫主要代码 data = {} data["numeric"] = "生活" data["rankDate"] = "2022-12-15" data["start"] = 1 data["size"] = 50 data["rankType"] = "0" data["type"] = "0" url = "https://www.newrank.cn/nr/bili/rank/complexMainRank" today = datetime.datetime.now() wb = openpyxl.Workbook() ws = wb.active ws.title = "UP数据" ws.append(["UP主号", "投稿视频数", "投币数", "弹幕数", "最高点赞数", "播放数", "涨粉数", "新榜指数"]) # 获取近三百天的数据 for i in range(300): data["rankDate"] = str((today + datetime.timedelta(days=-i)).date()) res = requests.post(url, json=data) res_str = res.content.decode("utf-8").replace('\\x', '%') res_data = json.loads(res_str) local_data = res_data['data']['vos'] for item in local_data: if 'w' in item["followerDiff"]: item["followerDiff"] = item["followerDiff"].replace('w', '') item["followerDiff"] = str(float(item["followerDiff"]) * 10000) if 'w' in item["opusCount"]: item["opusCount"] = item["opusCount"].replace('w', '') item["opusCount"] = str(float(item["opusCount"]) * 10000) if 'w' in item["coinCount"]: item["coinCount"] = item["coinCount"].replace('w', '') item["coinCount"] = str(float(item["coinCount"]) * 10000) if 'w' in item["videoReviewCount"]: item["videoReviewCount"] = item["videoReviewCount"].replace('w', '') item["videoReviewCount"] = str(float(item["videoReviewCount"]) * 10000) if 'w' in item["likeCount"]: item["likeCount"] = item["likeCount"].replace('w', '') item["likeCount"] = str(float(item["likeCount"]) * 10000) if 'w' in item["playCount"]: item["playCount"] = item["playCount"].replace('w', '') item["playCount"] = str(float(item["playCount"]) * 10000) temp = [item["name"], item["opusCount"], item["coinCount"], item["videoReviewCount"], item["likeCount"], item["playCount"], item["followerDiff"], item["newrankIndex"]] ws.append(temp) wb.save('data.xlsx')
运行后:
打开文件: bilibilidata数据表格
绘制wordcloud
wb = openpyxl.load_workbook('data.xlsx') ws = wb.active def create_cloud(frequency, name): wordcloud = WordCloud(font_path="C:/Windows/Fonts/simsun.ttc", background_color="white", width=2021, height=1080) wordcloud.generate_from_frequencies(frequency) wordcloud.to_file('%s.png' % name) frequency_follower = {} frequency_movie = {} for row in ws.values: if row[0] == "UP主号": pass else: if row[0] not in frequency_follower: frequency_follower[row[0]] = 0 frequency_follower[row[0]] += float(row[6]) if row[0] not in frequency_movie: frequency_movie[row[0]] = 0 frequency_movie[row[0]] += float(row[1]) create_cloud(frequency_follower, "近300天up主涨粉数情况词云图") create_cloud(frequency_movie, "近300天up主发视频数情况词云图")
生成词云png格式图片
UP主发视频情况和涨粉词云
3. 数据可视化
df = db = shelve.open("store") df = db.get("data") group_show = df.groupby('UP主号')[['播放数']].sum().reset_index() group_review = df.groupby('UP主号')[['最高点赞数']].sum().reset_index() up = group_show['UP主号'].values.tolist() show = group_show['播放数'].values.tolist() review = group_review['最高点赞数'].values.tolist() bar1 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up) .add_yaxis("播放数", show) .set_global_opts( title_opts={"text": "播放数"} ) # 生成html文件 .render("UP播放数.html") ) bar2 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up) .add_yaxis("点赞数", review, stack="stack1", category_gap="50%") .add_yaxis("播放数", show, stack="stack1", category_gap="50%") # 生成文件 .set_global_opts( title_opts={"text": "播放数与点赞数对比"} ) .render("播放数与点赞数对比.html") ) bar3 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up[:50]) .add_yaxis("点赞数", review[:50], stack="stack1", category_gap="50%") .add_yaxis("播放数", show[:50], stack="stack1", category_gap="50%") # 生成文件 .set_global_opts( title_opts={"text": "播放数与点赞数对比"} ) .render("播放数与点赞数对比(前50条).html") )
播放数与点赞数可视化对比(前50条)
播放数与点赞数可视化对比
播放数可视化
最高点赞数与投币数的关系
四、附完整程序源代码
import datetime import json import time import pandas as pd import requests from lxml import etree import openpyxl from matplotlib import pyplot as plt from pyecharts.charts import Bar from pyecharts.globals import ThemeType from pyecharts import options as opts import shelve # 引入shelve做数据持久化 import seaborn as sns from wordcloud import WordCloud # 获得B站每天排行前50的UP数据 data = {} data["numeric"] = "生活" data["rankDate"] = "2022-12-15" data["start"] = 1 data["size"] = 50 data["rankType"] = "0" data["type"] = "0" url = "https://www.newrank.cn/nr/bili/rank/complexMainRank" today = datetime.datetime.now() wb = openpyxl.Workbook() ws = wb.active ws.title = "UP数据" ws.append(["UP主号", "投稿视频数", "投币数", "弹幕数", "最高点赞数", "播放数", "涨粉数", "新榜指数"]) # 获取近三百天的数据 for i in range(300): data["rankDate"] = str((today + datetime.timedelta(days=-i)).date()) res = requests.post(url, json=data) res_str = res.content.decode("utf-8").replace('\\x', '%') res_data = json.loads(res_str) local_data = res_data['data']['vos'] for item in local_data: if 'w' in item["followerDiff"]: item["followerDiff"] = item["followerDiff"].replace('w', '') item["followerDiff"] = str(float(item["followerDiff"]) * 10000) if 'w' in item["opusCount"]: item["opusCount"] = item["opusCount"].replace('w', '') item["opusCount"] = str(float(item["opusCount"]) * 10000) if 'w' in item["coinCount"]: item["coinCount"] = item["coinCount"].replace('w', '') item["coinCount"] = str(float(item["coinCount"]) * 10000) if 'w' in item["videoReviewCount"]: item["videoReviewCount"] = item["videoReviewCount"].replace('w', '') item["videoReviewCount"] = str(float(item["videoReviewCount"]) * 10000) if 'w' in item["likeCount"]: item["likeCount"] = item["likeCount"].replace('w', '') item["likeCount"] = str(float(item["likeCount"]) * 10000) if 'w' in item["playCount"]: item["playCount"] = item["playCount"].replace('w', '') item["playCount"] = str(float(item["playCount"]) * 10000) temp = [item["name"], item["opusCount"], item["coinCount"], item["videoReviewCount"], item["likeCount"], item["playCount"], item["followerDiff"], item["newrankIndex"]] ws.append(temp) wb.save('data.xlsx') # 持久化 data = pd.read_excel('data.xlsx') db = shelve.open('store') db['data'] = data db.close() # 词云 wb = openpyxl.load_workbook('data.xlsx') ws = wb.active def create_cloud(frequency, name): wordcloud = WordCloud(font_path="C:/Windows/Fonts/simsun.ttc", background_color="white", width=2021, height=1080) wordcloud.generate_from_frequencies(frequency) wordcloud.to_file('%s.png' % name) frequency_follower = {} frequency_movie = {} for row in ws.values: if row[0] == "UP主号": pass else: if row[0] not in frequency_follower: frequency_follower[row[0]] = 0 frequency_follower[row[0]] += float(row[6]) if row[0] not in frequency_movie: frequency_movie[row[0]] = 0 frequency_movie[row[0]] += float(row[1]) create_cloud(frequency_follower, "近300天up主涨粉数情况词云图") create_cloud(frequency_movie, "近300天up主发视频数情况词云图") # 生成柱状图 df = db = shelve.open("store") df = db.get("data") group_show = df.groupby('UP主号')[['播放数']].sum().reset_index() group_review = df.groupby('UP主号')[['最高点赞数']].sum().reset_index() up = group_show['UP主号'].values.tolist() show = group_show['播放数'].values.tolist() review = group_review['最高点赞数'].values.tolist() bar1 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up) .add_yaxis("播放数", show) .set_global_opts( title_opts={"text": "播放数"} ) # 生成html文件 .render("UP播放数.html") ) bar2 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up) .add_yaxis("点赞数", review, stack="stack1", category_gap="50%") .add_yaxis("播放数", show, stack="stack1", category_gap="50%") # 生成文件 .set_global_opts( title_opts={"text": "播放数与点赞数对比"} ) .render("播放数与点赞数对比.html") ) bar3 = ( Bar({"theme": ThemeType.MACARONS, "width": "1600px", "height": "720px"}) .add_xaxis(up[:50]) .add_yaxis("点赞数", review[:50], stack="stack1", category_gap="50%") .add_yaxis("播放数", show[:50], stack="stack1", category_gap="50%") # 生成文件 .set_global_opts( title_opts={"text": "播放数与点赞数对比"} ) .render("播放数与点赞数对比(前50条).html") ) # 线性回归图 db = shelve.open("store") plt_data = db.get("data") plt_data.head() sns.set() plt.rcParams['font.sans-serif'] = ['SimHei'] plt.grid() sns.lmplot(x='最高点赞数', y='投币数', data=plt_data) plt.savefig("最高点赞数与投币数的关系.png", dpi=300)
五、总结
1.总结
通过本次的课程设计学习,我们可以清晰的了解到bilibili博主的播放数、点赞数、投币数和涨粉数之间的关系。
2.目标
已经达到我预期的目标。通过对爬取的数据进行数据可视化分析,可以较便捷得看出up博主视频的情况。
3.自我建议
(1)加强自身独立自主的能力,提高编程技能。在本次课程设计中,询问了室友许多的内容。自己在编程上的功底薄弱,有待加强。
(2)多逛csdn等编程学习平台,扎实自身,并打开视野。
标签:课程设计,Python,UP,item,柱状图,frequency,import,播放,data From: https://www.cnblogs.com/0xMike/p/16999471.html