Last active
October 3, 2020 01:27
-
-
Save tsukumijima/9229557ea156a6dc6c675d0829a07d47 to your computer and use it in GitHub Desktop.
過去ログの XML からニコニコ実況にコメントしたユーザー ID と総ユーザー数、コメント回数の平均などを算出するツール
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import | |
import argparse | |
import chardet | |
import os | |
import re | |
import statistics | |
import sys | |
import xmltodict | |
import matplotlib.pyplot as plt | |
from collections import OrderedDict | |
from pprint import pprint | |
def main(): | |
# 引数を設定・取得 | |
parser = argparse.ArgumentParser(description = '', formatter_class = argparse.RawTextHelpFormatter) | |
parser.add_argument('InputFile', help = 'InputXML') | |
args = parser.parse_args() | |
# 入力 XML | |
xml_file = args.InputFile | |
print() | |
# ファイル読み込み | |
with open(xml_file, mode = 'rb') as fp: | |
# エンコード判定 | |
xml_binary = fp.read() | |
encoding = chardet.detect(xml_binary) | |
# 判定した文字エンコードでデコード | |
xml = xml_binary.decode(encoding['encoding']) | |
# xml ヘッダをつける | |
if '<?xml version="1.0"' not in xml: | |
xml = '<?xml version="1.0"?>\n<thread>\n' + xml + '\n</thread>' | |
# 不正な xml になっていることがあるので整形 | |
xml = xml.replace('chatthread', 'chat thread') | |
xml = re.sub(r'([^=]")([^> ])', r'\1 \2', xml) | |
# xml を解析 | |
nicojk_comment = xmltodict.parse(xml)['thread']['chat'] | |
# ユーザー ID を確認する OrderedDict | |
nicojk_users = OrderedDict() | |
# コメントごとに回す | |
for nicojk_chat in nicojk_comment: | |
# ユーザー ID が dict 内に存在する | |
if '@user_id' in nicojk_chat: | |
# そのユーザー ID のキーが存在しない | |
if nicojk_chat['@user_id'] not in nicojk_users: | |
# 新しくキーを作成 | |
# nicojk_users[nicojk_chat['@user_id']] = nicojk_chat | |
nicojk_users[nicojk_chat['@user_id']] = OrderedDict(nicojk_chat) | |
nicojk_users[nicojk_chat['@user_id']]['@premium'] = '@premium' in nicojk_chat | |
nicojk_users[nicojk_chat['@user_id']]['name'] = nicojk_chat['@user_id'] | |
nicojk_users[nicojk_chat['@user_id']]['count'] = 1 | |
# すでにキーが存在する | |
else: | |
# カウントを加算 | |
nicojk_users[nicojk_chat['@user_id']]['count'] += 1 | |
# 計算 | |
nicojk_comment_count = [] | |
nicojk_premium_count = 0 | |
for nicojk_user in nicojk_users.values(): | |
# コメント数のみの list を作成 | |
nicojk_comment_count.append(nicojk_user['count']) | |
# プレミアム会員数をカウント | |
if nicojk_user['@premium'] == True: | |
nicojk_premium_count += 1 | |
# 出力 | |
print('ユーザー ID: ' + str(nicojk_user['name']) + ' コメント回数: ' + str(nicojk_user['count']) + ' プレミアム: ' + str(nicojk_user['@premium'])) | |
# 総コメントユーザー数 | |
nicojk_users_count = len(nicojk_users) | |
# うちプレミアム会員の割合 | |
nicojk_premium_percentage = round(nicojk_premium_count / nicojk_users_count * 100, 2) | |
# 平均値・中央値を取得 | |
nicojk_comment_count_mean = round(statistics.mean(nicojk_comment_count), 2) # 平均値 | |
nicojk_comment_count_median = round(statistics.median(nicojk_comment_count), 2) # 中央値 | |
# 出力 | |
print() | |
print('総コメントユーザー数 : ' + str(nicojk_users_count) + ' 人') | |
print(' うちプレミアム会員 : ' + str(nicojk_premium_count) + ' 人 (' + str(nicojk_premium_percentage) + '%)') | |
print('コメント回数の平均値 : ' + str(nicojk_comment_count_mean) + ' 回') | |
print('コメント回数の中央値 : ' + str(nicojk_comment_count_median) + ' 回') | |
print('コメント回数の最大値 : ' + str(max(nicojk_comment_count)) + ' 回') | |
print('コメント回数の最小値 : ' + str(min(nicojk_comment_count)) + ' 回') | |
print() | |
# matplotlib | |
plt.hist(nicojk_comment_count, 200, (0, 200), color='c') | |
plt.xlabel('Number of comments', fontsize=17) | |
plt.ylabel('Number of users', fontsize=17) | |
plt.tick_params(labelsize=12) | |
plt.grid(True) | |
plt.show() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment