用 Python 分析微信群聊記錄,是怎樣一種體驗?

優質文章,第一時間送達!

用 Python 分析微信群聊記錄,是怎樣一種體驗?

1. 場景

前幾天,有一位小夥伴在後臺給我留言,說自己有幾十個微信群,自己精力有限,沒法看過來,想要篩選一些高質量的群,讓我是否能幫忙想想辦法。

其實,微信群裡的所有聊天記錄都在手機本地文件夾內,只需要導出來進行解密,然後來一波數據分析,就可以幫他篩選出高質量的社群。

本篇文章將帶大家用 Python 一步步來實現這個功能。

2. 實現步驟

第 1 步,導出微信聊天記錄數據庫

首先,我們使用一部 Root 後的手機或者模擬器登錄微信,找到微信聊天記錄數據庫,然後導出到本地。

數據庫文件的完整路徑如下:

<code># 微信聊天記錄數據庫完整路徑
/data/data/com.tencent.mm/MicroMsg/[當前登錄微信的隨機字符串]/EnMicroMsg.db
/<code>

需要注意的是,如果當前設備沒有 Root,可以選擇群聊消息進行一次遷移,然後從 Root 設備或模擬器中導出數據庫。

第 2 步,獲取數據庫的密碼

微信數據庫的密碼組成形式為:手機 IMEI + 微信 UIN,然後 md5 加密(32 位小寫)的前 7 個數字。

其中,手機的 IMEI 可以通過 *#06# 獲取,如果是雙卡手機,需要自己做一下判斷。

用 Python 分析微信群聊記錄,是怎樣一種體驗?

微信的 UIN 在下面配置文件中,找到 name 屬性為 default_uin 的 value 值,即為 UIN

<code># 當前登錄微信的配置文件
/data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml/<code>

最後,然後將 IMET 和 UIN 組成字符串,然後利用 MD5 進行加密,取 32 位小寫的前 7 位即為微信數據庫的密碼。

用 Python 分析微信群聊記錄,是怎樣一種體驗?

第 3 步,破解數據庫

由於微信數據庫是使用 SQLCipher 生成,所以要先安裝 sqlcipher 命令行文件

<code># 安裝sqlcipher命令行(Mac) 

brew install sqlcipher

# Win可以去下載sqlcipher命令行文件
/<code>

然後,輸入數據庫的密碼及解密方式等,導出破解後的數據庫。

用 Python 分析微信群聊記錄,是怎樣一種體驗?

第 4 步,分析數據庫

推薦使用 SQLiteSutdio 打開並分析上面破解後的數據庫,重點查看 message、rcontact、chatroom 這 3 張表。

微信所有的文字聊天記錄都存放在 mesage 數據表中,包含:聊天內容、發送者、消息類型、創建時間等

用 Python 分析微信群聊記錄,是怎樣一種體驗?

rcontact 為微信通訊錄表,包含:微信 ID、暱稱、備註名等

chatroom 是群聊信息表,包含:群聊 ID、成員列表等

第 5 步,Python 打開數據庫並封裝

使用 sqlite3 連接本地數據庫文件,獲取數據庫對象和遊標對象

<code>import sqlite3

def __init__(self, db_path="./weixin.db"):
"""
本地數據庫初始化

"""
self.db = sqlite3.connect(db_path)
self.cursor = self.db.cursor
/<code>

接著,對數據庫常用的操作,包含:增刪改查,進行封裝操作。

<code>def execute(self, sql, param=None):
"""
sql: Sql語句,包含:增、刪、改
param:數據,可以為列表、字典,也可以為空
"""
try:
if param is None:
self.cursor.execute(sql)
else:
if type(param) is list:
self.cursor.executemany(sql, param)
else:
self.cursor.execute(sql, param)
count = self.db.total_changes
self.db.commit
except Exception as e:
print(e)
return False, e

# 返回結果
return True if count > 0 else False

def query(self, sql, param=None):
"""
查詢語句
sql:Sql語句
param:參數,可以包含空
retutn:成功返回True
"""
if param is None:
self.cursor.execute(sql)
else:
self.cursor.execute(sql, param)

# 返回查詢的結果

return self.cursor.fetchall
/<code>

第 6 步,通過群聊名稱獲取群聊 ID

根據群聊暱稱,使用 Sql 語句查詢 rcontact 表,可以獲取群聊的 ID 值

<code>def __get_chartroom_id(self):
"""
獲取群聊的id
:return:
"""
res = self.db.query('select username from rcontact where nickname=?;', (self.chatroom_name,))

# 群聊id
chatroom_id = res[0][0]

return chatroom_id
/<code>

第 7 步,獲取群聊消息

擁有群聊 ID 之後,緊接著查詢 message 表,獲取當前群聊的所有消息內容。

<code># message表:聊天記錄表
# isSend=0:對方發送的;isSend=1:自己發送的
sql = "SELECT content FROM message WHERE talker='{}' and isSend=0".format(chatroom_id)

# 查詢表,獲取所有的聊天記錄
result = self.db.query(sql)
/<code>

為了獲取有效的消息內容,可以清洗掉自己發送的消息、系統消息、紅包消息等內容

<code># 循環查詢到的所有的消息 

for item in result:
# 過濾數據
if not item or not item[0] or item[0].find('xml') != -1 or item[0].find('sysmsg') != -1 or item[0].find(
'') != -1 or item[0].find('chatroom') != -1 or item[0].find('weixinhongbao') != -1:
continue
# 過濾掉自己發送的內容,不包含:
temps = item[0].split(':')
if len(temps) < 2:
# print('自己發送的內容:' + item[0])
continue
# 每一條聊天記錄,過濾掉髮送者,只保留消息正文
# 發送者
send_from = item[0].split(':')[0]

# 發送內容
send_msg = "".join(item[0].split(':')[1:]).strip.replace(""", "")
# 過長的消息,也過濾掉
if len(send_msg) > 200:
continue
/<code>

對於群其他成員發送的內容,再過濾掉消息內容的前半部分,只保留消息正文

用 Python 分析微信群聊記錄,是怎樣一種體驗?

第 8 步,生成詞雲

使用 jieba 對群內有效的消息進行分詞,然後使用 wordcloud 生成詞雲圖。

<code>def generate_wordcloud(self, word):
"""
生成詞雲
:param word:
:return:
"""

img = WordCloud(font_path="./DroidSansFallbackFull.ttf", width=2000, height=2000,
margin=2, collocations=False).generate(word)
plt.imshow(img)
plt.axis("off")
plt.show

# 保存圖片
img.to_file("{}.png".format("群聊"))

# 分詞
temp = " ".join(jieba.cut(words, cut_all=True))

# 生成詞雲
generate_wordcloud(temp)
/<code>

第 9 步,新建排名表,插入數據

為了統計群聊活躍度排名,我們需要新建一張表,包含:id、微信暱稱、消息內容 3 個字段。

<code>def __create_top_table(self):
"""
創建Top表
:return:
"""
# 創建Top表,如果存在就不重新創建
result = self.db.execute(
"CREATE TABLE IF NOT EXISTS top(uid integer primary key,name varchar(200),msg varchar(200))")

/<code>

接著,將上一步的每一條消息中的發送者 ID、發送內容 2 個字段插入到新建的 Top 表內

<code># 定義一個列表,加入所有要統計的數據
msg_pre =

for item in result:
# 發送者
send_from = item[0].split(':')[0]
# 發送內容
send_msg = "".join(item[0].split(':')[1:]).strip.replace(""", "")
msg_pre.append((send_from, send_msg))

# 把要統計的數據,插入到top表中
self.db.execute("insert into top(uid,name,msg) values (,?,?);", msg_pre)
/<code>

第 10 步,獲取活躍度排名並可視化

從 Top 數據表中,通過微信暱稱查詢出每一位成員發言的次數,並保存到一個列表中

<code>def get_top_partner(self):
"""
排名前15的成員
:return:
"""
sql = "SELECT name as 姓名,COUNT(*) as times FROM top GROUP BY name ORDER BY times DESC limit %d;" % self.top_num
result = self.db.query(sql)

for item in result:
# 用戶id
id = item[0]
# 發言次數
count = item[1]

# 獲取用戶的暱稱,即:微信暱稱

username = self.get_username(id)

self.top_data.append({
'username': username,
'count': count
})
/<code>

最後,去除微信暱稱的特殊符號,使用 pyecharts 將數據可視化。

<code>def draw_image(self):
"""
數據可視化
:return:
"""
usernames =
counts =
for user in self.top_data:
# 去除暱稱中的特殊符號
usernames.append(get_ava_string(user.get('username').strip)[0:8])
counts.append(user.get('count'))

def bar_chart -> Bar:
c = (
Bar
.add_xaxis(usernames)
.add_yaxis("活躍度", counts)
.reversal_axis
.set_series_opts(label_opts=opts.LabelOpts(position="right"))
.set_global_opts(title_opts=opts.TitleOpts(title="最活躍的%d個小夥伴" % self.top_num))
)
return c

# 需要安裝 snapshot-selenium 或者 snapshot-phantomjs
make_snapshot(driver, bar_chart.render, "bar.png")/<code>

3. 最後

上面的操作,通過生成的詞雲瞭解到當前群聊過去一段時間都在聊的話題及價值,通過對聊天記錄的數據分析,獲取到微信群聊活躍度排名。

用 Python 分析微信群聊記錄,是怎樣一種體驗?

當然,也可以分析群成員潛水排名及某一位群成員的數據分析。

我已經將全部源碼上傳到後臺,關注公眾號後回覆「 微信群聊」即可獲得全部源碼。

回覆下方「關鍵詞」,獲取優質資源


回覆關鍵詞「

pybook03」,立即獲取主頁君與小夥伴一起翻譯的《Think Python 2e》電子版

回覆關鍵詞「入門資料」,立即獲取主頁君整理的 10 本 Python 入門書的電子版

回覆關鍵詞「m」,立即獲取Python精選優質文章合集

回覆關鍵詞「」,將數字替換成 0 及以上數字,有驚喜好禮哦~


題圖:pexels,CC0 授權。

用 Python 分析微信群聊記錄,是怎樣一種體驗?

好文章,我在看❤️


分享到:


相關文章: