0. 前言

​ 之所以想要提取微信的聊天记录并分析是因为也开始再学习python,但是单纯看看语法什么的又很无趣,无意间看到python可以进行微信聊天记录的分析,就自己尝试做了一下,感觉还是挺有意思的。

1.提取聊天记录数据库

​ 我所用的是小米手机,所以提取聊天记录是主要是通过本地备份功能,其余手机也可参考下述博客,具体流程可参考:

微信聊天记录导出(2020新版)

安卓\电脑微信聊天记录导出表格

微信聊天记录数据提取并分析

利用python做微信聊天记录词云分析

提取微信数据库的主体流程都差不多,基本都是先进行备份,然后将备份文件复制到电脑进行解压,解压完成之后根据得到的数据库密码访问数据库。提取数据库的过程基本上都不会有什么问题,主要会出现的问题在于获取微信数据库密码。我开始使用的是手机IMEI + uin拼接取其32位MD5码前7位的方式,但是因为我手机上有两个IMEI码,尝试了各种组合获得的密码始终是错误的,所以就放弃采用这种方式,但是根据其他博客中的内容,这种方式也可以获取数据库密码。

​ 我最终采用的是反序列化的方式获取数据库密码,即将微信com.tencent.mm\r\MicroMsg\systemInfo.cfg和com.tencent.mm\r\MicroMsg\CompatibleInfo.cfg这两个文件复制出来,通过参考代码获取数据库密码。开始直接在命令行通过javac编译并运行,如下所示


javac IMEI.java
java IMEI systemInfo.cfg CompatibleInfo.cfg

​ 但是直接在命令行中运行会报 “错误: 找不到或无法加载主类 IMEI 原因: java.lang.ClassNotFoundException: IMEI”,但是将代码放在IDEA中可以运行并得到最终数据库密码,代码如下:

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.security.MessageDigest;
import java.util.HashMap;public class IMEI {public static void main(String[] args) {// systemInfo.cfg存储路径,修改为电脑中存储位置String systemInfo_path = "D:\\wechet-anayze\\systemInfo.cfg";// compatibleInfo.cfg存储路径,修改为电脑中存储位置String compatibleInfo_path1 = "D:\\wechet-anayze\\CompatibleInfo.cfg";try {ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));Object DL = in.readObject();HashMap hashWithOutFormat = (HashMap) DL;ObjectInputStream in1 = new ObjectInputStream(new FileInputStream(path1));Object DJ = in1.readObject();HashMap hashWithOutFormat1 = (HashMap) DJ;String s = String.valueOf(hashWithOutFormat1.get(Integer.valueOf(258))); // 取手机的IMEIs = s + hashWithOutFormat.get(Integer.valueOf(1)); //合并到一个字符串s = encode(s); // hashSystem.out.println("The Key is : " + s.substring(0, 7));in.close();in1.close();} catch (Exception e) {e.printStackTrace();}}public static String encode(String content) {try {MessageDigest digest = MessageDigest.getInstance("MD5");digest.update(content.getBytes());return getEncode32(digest);} catch (Exception e) {e.printStackTrace();}return null;}private static String getEncode32(MessageDigest digest) {StringBuilder builder = new StringBuilder();for (byte b : digest.digest()) {builder.append(Integer.toHexString((b >> 4) & 0xf));builder.append(Integer.toHexString(b & 0xf));}return builder.toString();}
}

​ 微信数据库及数据库密码获取完成之后就可以通过sqlcipher(官方下载地址)软件访问数据库中内容,查看具体的聊天信息等,我在后续处理中主要用到了messagecontact表,message表中记录了所发送的所有消息信息,contact表中记录了所有的联系人信息,message表中主要使用到的内容如下:

message表主要内容

列名 内容
msgId 按所有消息时间顺序的唯一编号
type 聊天内容类型
isSend 标识消息是自己发送还是对方发送,1表示自己,0表示对方
createTime 聊天时间
talker 单聊的wxid或群聊编号"XXXX@chatroom"
content 聊天内容,单聊直接显示内容,群聊格式为“wxid:\n”内容

​ 因为也挺想知道和其他人的聊天类型,所以就也根据message表中的type值结合createTime查找具体的聊天信息,从而对type类型做了如下分类,

type类型信息

type值 表示内容
1 文本内容
2 位置信息
3 图片及视频
34 语音消息
42 名片(公众号名片)
43 图片及视频
47 表情包
48 定位信息
49 小程序链接
10000 撤回消息提醒(XXXX撤回了一条消息)
1048625 照片
16777265 链接
285212721 文件
419430449 微信转账
436207665 微信红包
469762097 微信红包
·11879048186 位置共享
(还有未知type信息,待补充)

contact表主要内容

列名 含义
username 微信id,格式是"wxid_xxxxxxxx"或者一看就是自己设置的
alias 自己设置的那个可以通过查找加好友的微信名(和上面那个有的有区别有的为空)
conRemark 联系人备注名
nickname 微信名片上的名字,公众号的名字
contactLabelIds 联系人标签号

2.数据预处理

2.1 message表和contact表获取

​ 获取到微信数据库及数据库密码后,可通过sqlciper软件查看数据库中内容,同时也可将所需的数据导出,可通过file/Export/Table as CSV file选项,选择需要导出的数据表,将之存储为CSV文件。

这里需要注意一下:

​ 如果在python中直接读取导出的csv文件夹,python中会报错,大致是因为编码错误。其余博客中有提到使用excel打开导出的csv文件,然后以utf-8格式另存,最后读取另存后的文件,通过试验这种方法可以进行读取,但是因为csv文件用excel打开时超过16位的数字将会被强制使用科学计数法表示,所以message表中的createTime会被使用科学计数法表示,另存后的文件中creatTime时间精度会损失,所以我最终采用了一个简单粗暴的方法:用记事本打开csv文件,然后以utf-8的形式另存,在python中就可以正常读取了。(话说用记事本打开要比用excel打开快好多倍)

2.2 message表预处理

​ 因为message表中和contact表中含有大量数据分析时不用的数据列,所以在数据预处理阶段中,只需要提取message表和contact表中我们所关注的一些数据。对于message表而言,我们只关注talker,createTime,type, isSend, content所表示的内容,也即聊天对象,聊天时间,消息类型,消息由谁发送,聊天内容。更近一步,对于聊天内容而言,我们只关注文本消息(文本消息可用于后续制作词云),对于其他类型的消息我们只需要统计出现的次数,而不必关注具体内容。所以在预处理过程中,同时需要将非文本类型消息内容置0,这样做的另一个好处是可以大大减少message表的数据量,就个人而言,将非文本消息置零后,message文件大小由134MB缩小到29M。

提取talker,createTime,type, isSend, content内容

"""
Create on 2020-11-21
@author: muxiaohe
"""
# 对message表中内容进行处理,只留下所需的type, isSend, createTime, talker, content内容,并将之存储于新的文件中
def get_needed_data(file_path, save_file_path):message = read_file(file_path)message = message[['type', 'isSend', 'createTime', 'talker', 'content']]message.to_csv(save_file_path, encoding='utf_8_sig',header=True, index=False)

将非文本消息置零

"""
Create on 2020-11-21
@author: muxiaohe
"""
# 对message表中数据进行处理,,删除content中的无用数据,将type中非1值对应的content数据统统置为零
def data_clean(file_path, save_path):message = pd.read_csv(file_path, sep=',', encoding='utf-8', low_memory=False)print("源文件大小: ", message.shape)message.loc[message.type != 1, 'content'] = 0print("处理后文件大小: ", message.shape)message.to_csv(save_path, encoding='utf_8_sig', header=True, index=False)

2.3 contact表预处理

​ 与message表类似,contact表也需去除无关数据,contact表中我们只提取 usename, alias, conRemark, nickname信息,同时在处理时只保留了有备注的联系人,没有备注的联系人也没必要分析聊天记录。

"""
Create on 2020-11-21
@author: muxiaohe
"""
# 对contact表中数据进行预处理,获取所需数据,清除其余数据
def contact_pre_treatment(file_path, save_path):contact_path = r"D:\wechet-anayze\recontact.txt"contact_save_path = r"D:\wechet-anayze\pre-recontact.csv"contact = pd.read_csv(contact_path, sep=',', encoding="utf-8", low_memory=False)print("处理前文件大小: ", contact.shape)contact = contact[['username', 'alias', 'conRemark', 'nickname']]# 删除无用记录,只保留有备注的联系人contact1 = contact.drop(contact[pd.isna(contact.conRemark)].index)print("处理后文件大小: ", contact.shape)contact1.to_csv(contact_save_path, encoding='utf_8_sig', header=True, index=False)

3.聊天记录分析

3.1 获取常用联系人聊天次数

​ 在预处理的基础之上,获取每个联系人的聊天次数,并据此使用pyecharts绘制柱状图,使用pyecharts绘制时需特别注意:pyecharts传入数据时需要int数据,而从文件中读取赋值到list中的数值类型为int64,需要先使用int()函数进行转换,否则绘制出来的图形中data数据域将都为NaN

"""
Create on 2020-11-21
@author: muxiaohe
"""
# 获取常用联系人聊天次数
def get_chat_nums(message_path, contact_path):""":param message_path: 预处理完成后的message表存储路径:param contact_path: 预处理完成后的contact表存储路径:return:"""# message_path = r'D:\wechet-anayze\pre-message-2.txt'# contact_path = r'D:\wechet-anayze\pre-recontact.csv'message = pd.read_csv(message_path, sep=',', encoding='utf-8', low_memory=False)contact = pd.read_csv(contact_path, sep=',', encoding='utf-8', low_memory=False)# 提取出联系人列表中用户名和备注名称contact = contact[['username', 'conRemark']]# 将用户名提取出来username = contact['username'].tolist()print(type(username))# 将用户名及备注名提取为一个字典contact_dict = dict(zip(contact['username'], contact['conRemark']))# 联系人及其聊天次数集合contact_sum_message = {}# 全部联系人聊天次数集合sum_message = 0# 联系人列表uname_list = []# 联系人列表对应的聊天次数列表chat_num_list = []# 遍历联系人列表,并逐一统计聊天次数for uname in username:# 根据微信id获取真实姓名,key为真实姓名key = contact_dict.get(uname)# 根据微信id统计聊天次数,value:聊天次数value = (message['talker'] == uname).sum()# 过滤聊天次数为0的联系人,只保留聊天次数不为0的联系人if value != 0:contact_sum_message[key] = valuesum_message += valueuname_list.append(key)# 这里需特别注意:value值也即聊天的次数格式是int64,但是pyecharts中如果传入的是int64时,最终渲染出的html文件中会数据会丢失,# 所以需转为int值(血泪教训)chat_num_list.append(int(value))# print(contact_sum_message)print("总聊天次数: ", sum_message)# 使用pyecharts绘制柱状图c = (Bar(init_opts=opts.InitOpts(width="1600px", height="600px", page_title="聊天次数统计")).add_xaxis(uname_list).add_yaxis(series_name="聊天次数", y_axis=chat_num_list, color='#FF6666').set_global_opts(# 标题配置title_opts=opts.TitleOpts(title="聊天次数统计"),# X轴区域缩放配置项,可使用list同时配置多个配置项datazoom_opts=[opts.DataZoomOpts(range_start=20, range_end=40), opts.DataZoomOpts(type_="inside")],# 区域选择组件brush_opts=opts.BrushOpts(),# X坐标轴旋转xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),# 工具箱组件toolbox_opts=opts.ToolboxOpts(),# 图例配置legend_opts=opts.LegendOpts(is_show=False),).set_series_opts(label_opts=opts.LabelOpts(is_show=False),# 配置最大值最小值刻度线markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="min", name="最小值"),opts.MarkLineItem(type_="max", name="最大值"),opts.MarkLineItem(type_="average", name="平均值"),]),).render("chat_num_count.html"))

3.2 获取聊天消息中不同类型消息占比

"""
Create on 2020-11-21
@author: muxiaohe
"""
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Pie
# 获取各个消息聊天记录数量,并使用pycharts绘图
def get_message_type_frequency(file_path, wxid):""":param file_path: 经过预处理后的message表存储位置:param wxid: 待查询人的微信id:return:"""# file_path = r'D:\wechet-anayze\pre-message-2.txt'message = pd.read_csv(file_path, sep=',', encoding='utf-8', low_memory=False)# wxid = ''# 进行数据筛选,选择message表中与所需微信id一致的数据message = message[message['talker'] == wxid]# 根据消息类型统计每种类型的频次(索引为数字编码)chat_type_count = message['type'].groupby(message['type']).size()# 消息类型对应关系message_type = {'1': '文本内容', "3": "图片及视频", "34": "语音消息", "42": "名片信息", "43": "图片及视频","47": "表情包", "48": "定位信息", "49": "小程序链接", "10000": "消息撤回提醒", "1048625": "网络照片","16777265": "链接信息", "419430449": "微信转账", "436207665": "红包", "469762097": "红包","-1879048186": "位置共享"}# 集合对象,功能与chat_type_count相同,存储(聊天类型:频次)信息(索引为对应中文类型)chat_type_count_dict = {}# 根据消息类型代码for key in chat_type_count.index:if str(key) in message_type.keys():print(message_type.get(str(key)))chat_type_count_dict[message_type.get(str(key))] = chat_type_count[key]else:chat_type_count_dict[key] = chat_type_count[key]print("结果集类型: ", type(chat_type_count_dict))print(chat_type_count_dict)x_data = []y_data = []for key in chat_type_count_dict:temp = [str(key), chat_type_count_dict.get(key)]x_data.append(str(key))y_data.append(int(chat_type_count_dict.get(key)))a1 = []for z in zip(x_data, y_data):a1.append(z)pie = Pie(init_opts=opts.InitOpts(width="1600px", height="600px", page_title="消息类型统计"))pie.add("",data_pair=a1,center=["35%", "60%"],)pie.set_global_opts(title_opts=opts.TitleOpts(title="Pie-调整位置"),legend_opts=opts.LegendOpts(pos_left="15%"),)pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}"))pie.render("message_type_count.html")

3.3 聊天记录词云

​ 可选择具体的聊天对象,获取全部的聊天内容,代码中可以chinese_slice选择是否进行分词,如果不进行分词则将全部聊天内容拼接到一起,通过wordcloud模块生成词云,如果选择分词则会调用jiebe模块先进行分词,然后再通过wordcloud模块生成词云。

"""
Create on 2020-11-21
@author: muxiaohe
"""
import imageio
import jieba
import pandas as pd
import matplotlib.pyplot as plt
import wordcloud
# 根据聊天记录生成词云
def get_wordcloud(file_path, stopword_path, wxid, image_path):""":param file_path: 预处理完成后的message表存储位置:param stopword_path: 停用词文件存储位置:param wxid: 待查询人微信id:return:"""# 分词及词云处理# message_path = r'D:/wechet-anayze/pre-message-2.txt'# stopword_path = r'D:/wechet-anayze/stopword.txt'# 文件读取message = pd.read_csv(file_path, sep=',', encoding='utf-8', low_memory=False)# 数据筛选,选择对应微信id的信息message = message[message['talker'] == wxid]# 提取聊天内容信息content = message['content']# 中文字型存储路径font_path = r'C:\Windows\Fonts\MSYH.TTC'# 是否选用分词wordcut_flag = True# 词云图片输出路径image_out_name = 'word-heart.png'# 读取停用词表stopwords = [line.strip() for line in open(stopword_path, encoding='UTF-8').readlines()]if image_out_name is None:image_out_name = 'word-heart.png'if wordcut_flag:print("进行中文分词")outstr = ""text = ",".join(content)text_list = jieba.lcut(text, cut_all=False)for word in text_list:if word not in stopwords:if word != '\t' and '\n':outstr += wordoutstr += " "# 如果想存储分词后结果,可取消下方注释# savepath = r'D:/wechet-anayze/textlist.txt'# fp = open(savepath, 'w', encoding='utf8', errors='ignore')# fp.write(outstr)# fp.close()text = outstrelse:print("不进行中文分词")text = " ".join(content)# 词云形状图片位置mk = imageio.imread(image_path)# 构建并配置词云对象w,注意要加scale参数,提高清晰度w = wordcloud.WordCloud(width=1000,height=700,background_color='white',font_path=font_path,mask=mk,scale=2,stopwords=None,contour_width=1,contour_color='red')# 将string变量传入w的generate()方法,给词云输入文字w.generate(text)# 展示图片# 根据原始背景图片的色调进行上色image_colors = wordcloud.ImageColorGenerator(mk)plt.imshow(w.recolor(color_func=image_colors))# 根据原始黑白色调进行上色# plt.imshow(wc.recolor(color_func=grey_color_func, random_state=3), interpolation='bilinear') #生成黑白词云图# 根据函数原始设置进行上色# plt.imshow(wc)# 隐藏图像坐标轴plt.axis("off")plt.show()# 将词云图片导出到当前文件夹w.to_file(image_out_name)

有兴趣的话可以参考我的GitHub地址,里边有所需的全部文件及代码,有帮到的请给star呀~

微信聊天记录提取及分析

微信聊天记录提取及分析(wordcloud+pyecharts)相关推荐

  1. 利用python做微信聊天记录词云分析——记录美好回忆

    目录 1 概述 2 数据准备 2.1 安卓设备 2.1.1 Root手机,安装Root Explorer 2.1.2 用Root Explorer将聊天记录的数据文件导出并存入电脑 2.1.3 对En ...

  2. 微信聊天记录词云分析

    步骤 - 获取对象聊天记录加密数据 - 解码 - 对csv数据进行筛选 -词云分析 获取微信聊天记录加密数据 安卓手机获取微信导出微信聊天记录需要先获取root权限,这个风险比较大,而且我这个手机比较 ...

  3. 微信聊天记录数据提取并分析

    项目背景: 公司有一部手机,这个手机专门用微信群拉客户的.手机里微信群聊天记录很多,想把这些聊天记录提取出来分析一下有用的信息. 查找一下 首先看一下有没有人之前做个这个项目,如果有的话就不用浪费时间 ...

  4. 微信聊天记录的词云制作

    微信聊天记录的词云制作 需求 导出微信聊天记录 提取文字聊天记录 生成词云 需求 想把跟朋友的微信聊天记录做个词云 导出微信聊天记录 我的手机是iphone,用旧版的itunes备份手机全部信息 it ...

  5. 520小玩意之Python词云:导出与女票的微信聊天记录并分析

    用python看看自己和女票都聊了些什么事 最终效果图: 一.导出微信聊天文件 写2种导出聊天记录的方法:一种是Mac版微信,另一种是iOS版微信. 1.导出Mac版微信聊天记录 Mac版微信在本地存 ...

  6. python通过微信聊天记录分析_Python利用itchat对微信中好友数据实现简单分析的方法...

    前言 最近在一个微信公众号上看到一个调用微信 API 可以对微信好友进行简单数据分析的一个包 itchat 感觉挺好用的,就简单尝试了一下. 库文档说明链接在这: itchat 安装 在终端中输入以下 ...

  7. WX Backup - 免费微信聊天记录备份导出与查看工具 (可提取图片/视频/语音)

    微信绝对是一个让人爱恨交织的 APP,它在国内几乎完全占据了人们的社交以及生活的方方面面,但腾讯却并没有为微信提供好用的「聊天记录」备份导出和查看的功能. WX Backup 是一款完全免费的微信聊天 ...

  8. 微信聊天记录深度分析,看看这一年你和谁最亲密

    原文链接: https://zhuanlan.zhihu.com/p/100084316 2019年就要过去了,想知道你平时用的最多的词是什么吗?想知道你一天中哪个时间段聊天最多吗?想知道这一年谁和你 ...

  9. chatgpt赋能python:Python微信聊天记录:如何导出并分析聊天记录

    Python 微信聊天记录:如何导出并分析聊天记录 微信是目前最受欢迎的聊天工具之一,但是它的聊天记录并不方便导出和分析.本文将介绍如何使用 Python 导出微信聊天记录,并进行分析. 导出微信聊天 ...

最新文章

  1. C#解析XML各种方法特点比较(转载)
  2. 公子龙:我读研期间通过实习和比赛收入五十万
  3. ksql 数量大于2_A股史上唯一能暴涨200%的买卖铁则:内盘大于外盘股价必跌,外盘大于内盘股价必涨,堪称绝技...
  4. 【全记录】2017云栖大会·北京峰会——企业云上业务优化专场
  5. 变压器 5g_T5:文本到文本传输变压器
  6. 【英语学习】【Level 07】U01 Making friends L2 A new friend from the past
  7. Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(6) - 逻辑指令 比较指令
  8. FusionCharts参数说明——3D饼图属性(Pie3D.swf )
  9. unity 是厘米还是米_做工扎实,可玩性强,类乐高产品的好选择,米兔积木工程吊车...
  10. 记录一下免费域名和空间
  11. 转:神奇的Fastcgi_Finish_Request
  12. 用于语音识别的数据增强
  13. 【Leetcode 795】Number of Subarrays with Bounded Maximum
  14. 论文笔记_S2D.31_2015-CVPR_对单张图像进行统一的深度和语义预测
  15. 计算机考试九九乘法表,多种办法用EXCEL软件生成99乘法表
  16. php pager,fleaphp常用方法分页之Pager使用方法
  17. BCD码与十进制转换
  18. 串口连接BBB(三)
  19. Php区分自然量跟aso量,ASO优化——判断下载量与评论的比例关系
  20. C++ uint8_t

热门文章

  1. css层叠样式表基础学习笔记--第五章 文本属性
  2. 什么条件下犬才作近亲繁殖?
  3. Discuz 论坛设置发帖最大字数
  4. 如何做目录——目录的生成?
  5. android 翻转imageview,如何在Android中翻转ImageView?
  6. Java intern函数详解
  7. 闪存浪潮下不得不知的知识(1)-厂商篇
  8. 为自己的位置设定好灯光
  9. 如何成功,与各位共勉之
  10. 汇编两个十进制数相乘,以二进制和十六进制分别输出