无所事事的时候看到这站内的这个帖子,正好最近在做(学习)数据分析的工作,同时我对主帖子中的一些问题表示关注,所以顺带水一片博文进行分析。

首先对从那些地方能获取到数据要进行分析:用户在论坛发帖提交Banner会留下记录,管理员使用Banner更换系统进行自动更换时会在“普通”日志中留下记录,已经展示过的Banner有集中展示页面。
所有数据基于站内公开数据,数据最后更新
(爬取)于2018/07/11 17:00,未统计早期(2015年1月至11月)Banner信息
本文仅限NPUBits内部论坛以及本人博客( https://blog.rhilip.info )发布,禁止转载。
近一年Banner更新间隔
这一节主要分析log页面。系统在日志页留下的记录一般如下:

2018-07-06 00:00:01 Site BANNER was auto changed to 神啊,请赐予败犬幸福! on schedule. July 6, 2018, 12:00 am
记录中会留下实际更换时间,更换的Banner关联的主题以及计划更换时间。因为实际更换时间与计划基本一致,且换算到小时为单位时误差可以忽略,所以简单的抓取实际更换时间即可,下面为示例代码:
1 | import arrow |
统计结果如下
| 小时 | 计数 | 小时 | 计数 | 小时 | 计数 | 小时 | 计数 |
|---|---|---|---|---|---|---|---|
| 0 | 10 | 24 | 49 | 48 | 16 | 72 | 3 |
| 1 | 4 | 25 | 4 | 49 | 1 | 76 | 1 |
| 2 | 1 | 26 | 4 | 50 | 0 | 79 | 1 |
| 3 | 2 | 27 | 1 | 51 | 1 | 88 | 2 |
| 4 | 3 | 28 | 0 | 52 | 0 | 90 | 1 |
| 5 | 0 | 29 | 3 | 53 | 0 | 94 | 1 |
| 6 | 1 | 30 | 1 | 54 | 0 | 96 | 1 |
| 7 | 1 | 31 | 4 | 55 | 2 | 110 | 1 |
| 8 | 4 | 32 | 2 | 56 | 3 | 111 | 1 |
| 9 | 2 | 33 | 1 | 57 | 2 | 113 | 1 |
| 10 | 2 | 34 | 0 | 58 | 0 | 153 | 1 |
| 11 | 3 | 35 | 5 | 59 | 0 | 156 | 1 |
| 12 | 8 | 36 | 5 | 60 | 1 | 157 | 1 |
| 13 | 2 | 37 | 1 | 61 | 1 | 204 | 1 |
| 14 | 4 | 38 | 2 | 62 | 0 | 206 | 1 |
| 15 | 6 | 39 | 1 | 63 | 2 | 240 | 1 |
| 16 | 4 | 40 | 1 | 64 | 0 | ||
| 17 | 1 | 41 | 0 | 65 | 0 | ||
| 18 | 2 | 42 | 0 | 66 | 0 | ||
| 19 | 1 | 43 | 1 | 67 | 2 | ||
| 20 | 0 | 44 | 1 | 68 | 2 | ||
| 21 | 3 | 45 | 1 | 69 | 0 | ||
| 22 | 1 | 46 | 4 | 70 | 0 | ||
| 23 | 27 | 47 | 12 | 71 | 3 |
通过统计,在这一年中(NexusPHP的日志只保留最近一年的相关历史)共使用了250次Banner(可能存在重复情况,此处暂不做考虑),这些Banner最短停留时间为4s(2017/11/7 8:00:07 - 2017/11/7 8:00:11),排除掉这个极端数据的话,停留时间最短一般为5分钟,停留时间最长的一次 Banner则有10天(2017/7/27 8:00:03 - 2017/8/6 8:00:09)。此外,一次 Banner 平均停留时间为 35.69小时(约128487s)。而从更换时间上看,多数情况下是在0点,8点,18点进行自动更换的。

这样看来,多数投稿的Banner其实并不能展示两天(滑稽。超过1/3的投稿作品只能在首页停留1天,当然也同样存在1/3的投稿作品能活过1天的时间线一直生存到第二天。。

Banner 历史
这一节主要分析bannerthank页面。这个页面是用来展示站内已经使用的Banner信息,页面结构如下:

通过对页面的分析,可以从中获取很多信息。我将这些信息分成4种类型:
- Banner相关: 递增id、替换时间、关联链接、获得“赞”数量、获得“沙砾”数量
- 发布者相关: 用户id、用户名称、用户等级
- 图片信息:图片链接、图片上传时间、图片标识符(md5)、
图片类型(后续人工分类)
同样写一个简单爬虫,并使用sqlite3数据库对相关数据进行存储,并下载对应Banner进行后续分析。
代码示例如下:
1 | import os |
记录条数
根据前面爬虫数据可知,目前站内共使用了579次Banner悬挂,但部分记录已经被删除,实际共爬取下573条记录。根据文件hash值(md5值)判断,共有550个不重复的Banner文件。而根据文件来判断,则一共下载共572个Banner文件。
1 | # 记录示例 |
更换频次
对 b_date 字段进行简单分析,首先以一个月为单位进行处理获取banner更新频率,示例SQL如下:
1 | Select strftime('%Y-%m',b_date) as date_ym, count(*) from banner group by date_ym |
| 2015 | 更换次数 | 2016 | 更换次数 | 2017 | 更换次数 | 2018 | 更换次数 |
|---|---|---|---|---|---|---|---|
| 2016-01 | 13 | 2017-01 | 12 | 2018-01 | 24 | ||
| 2016-02 | 10 | 2017-02 | 3 | 2018-02 | 23 | ||
| 2016-03 | 15 | 2017-03 | 14 | 2018-03 | 22 | ||
| 2016-04 | 18 | 2017-04 | 25 | 2018-04 | 15 | ||
| 2016-05 | 21 | 2017-05 | 22 | 2018-05 | 25 | ||
| 2016-06 | 13 | 2017-06 | 31 | 2018-06 | 19 | ||
| 2016-07 | 8 | 2017-07 | 10 | 2018-07 | 5 | ||
| 2016-08 | 13 | 2017-08 | 8 | ||||
| 2016-09 | 9 | 2017-09 | 17 | ||||
| 2015-10 | 1 | 2016-10 | 21 | 2017-10 | 19 | ||
| 2015-11 | 14 | 2016-11 | 12 | 2017-11 | 18 | ||
| 2015-12 | 40 | 2016-12 | 28 | 2017-12 | 25 | ||
| 年均 | 18 | 年均 | 15 | 年均 | 17 | 年均 | 10 |
从年均数据上看,每月平均更换Banner数量均在 16 以上(2018年7月因只过了半个月冲稀了数量)。此外,寒暑假对更换的影响仍然存在,但这一现象在18年寒假表现得并不是很明显(因为春节系列Banner更换)。

投稿用户等级分布
对用户信息进行分析
1 | Select up_id,up_name,up_level,count(*) from banner group by up_id; |
总共有115位用户为站点贡献了所有的Banner。这其中,按照用户现在的等级来进行分类的话,普通用户投稿的比例其实并没有想象中的那么多,只占据了一半不到。站内多数作品仍然是美工组(多数为Retiree或者VIP级别)投稿使用或复用。

而从单个用户被采纳的Banner数量来看(此表只列出采纳数大于5的用户数量)。桐壶以及胖虎两位dalao为站内贡献了绝大多数的Banner。多数人投稿的Banner仅被采纳了1次(或仅进行了一次投稿)。采纳Banner数量大于5的用户仅有30位,列表如下。
| 用户名 | 采纳数 | 用户名 | 采纳数 | 用户名 | 采纳数 |
|---|---|---|---|---|---|
| 桐壶 | 112 | Gulnaz | 11 | Edge | 5 |
| 胖虎 | 64 | zbx123 | 9 | Fade | 5 |
| 黄昏的尘土 | 20 | 扑克脸8888 | 9 | Gaussian | 5 |
| Miss老杨 | 18 | Jooooo啊 | 8 | Holiday0 | 5 |
| 云端的林公子 | 18 | Mask小丑 | 8 | IamNobody | 5 |
| 咴咴君 | 17 | 卯月 | 8 | QSQS | 5 |
| lovelive | 16 | 徐某 | 8 | Twinkle | 5 |
| pokerpoke | 13 | Tres | 7 | dongwanqing | 5 |
| Wangxiaozzz | 12 | 404 | 5 | 发种姬是Loli控 | 5 |
| Grimace.RS | 11 | 404Notfound | 5 | 吃葡萄不吐橘子皮 | 5 |

图片基本信息
使用python的PIL库读取图片文件的宽高信息。代码示例如下:
1 | from PIL import Image |
通过统计,常用的图片上传格式为jpg (计数 543,占比 94.7 % )以及png(计数 29,占比 5.06 % ),而常见尺寸为 1280x230 以及 1400x312 。(Ps. 我还用过 1400x320 的分辨率),详细统计数据见下图

用户奖励情况
通过提取数据库信息获取用户对Banner的奖励情况
1 | Select thanks_count,thanks_bonus,thanks_bonus/thanks_count as thank_avg from banner |
经过整理得到下列信息,通过Banner点赞系统,用户共点击了51743次赞,共送出了588w沙砾,平均下来每个Banner都能获得1w左右的沙砾。而目前获得沙砾最多的是来自@GJP 制作的纪念性Banner (链接),此外第二名也是一个纪念陈士橹院士的Banner。
| total | avg. | min | max | |
|---|---|---|---|---|
| thanks_count | 51743 | 90.30192 | 2 | 880 |
| thanks_bonus | 5880263 | 10262.24 | 0 | 97950 |
| thank_avg | 60733 | 105.9913 | 0 | 1670 |
考虑到用户可以通过接口获取具体的点赞数量,但这部分数据并不好进行解析(目录树不清晰,用户名以及可能存在的奖励信息在同一子树下),DOM结构分别如下
1 | <span class="nowrap"><a class="User_Name username" data-userid="46398" href="userdetails.php?id=46398"><b>zbw</b></a></span> <!-- 用户纯点赞 --> |
所以对这块的清洗需要进行一些取巧的操作,以获取 id=579 为例
1 | thank_details_page = requests.get("https://npupt.com/bannerthanks.php?action=detail&id=579",cookies=cookies) |
批量爬取的整段方法如下
1 | db_c.execute("CREATE TABLE thank ( " + |
爬取完成后的数据存入数据表thank。并使用以下SQL语句进行提取分析绘图
1 | Select thanks_user,sum(thanks_bonus) as total_bonus,count(*) as total_thanks from thank group by thanks_user; |

默存大是土豪!默存大是土豪!默存大是土豪!共计 147次点赞共送出了 653,010沙砾,平均每次送出 4442沙砾。远远甩开其他管理组成员打赏总额。
1 | Select thanks_bonus,count(*) from thank where thanks_user="默存" group by thanks_bonus; |

Banner类别
因为这块在Banner相关的任何位置均无法准确定位类别,所以我人工将其划分为以下各类:电影(含动漫电影)、动漫、剧集、游戏、体育、节日(含西元节日、法定节假日、传统节日、二十四节气等)、站内活动、时事(含人物纪念)、校园活动、其他(纯标语或难以归于以上各类),统计并更新数据库,如果有分类不准确的情况还请谅解。
(我已经对这种机械性分类劳动表示厌烦了

经过分类统计显示,动漫类Banner实际上并不算很多,站内很大一部分Banner更换计划实际是被节日类占用,而将投稿类别与悬挂时间相联系起来的话,其实平均悬挂时间均差不多,站务组并没有特别偏向某一题材作品,而是按照真实的投稿比例进行展示。


统计时悬挂时长不足一天的计数为0天,悬挂1-2天的计数为1天,以此推论。
投稿信息
这一节主要分析论坛美工作品区,爬虫抓取投稿时间以及热度(回复/查看)并使用数据库存储,代码示意如下:
1 | db_c.execute("CREATE TABLE topic (" + |
以同样的方法获取Banner提交频次(此处一并统计较少的非Banner主题帖发布情况,后同)
1 | Select strftime('%Y-%m',f_date) as date_ym, count(*) from topic group by date_ym |

通过统计可得,2016年平均月投稿12.58贴,2017年为16.08贴,而2018年至今为19.14贴(7月按12贴计算)。而综合下来平均月投稿数量为15.06贴,用户投稿(贴)数量确实是在逐渐增加。但通过前面与更换频次的结果对比,特别是考虑站内部分固定更换的Banner情况存在,其实很难保证用户投稿的所有Banner均能够进行有效的展示。
而从主题回复以及查看的情况来看,除E姐的石头门以及re0的特效Banner之外,其他主题贴内容基本不与动漫相关。(可见死宅们果然是每隔几个月就换老婆的)
主题贴回复排行榜(前10名)
| 帖子id | 发布时间 | 名称 | 发布者 | 回复数 | 查看数 |
|---|---|---|---|---|---|
| 1983 | 2015/12/4 | 【终于填了坑但还是没重新做】Steins;Gate - 大家好我是来考古的 | 卯月 | 62 | 3596 |
| 1990 | 2015/12/5 | 第一次做banner,被夸的话……会害羞的! | 咴咴君 | 51 | 1530 |
| 3236 | 2016/12/4 | Five years later… | 一色彩羽 | 46 | 2628 |
| 3200 | 2016/12/2 | Re : Start | 卯月 | 46 | 4400 |
| 3354 | 2016/12/26 | 二十四节气第二波 | 桐壶 | 45 | 29613 |
| 2480 | 2016/5/13 | (第二次投稿,完了停不下来了)山寨一大波游戏 | Wangxiaozzz | 45 | 3950 |
| 5665 | 2018/5/21 | RNG夺得MSI冠军!!!!RNG牛逼!!!UZI牛逼!!!!!!! | Twinkle | 42 | 2264 |
| 4098 | 2017/7/2 | 做了个黑暗剑的banner,传播一下秦流感 | 布鲁斯韦天 | 40 | 2435 |
| 2505 | 2016/5/19 | 做点特别的东西纪念这段666天的异地恋 | WIRY95 | 40 | 1672 |
| 3819 | 2017/5/17 | 权力的游戏第七季_2017.07.16北美开播_预告一下~ | 桐壶 | 38 | 7283 |
主题贴查看排行榜(前10名)
| 帖子id | 发布时间 | 名称 | 发布者 | 回复数 | 查看数 |
|---|---|---|---|---|---|
| 1830 | 2015/11/9 | Banner自由投稿说明 | XE | 34 | 46410 |
| 3354 | 2016/12/26 | 二十四节气第二波 | 桐壶 | 45 | 29613 |
| 3405 | 2017/1/9 | 加油!蒲公英 | Gaussian | 2 | 11089 |
| 3819 | 2017/5/17 | 权力的游戏第七季_2017.07.16北美开播_预告一下~ | 桐壶 | 38 | 7283 |
| 4292 | 2017/9/9 | 悬赏征集Banner&侧边栏,为我妹妹疯狂打call | IU是我妹妹 | 35 | 6775 |
| 4381 | 2017/9/30 | 萌新的初次尝试请指教 | Gulnaz | 16 | 6139 |
| 2868 | 2016/9/11 | 新手来一波黑暗系 | 北城之光 | 10 | 5646 |
| 4713 | 2017/11/29 | 【工大姑娘】—-梦之翼网络文化工作室品牌栏目宣传 | MrCzx | 30 | 5200 |
| 4894 | 2017/12/30 | 【跳一跳】根本停不下来~ | 胖虎 | 15 | 4680 |
| 2725 | 2016/7/8 | 暑假快乐! | 卯月 | 19 | 4655 |
后记
受限于我已经毕业、忙于实习的现状,这篇文章从准备写作到目前(其实是2天)已经前前后后占用了很多空闲时间(拿来休息看动漫推游戏),所以这次的统计其实到后面也并不是很理想。
身为其他站点管理(在NPU这边挂职锻炼23333),其实是很羡慕站内美工区Banner投稿数量、主题众多的现状。同时,管理Banner更换的管理们也很热心,即使是部分我觉得其实并不算美观或规范的作品也能得到管理组成员的帖子打赏或者悬挂。在这里不是抨击管理不注意筛选,而是应该看到管理组成员鼓励普通用户发布自己制作Banner的用心;当然,也更应该看到在投稿数量日渐增加(其实并没有很明显)的情况下,管理组为作品筛选实际已经在做的一些工作。
此外,就统计结果综合来看,动漫类Banner在更换过程中,其实并没有得到很区别的对待,由于特定日期Banner情况的存在,节日类主题Banner实际在悬挂过程更为常见。而关于时事类题材作品(对展示时间有特定需求的作品应在当天上线展示),在投稿说明以及彩羽的回复中,都有向志愿者团队发信帮忙的提醒。毕竟人无完人,负责对Banner更换志愿者也有自己的学习、工作任务,不可能24小时关注着论坛区。
最后,文章PDF版本以及数据库情况均附在内(,Python源代码因文章中已经基本给出,不再另附),如有需要请自取研究~
其他相关
所用工具: Python 3 (爬虫、分析)、Sqlite (数据库)、Echart (作图展示)
统计+执笔: Rhilip
PDF版及数据库(不含源代码及图片文件):npu_banner_ana.zip
相关论坛帖:
自力更生、艰苦创业~

