一、导出聊天记录.txt。
二、通过正则表达式对txt匹配得到:日期,时间,QQ号码,聊天内容四个列表。
正则表达式分析:
1、’r’是防止字符转义的 如果路径中出现’\t’的话 不加r的话\t就会被转义 而加了’r’之后’\t’就能保留原有的样子。 raw string。
2、[]定义字符范围。[\d-]匹配数字和-格式的字符;\s+ 匹配多个空格。
[^\n]代表任何字符除了\n,任何字符有不同的含义,一般是不包括空白符号、换行,有些情况会包含.。
(?:x|y)非捕获分组,x 和y 任何一个都可以完成正则表达式的匹配。\) 匹配 “)”。
import re
import wordcloud as wc
import jieba
import matplotlib.pyplot as plt
from scipy.misc import imread
re_pat = r'20[\d-]{8}\s[\d:]{7,8}\s+[^\n]+(?:\d{5,11}|@\w+\.[comnetcn]{2,3})\)' # 正则语句,匹配记录头
fn = r'./in/1.txt'
with open(fn, 'r', encoding='utf-8', errors='ignore') as reader:
txt = reader.read()
# find 匹配出pattern对应的字符串列表
log_title_arr = re.findall(re_pat, txt) # 记录头数组['2016-06-24 15:42:52 张某(40**21)',…]
# split根据pattern对文章进行分割,[:1]表示把后面的对话记录。把所有聊天记录保存到一个列表里,和保存qq号码的列表一一对应
log_content_arr = re.split(re_pat, txt)[1:] # 记录内容数组['\n', '\n选修的\n\n', '\n就怕这次…]
分别得到四个部分。(?<=\()表示需要字符串里有“(”但是完成匹配返回值里面不保留“(”,称为正回顾后发断言。
[^\)]+匹配除了“)”之外的任意字符,因此可以得到qq号码。
for i in range(int(len(log_title_arr))):
date = re.search(r'20[\d-]{8}\s[\d:]{7,8}', log_title_arr[i]).group() # 匹配记录头中的时间
qq = re.search(r'(?<=\()[^\)]+', log_title_arr[i]).group() # 匹配记录头中的QQ号
content = log_content_arr[i].strip('\n') # 聊天内容
hour = re.search(r'(?<=\s)[^\:]+', date).group() # 一天中聊天的时刻
times.append(date) # 记录所有的聊天日期
hours.append(hour) # 记录所有聊天时刻点
qqs.append(qq) # 所有qq
contents.append(content) # 所有聊天内容
entity.append((date, qq, content))
三、对整体聊天内容和每个用户的聊天内容制作词云。
1.得到每个qq 对应的聊天记录
# 每个人的聊天记录
oneqq = set(qqs)
print(oneqq)
for qq in oneqq:
contentuser = ''
for i in range(len(entity)):
if qq == entity[i][1]:
contentuser += entity[i][2]
2、数据预处理:分词并把聊天记录的‘表情’和‘图片’去掉。
all_text = contentuser.replace('\n', '')
all_text = all_text.replace('\u3000', '')
seg_list = jieba.cut(all_text, cut_all=False)
words = ' '
for seg in seg_list:
if seg not in stopwords and seg != '表情'and seg != '图片'and seg !='葱油'and seg !='鲤鱼':
words = words + seg + ' '
print(words)
3、词云生成.:wordcloud模块。
font 使用windows自带的字体。scale 词云里每个词语的分辨率,越大越清晰,但是电脑要崩溃。
for 循环保存图片使用 ‘%s.jpg’%(string)格式设定图片的名称。
font = r"C:\WINDOWS\Fonts\simhei.ttf"
color_mask = imread('./3.jpg')
cloud = wc.WordCloud(scale=16,
font_path=font, # 设置字体
background_color="white", # 背景颜色
max_words=500, # 词云显示的最大词数
mask=color_mask, # 设置背景图片
max_font_size=100, # 字体最大值
width=800,
height=800,
random_state=42)
mywc = cloud.generate(words)
plt.imshow(mywc)
#plt.title(qq,fontsize=20)
#plt.savefig("%d.jpg"%(int(qq)),dpi=300) #save需要在show函数之前,否则保存一张空白图片
mywc.to_file('%s.jpg'%(qq))
plt.show()
四、聊天时间段绘图。从xlsx读取数据,用plt画图
#/usr/bin/env python
# -*- coding:utf-8 -*-
import xlrd
import matplotlib.pyplot as plt
import numpy as np
def fileload(filename = '待读取.xlsx'):
dataset = []
workbook = xlrd.open_workbook(filename)
table = workbook.sheets()[0]
for row in range(table.nrows):
dataset.append(table.row_values(row))
return dataset
filename = './out/1.xlsx'
a = fileload(filename)
x = []
y = []
for i in range(len(a)-1):
x.append(a[i+1][0])
y.append(int(a[i+1][1]))
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
#plt.figure(figsize=(8, 6)) ##指定图像比例: 8:6
plt.subplots_adjust(bottom=0.2)
plt.plot(x, y, color="red", label="times")
plt.xlabel("时间00:00—24:00")
plt.ylabel("发言次数/次")
plt.xticks(range(0, 24), rotation=75, fontsize=15) # 设置横坐标显示24次。
plt.yticks(fontsize=10)
plt.show()