今天实验室停电,我又可以名正言顺摸鱼了,想起来之前收集了这个月CC98十大贴的信息,就趁有空分析一下。
CC98
浙江大学CC98论坛,简称“CC98论坛”或“98”,是浙江大学校内论坛。论坛的运营团队为浙江大学CC98论坛运营管理团队,隶属于浙江大学党委宣传部。论坛创建于2002年12月,前身是计算机学院“王重阳”(98id)老师的答疑版,得名于98最初的ip:10.71.45.98。后来王重阳老师以动网bbs5.0为基础发布了网站,并由98论坛第一任站长“萝卜”加以精简完善,形成了98论坛的雏形。什么是十大
十大就是当前最热门的十个帖子,可以出现在首页醒目的地方。
发帖之后,24小时内有机会上十大,超过24小时就无法出现在十大;一个版面最多两个帖子可以上十大;上十大跟参与回复的ID数目有关,跟具体的帖数没有关系,跟浏览量也没有关系。收集数据
获取当前时间点的十大帖子数据
和目前大部分网站一样,改版后的CC98也是动态加载的,所以要抓的数据不是HTML,而是返回的JSON数据。
包含十大贴数据的响应预览在CC98首页打开开发者模式就能找到包含十大帖子数据的API。
定时获取信息
Python有很多任务调度库,我本次使用的是比较轻量级的 schedule ,如果有比较复杂的任务可以使用 Apscheduler 。把代码挂在实验室的服务器上,每天0点自动保存一下当前的十大贴数据,每个帖子的数据是这样子的:
{'id': 4986263, 'title': '开怀酒吧', 'boardId': 135, 'boardName': '开怀一笑', 'participantCount': 49, 'replyCount': 52, 'hitCount': 3940, 'authorName': '霏霏在此', 'authorUserId': 531478, 'createTime': '2020-11-02T00:22:00', 'type': 0, 'isAnonymous': False} 可以看出包含了如下信息:
题目 发帖人ID 帖子所在版面 回复数 发帖时间读取JSON文件
python的 json 模块提供了一种很简单的方式来编码和解码JSON数据。其中两个主要的函数是 json.dumps() 和 json.loads() 。如果要处理的是文件而不是字符串,则可以使用 json.dump() 和 json.load() 来编码和解码JSON数据。
# Writing JSON data with open('data.json', 'w') as f: json.dump(data, f) # Reading data back with open('data.json', 'r') as f: data = json.load(f) 然后就可以愉快地读取之前保存的32个json文件了:
import glob files = glob.glob('./hot_topics/*') data = [] for file in files: with open(file, 'r') as f: data += json.load(f) 也可以转化为pandas的数据结构,方便查看每一条数据。如果 Jupyter 中安装了扩展插件 Nbextentions ,那么其中的 table_beautifier 可以方便我们处理表格数据。
import pandas as pd df = pd.read_json(json.dumps(data)) pd.set_option('display.max_rows', None) print(df) table_beautifier方便了dataframe的预览
统计每个版面上十大的次数
手动统计就太麻烦啦,用Python的 collections 模块中的 Counter 类可以方便的实现这个功能。
import collections board_names = [i['boardName'] for i in data] board_count = collections.Counter(board_names) print(board_count.most_common())
输出如下:
[('心灵之约', 64), ('缘分天空', 54), ('郁闷小屋', 38), ('开怀一笑', 33), ('似水流年', 32), ('校园信息', 20), ('感性空间', 16), ('求职广场', 14), ('学习天地', 5), ('信息资讯', 5), ('研究生', 4), ...... 不出意外,心灵之约是出现次数最多的板块,每天都会统计到2个帖子。紧随其后的是情感区的三个板块,分别是具有交友功能的「缘分天空」、吐槽不开心的「郁闷小屋」和分享快乐的「开怀一笑」。
用pyecharts可视化
pyecharts 是一个可以生成各种各样图表的Python库。
绘制十大贴版面分布图from pyecharts.charts import * from pyecharts import options as opts pie = (Pie(init_opts=opts.InitOpts(width='800px', height='1000px')) .add('', board_count.most_common()) ) pie.render_notebook() 十大贴版面分布图 绘制十大贴版面分布图
分区信息可以在版面列表页中提取到。
包含分区信息的响应预览
import requests r = requests.get('https://api.cc98.org/Board/all') areas = r.json() sunburst_data = [] # 只统计前7个分区 for area in areas[:7]: boards = area['boards'] children = [{"name": board['name'], "value": board_names.count(board['name'])} for board in boards] sunburst_data.append({"name": area['name'], "children": children}) 十大贴版面分布图
用jieba和wordcloud绘制十大贴标题词云
之前写过一个《当我们在缘分天空喷人的时候,我们在喷些什么》,代码稍微改了改就继续用了。
import jieba import wordcloud from random import randint # 导入imageio库中的imread函数,并用这个函数读取本地图片,作为词云形状图片 import imageio mk = imageio.imread("98.png") w = wordcloud.WordCloud(mask=mk) # 导入停用词 stop_words = [line.strip() for line in open('cn_stopwords.txt', encoding="utf-8").readlines()] # 添加自定义词语 jieba.add_word('男征女') jieba.add_word('女征男') jieba.add_word('海底捞') jieba.add_word('耗子尾汁') # 构建并配置词云对象w,注意要加scale参数,提高清晰度 w = wordcloud.WordCloud(width=200, height=200, background_color='white', font_path='HanYiCuFangSongJian.ttf', mask=mk, scale=10, collocations=False, stopwords={*stop_words} ) # 对来自外部文件的文本进行中文分词,得到string titles = [i['title'] for i in data] title_str = ' '.join(titles) words = jieba.lcut(title_str) string = ' '.join(words) # 将string变量传入w的generate()方法,给词云输入文字 w.generate(string) # 将词云图片导出到当前文件夹 w.to_file('output_98.png')
十大贴标题词云
一些浅显的分析
匿名形式下,大家更愿意畅所欲言。「心灵之约」自然不用说,所有帖子都是匿名的。而「郁闷小屋」上十大的38个帖子中,有过半数(21个)是匿名发表的。 情感问题是浙大学子最关心的问题。从十大贴中情感区的帖子占了接近一半可以看出,大家更热衷于讨论带有情感话题的帖子。此外,「心灵之约」的十大贴中有非常大一部分也是在讲情感问题。 「缘分天空」中「女征男」的帖子要多于「男征女」,也更容易引起讨论。本月「缘分天空」最火的5个帖子中除了「站务组群征贴」,其他四个都是「女征男」,其中最火的「杭师大贴」有38623次点击和363条回复。 关于食堂的讨论无处不在。有12个帖子上了十大,分布于「似水流年」、「心灵之约」、「感性空间」、「郁闷小屋」、「校园信息」。 流量比较小的院系区和天下区比较难上十大,上了十大的都是「版主上任贴」和「版聚邀请贴」。
查看更多关于【数据】浙大CC98校园论坛最火的帖子都在讨论什么的详细内容...