写在最前:某天和女朋友聊天,我说,我觉得你和我在一起这么久,性格变了不少,从微信聊天记录应该可以反映出来,于是疑问产生了——微信聊天记录怎样才能在PC端查看呢?
项目开源地址:Github
需要准备的工具:已root的安卓手机,RE文件管理器,wxsqlcipher.exe(用于解密数据库),python 3.5及相关库(jieba,wordcloud)
效果图如下:
在手机上使用RE文件管理器进入目录“/data/data/com.tencent.mm/Micromsg”,可以发现若干和和账户关联的形如20位+长度的文件夹,在其中一个可以找到文件EnMicromsg.db,这就是微信储存聊天记录的数据库文件,将其拷贝至容易访问的文件,进而传输至PC端。
手机的IMEI码,在拨号界面输入*#06#,可以查看本机的IMEI码,对于双卡手机会得到2-3个,全部记录下来
微信的uin码,可以通过RE文件管理器访问“/data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml”查看。
也可以通过网页抓包的方式——
2.1、登录微信网页版(推荐使用chrome浏览器)
2.2、开始chrome浏览器内置的抓包模式,即在新建的标签页地址栏中输入:chrome://net-internals/#events
2.3、在微信中进行一些聊天操作,然后在浏览器的层级上搜索(ctrl+f)“uin”,不出意外可以搜到一个9位的uin码,这个就是你微信号对应的uin码
解密:
将IMEI和UIN码拼接在一起(长度增加)后,使用MD5算法加密(md5在线加密),选择32位小写的加密方式截取前7位,即为数据库密码。
使用wxsqlcipher.exe打开EnMicromsg.db文件,提示需要密码,输入上述获得的密码,可以查看数据库中文件。
我们选择table为“message”的信息,加载需要一定时间,即可以查看到本机本账号储存的所有微信聊天记录,而后我们有两种处理方式,一是用内部的sql语句导出内容,经测试效率较低。
二是导出为csv文件,利用python的csv模块来处理,这里我们选择方案二,File---export---csv file
我们要使用csv模块中DictReader的功能。代码直接放在下方,参考注释修改特征信息:
import csv
import time
import re
def write_sorted_chathistory():
chat_txtfile = open(r'C:\Users\ctrl\Desktop\chat_tk.txt', 'w', encoding='gb18030') # 打开待写入的txt文件
count = 0 # 记录进度
chathistory_dict = {}
with open(r'C:\Users\ctrl\Desktop\chathistory.csv', 'r', encoding='gb18030') as f: # 打开写有聊天记录的csv文件
reader = csv.DictReader(f)
for row in reader:
newlist = []
if row['talker'] == 'tiankun_007' and row['imgPath'] == '' and 'content' not in row['content']: # talker为微信ID,imgPath去掉图片信息(乱码)
if row['isSend'] == '1': # 信息为我方发出
time_str = str(time.gmtime(int(row['createTime']) / 10e2 + 36000)) # 对UNIX时间戳的处理
match_list = re.findall('=(\d+)', time_str)
for i in match_list:
if len(i) == 1:
newlist.append('0' + i)
else:
newlist.append(i)
time_standard = '{0}-{1}-{2} {3}:{4}:{5}'.format(newlist[0], newlist[1], newlist[2], newlist[3],
newlist[4], newlist[5]) # 通过正则表达式转换为方便观看的时间
chathistory_dict[row['createTime']] = time_standard + ' 园小方:' + row['content'] + '\n' # 写入文档
else: # 信息为对方发出
time_str = str(time.gmtime(int(row['createTime']) / 10e2 + 36000))
match_list = re.findall('=(\d+)', time_str)
for i in match_list:
if len(i) == 1:
newlist.append('0' + i)
else:
newlist.append(i)
time_standard = '{0}-{1}-{2} {3}:{4}:{5}'.format(newlist[0], newlist[1], newlist[2], newlist[3],
newlist[4], newlist[5])
chathistory_dict[row['createTime']] = time_standard + ' 古叶田:' + row['content'] + '\n'
count += 1
print(count)
chat_history = sorted(chathistory_dict.values()) # 使用字典来写入是为了防止时间乱序
for i in chat_history:
chat_txtfile.write(i)
write_sorted_chathistory() # 执行代码
至此,我们已经将文件以比较漂亮的形式写入了txt文档并可以留存。下面进行词频分析及词云绘制。
首先使用jieba库来进行分词(有的日常用语词库未包含,但可以自行添加进入字典,具体方式可以查看jieba的文档),并统计词频,生成词频字典。
然后根据底图或者默认的正方形,绘制专属的词云图~代码如下:
import jieba.analyse
import string
filename = r'C:\Users\ctrl\Desktop\chat_tk' # 读取txt文件路径
# 此模块用于分析文件中的字频,输出结果形如 词语 --- 权重频次
def AnalyzeData():
f = open(filename + '.txt', 'r', encoding='gb18030')
fcontent = f.read()
alpha = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM' # 去除非中文部分
tags = jieba.analyse.extract_tags(fcontent, topK=250, withWeight=True)
new_tags = {}
for k in range(len(tags)):
uchar = tags[k][0][0]
if uchar not in alpha:
new_tags[tags[k][0]]= int(tags[k][1]*10000)
# 将词频-词语保存为文件,注意格式化对齐的方式
with open(filename + '_Word.txt', 'w') as f:
for i, j in tags:
if i[0] not in alpha:
f.write('{:15}\t{:15}'.format(i,int(j*10000))+'\n')
# print('{:8}\t{:10}'.format(i,int(j*10000)))
f.close()
# 返回字典为wordcloud提供依据
return new_tags
from wordcloud import WordCloud
from scipy.misc import imread
import wordcloud
def cloudplot():
# 设置模板图像的路径
target_coloring = imread(r'C:\Users\ctrl\Desktop\heart.jpg')
# 以词频和背景模板为依据生成词云对象
word_cloud = WordCloud(font_path = r'C:\Windows\Fonts\simhei.ttf',
background_color="white",max_words=2000,mask=target_coloring).generate_from_frequencies(AnalyzeData())
# 生成颜色分布
image_color = wordcloud.ImageColorGenerator(target_coloring)
# image_color =
import matplotlib.pyplot as plt
# 仅按照词频、边界、默认颜色生成词云图像
plt.imshow(word_cloud)
plt.axis("off")
plt.figure()
# 重新上色,按照图像色彩分布生成
plt.imshow(word_cloud.recolor(color_func=image_color))
plt.axis("off")
plt.figure()
# 绘制原始图像
plt.imshow(target_coloring,cmap=plt.cm.gray)
plt.axis("off")
plt.show()
word_cloud.to_file(filename+'.png')
cloudplot()
到这里,我们的工作已经做完了。