前言:受到明佬《CSDN文章漫游者》的启发(←造福C站全体用户,最新版文章漫游者v0.3开放下载,赶快体验吧!),笔者将 CSDN 总榜 TOP10 的大佬们的文章数据爬了下来,分析一波大佬们名利前茅的秘密所在。本次分析用到的工具如下:
import pandas as pd
from datetime import datetime
import jieba
from pyecharts.charts import Bar, Pie, Timeline, WordCloud
from pyecharts import options as opts
一、TOP10 博主数据样本
首先,大概浏览一下采集到的数据,分为三个表。第一个是用户信息表 user ,包含 10 位博主的总体数据信息,及专栏信息串(形式为 专栏名称& 文章数; 专栏名称& 文章数; …)。
第二个是专栏信息表 special ,包含博主们所有专栏的相关信息。
第三个是文章信息表 article ,包含博主们所有文章的标题、摘要及相关数据信息,可见若要对专栏进行分析,用后两个表处理起来会更方便。
二、TOP10 博主综合分析
下面,笔者将从七个角度来对 TOP10 进行一次综合分析。
1、吸睛获粉哪家强?
那么,就让我们先从宏观来了解一下大佬们的总体情况吧。直接看原创数、访问量、粉丝数、总获赞、总评论、总收藏等基本指标,分别排序制图显得有些繁琐,可以利用 pandas 的样式功能制作热力图,在各自列中值越大,颜色越深。显而易见的是,各指标各自的排名之间没有必然的联系,写文多不一定访问多,访问多不一定粉丝多,粉丝多也不一定就获赞多。
user_data1 = user[['用户', '原创数', '访问', '粉丝', '总获赞', '总评论', '总收藏']]
user_data1.style.background_gradient()
进一步计算平均访问量、文章吸粉力、粉丝转化率后,却发现热力区有下沉之势,这在一定程度上表明后浪更具冲劲,前排的博主要悠着点啦。
user_data1['平均访问量'] = (user_data1['访问']/user_data1['原创数']).round(1)
user_data1['文章吸粉力'] = (user_data1['粉丝']/user_data1['原创数']).round(1)
user_data1['粉丝转化率'] = (user_data1['粉丝']/user_data1['访问']).round(2)
user_data1.iloc[:,[0,7,8,9]].style.background_gradient()
2、好评热议哪家强?
再计算一波个人的平均获赞、平均评论、平均收藏,可见有一位博主占据了评论与收藏双顶,表明其文章更容易引起大家讨论,讨论还不够,还要收藏后反复品读。另一位博主获赞情况最佳,看不懂插不了嘴,赞就完事儿了(开玩笑的)。
user_data1['平均获赞'] = (user_data1['总获赞']/user_data1['原创数']).round(1)
user_data1['平均评论'] = (user_data1['总评论']/user_data1['原创数']).round(1)
user_data1['平均收藏'] = (user_data1['总收藏']/user_data1['原创数']).round(1)
bar_user = (
Bar(init_opts=opts.InitOpts(width='1500px'))
.add_xaxis(user_data1['用户'].to_list())
.add_yaxis("平均获赞", user_data1['平均获赞'].to_list())
.add_yaxis("平均评论", user_data1['平均评论'].to_list())
.add_yaxis("平均收藏", user_data1['平均收藏'].to_list())
.set_global_opts(xaxis_opts=opts.AxisOpts(axislabel_opts={"interval":"0"}))
.set_series_opts(
label_opts=opts.LabelOpts(is_show=False),
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]),
)
)
bar_user.render_notebook()
3、肝帝谁与争锋?
让我们瞧瞧各位博主的肝度变化吧,是不忘初心还是再接再厉呢?首先整理一下需要的数据格式,我们想看的是每个月的历史累计发布量变化,那么先提截取出月份,通过透视得到每个月的月度发布量。
article['月份'] = article['发布时间'].str[:7]
article_per_month = pd.pivot_table(article, index=['月份'], columns=['用户'], values=["文章标题"], aggfunc=[len], fill_value=0).droplevel([0, 1], axis=1)
article_per_month.head()
可以看到 TOP10 中最早发迹的博主,其在 2006 年 4 月就发布了 19 篇文章。 在进行下一步前,先看看月度最佳是谁,发现有一位博主以 405 篇/月的战绩傲视群雄,但都是在同一天内发布的,看来是囤货了呀。 利用 pandas 获取历史累计发布量非常简单,只需调用 cumsum() 即可把每一行再加上前一行的值进行计算。
article_grand_total = article_per_month.cumsum().reset_index()
article_grand_total.head()
再用 melt() 将宽表转为长表,这样做的目的是便于提供 pyecharts 动态图所需的数据格式。
agt = pd.melt(article_grand_total, id_vars=['月份'])
agt
这次笔者制作了一个动态玫瑰图来呈现博主们的发布量变化,通过不断生长的环形区块,更加形象地展现了拉锯战的激烈(花里胡哨的,其实是动态条形图看腻了 )。
tl = Timeline()
tl.add_schema(play_interval=50)
for month in article_grand_total['月份']:
_agt = agt[agt['月份']==month].iloc[:,1:]
p = (
Pie()
.add('', list(zip(_agt['用户'], _agt.value)),
radius=['30%', '50%'], center=['50%', '50%'],
rosetype="radius")
.set_series_opts(
label_opts=opts.LabelOpts(
is_show=True,
position="outside",
formatter="{b}: {c}篇",
font_size=15,
font_weight="bold",
font_family="Microsoft YaHei"
),
)
.set_global_opts(
title_opts=opts.TitleOpts(f'{month}发布量', pos_left='42%', pos_top='48%'),
)
)
tl.add(p, f'{month}')
tl.render_notebook()
4、躺平,我就躺一下…
按照 CSDN 官方说明,其实总榜是根据积分和活跃度进行排名的,而积分又是根据文章发布量及热度计算的,所以我们也能发现积分排名和总榜排名的不一致。
作者总榜:基于博客积分对合规和创作活跃的用户进行排名。如果用户创作的内容不合规,将不被排名;如果用户创作不活跃,将根据其最近一次创作的时间,对其名次进行下调,下调的系数是一个时间衰减函数。10个月未创作,系数将衰减为零。
那就把偷懒的博主揪出来,催更!对比总榜排名和积分排名,若后者更靠前,则表示存在活跃度下降的情况。
user['积分排名'] = user['积分'].rank(ascending=False)
user.query('积分排名<总排名')[['用户', '总排名', '积分排名']]
再验证一下实际情况,取各位博主最近一次发布的时间,按用户和发布时间排序后分组,再取最后一个即可。
grp_apd = article.sort_values(['用户','发布时间']).groupby('用户').last()['发布时间']
grp_apd
再计算一下最近发布时间距今的天数,emmmm,某博主竟然有过百日未发文了!但这似乎没有体现出总榜排名的规则,CSDN 还留了一手哇(究竟在搞什么鬼呢 )。
recent = pd.DataFrame({'username':grp_apd.index, 'last_date':grp_apd.values})
recent['last_date'] = pd.to_datetime(recent['last_date'])
recent['so_far'] = (datetime.now()-recent['last_date']).dt.days
recent
5、博主们在写什么?
专栏名称已经是博主对文章分类提炼后的结果,因此,直接分析专栏会更高效,简单分词并制作词云图即可。
article['专栏分词'] = article['所属专栏'].astype(str).apply(lambda x: ','.join(jieba.lcut(x)))
jieba_str = ','.join([w for w in article['专栏分词'].values if w not in stopwords])
word_counter = {}
for word in jieba_str.split(','):
word_counter[word] = word_counter.get(word, 0) + 1
special_data = sorted(list(word_counter.items()), reverse=True, key=lambda x: x[1])[:100]
wc = (WordCloud()
.add("", special_data, shape="diamond")
)
wc.render_notebook()
6、读者们关心什么?
我们已经有了阅读、评论、点赞、收藏等 4 个指标来反映读者对文章的投入度,为了便于分析,可将其分别按数量区级分级,如低(1)、中(2)、高(3)、热(4),并可由此计算一个综合指数来体现文章的热度。 先来看一下原指标的基本情况,读者们的评论、点赞、收藏倾向都很极端,要么看了就跑,要么疯狂三连。
article.describe().round()
那么,对于各指标进行分箱,生成新指标。
article['瞩目级别'] = pd.cut(article['阅读'], bins = [0,500,1000,5000,99999], labels=[1, 2, 3, 4], right=False)
article['热议级别'] = pd.cut(article['评论'], bins = [0,100,500,1000,99999], labels=[1, 2, 3, 4], right=False)
article['点赞级别'] = pd.cut(article['点赞'], bins = [0,100,500,1000,99999], labels=[1, 2, 3, 4], right=False)
article['收藏级别'] = pd.cut(article['收藏'], bins = [0,100,500,1000,99999], labels=[1, 2, 3, 4], right=False)
article_hot = article[['所属专栏', '瞩目级别', '热议级别', '点赞级别', '收藏级别']]
article_hot
然后我们可以看一下高阅读且高赞的专栏有哪些,发现读者们对技术之外的'非技术向的感悟和总结' 也很感兴趣,不亏是吃瓜群众呀。
article_hot[(article_hot['瞩目级别']>2)&(article_hot['点赞级别']>2)]['所属专栏'].unique()
array([‘网络’, ‘非技术向的感悟和总结’, ‘程序人生’, ‘后端’, ‘cpp’, ‘面经合集’, ‘动态规划’, ‘趣学Java’, ‘python’, ‘Python’, ‘大数据集锦’, ‘NOSQL’, ‘编程技术’, ‘SQL’, ‘数据结构与算法’, ‘Java’, ‘os/设计模式/耳机/测试/导图/资源 杂记’, ‘DayDayUp’, ‘无’], dtype=object)
7、吃瓜环节:大佬关系网
在地球村,最多通过 6 个人就能联系上任何一个原本不认识的人。那么在 C 村这个小圈,博主们的关系网是什么样的呢?由于不便将全村人的(被)关注情况都扒个精光,在此仅通过 TOP10 博主的关注数据做一下简要分析。先看一下原始的关联数据:
构造 pyecharts 关系图所需的节点和链接数据,进行可视化。
df = pd.read_excel('follow.xlsx')
grp = df.groupby('用户')['关注'].count()
nodes_article = [{"name": n, "symbolSize": v/7} for n, v in zip(grp.index, grp.values)]
links_article = [{"source": s, "target": t} for s, t in zip(df['用户'], df['关注'])]
g = (
Graph()
.add("", nodes_article, links_article,
layout='circular',
linestyle_opts=opts.LineStyleOpts(curve=0.2),
)
)
节点大小反应了该用户关注其他用户的数量大小,可见 TOP10 博主中有 7 位比较高冷,几乎不关注其他人,但还是有一些博主之间有互相关注的。
三、后话
要细细深挖还有许多工作可做,最近实在太忙了,有机会的话再继续研究哈哈。因大佬们的文章都是心血产出,为保护知识产权,本次不提供爬虫代码,部分数据样本可戳 codechina 获取,仅供学习参考。本篇是兴趣使然的分析,如有不当之处,欢迎指正。这里是愁于要写什么文章才好的 Seon塞翁,下一篇再见!
|