自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 后端
前幾天,有一位小伙伴在后臺給我留言,說自己有幾十個微信群,自己精力有限,沒法看過來,想要篩選一些高質(zhì)量的群,讓我是否能幫忙想想辦法。

 1. 場景

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

[[322556]]

其實,微信群里的所有聊天記錄都在手機本地文件夾內(nèi),只需要導(dǎo)出來進行解密,然后來一波數(shù)據(jù)分析,就可以幫他篩選出高質(zhì)量的社群。

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

2. 實現(xiàn)步驟

第 1 步,導(dǎo)出微信聊天記錄數(shù)據(jù)庫

首先,我們使用一部 Root 后的手機或者模擬器登錄微信,找到微信聊天記錄數(shù)據(jù)庫,然后導(dǎo)出到本地。

數(shù)據(jù)庫文件的完整路徑如下:

 

  1. # 微信聊天記錄數(shù)據(jù)庫完整路徑 
  2. /data/data/com.tencent.mm/MicroMsg/[當(dāng)前登錄微信的隨機字符串]/EnMicroMsg.db 

需要注意的是,如果當(dāng)前設(shè)備沒有 Root,可以選擇群聊消息進行一次遷移,然后從 Root 設(shè)備或模擬器中導(dǎo)出數(shù)據(jù)庫。

第 2 步,獲取數(shù)據(jù)庫的密碼

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

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

 

 

 

 

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

 

  1. # 當(dāng)前登錄微信的配置文件 
  2. /data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml 

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

 

 

 

 

第 3 步,破解數(shù)據(jù)庫

由于微信數(shù)據(jù)庫是使用 SQLCipher 生成,所以要先安裝 sqlcipher 命令行文件

 

  1. # 安裝sqlcipher命令行(Mac) 
  2. brew install sqlcipher 
  3.  
  4. # Win可以去下載sqlcipher命令行文件 

然后,輸入數(shù)據(jù)庫的密碼及解密方式等,導(dǎo)出破解后的數(shù)據(jù)庫。

 

 

 

 

第 4 步,分析數(shù)據(jù)庫

推薦使用 SQLiteSutdio 打開并分析上面破解后的數(shù)據(jù)庫,重點查看 message、rcontact、chatroom 這 3 張表。

微信所有的文字聊天記錄都存放在 mesage 數(shù)據(jù)表中,包含:聊天內(nèi)容、發(fā)送者、消息類型、創(chuàng)建時間等

 

 

 

 

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

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

第 5 步,Python 打開數(shù)據(jù)庫并封裝

使用 sqlite3 連接本地數(shù)據(jù)庫文件,獲取數(shù)據(jù)庫對象和游標(biāo)對象

 

  1. import sqlite3 
  2.  
  3. def __init__(self, db_path="./weixin.db"): 
  4.     ""
  5.     本地數(shù)據(jù)庫初始化 
  6.     ""
  7.     self.db = sqlite3.connect(db_path) 
  8.     self.cursor = self.db.cursor() 

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

 

  1. def execute(self, sql, param=None): 
  2.     ""
  3.     sql: Sql語句,包含:增、刪、改 
  4.     param:數(shù)據(jù),可以為列表、字典,也可以為空 
  5.     ""
  6.     try: 
  7.         if param is None: 
  8.             self.cursor.execute(sql) 
  9.         else
  10.             if type(param) is list: 
  11.                 self.cursor.executemany(sql, param) 
  12.             else
  13.                 self.cursor.execute(sql, param) 
  14.             count = self.db.total_changes 
  15.             self.db.commit() 
  16.     except Exception as e: 
  17.         print(e) 
  18.         return False, e 
  19.  
  20.     # 返回結(jié)果 
  21.     return True if count > 0 else False 
  22.  
  23. def query(self, sql, param=None): 
  24.     ""
  25.     查詢語句 
  26.     sql:Sql語句 
  27.     param:參數(shù),可以包含空 
  28.     retutn:成功返回True 
  29.     ""
  30.     if param is None: 
  31.         self.cursor.execute(sql) 
  32.     else
  33.         self.cursor.execute(sql, param) 
  34.  
  35.     # 返回查詢的結(jié)果 
  36.     return self.cursor.fetchall() 

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

根據(jù)群聊昵稱,使用 Sql 語句查詢 rcontact 表,可以獲取群聊的 ID 值

 

  1. def __get_chartroom_id(self): 
  2.     ""
  3.     獲取群聊的id 
  4.     :return
  5.     ""
  6.     res = self.db.query('select username from rcontact where nickname=?;', (self.chatroom_name,)) 
  7.  
  8.     # 群聊id 
  9.     chatroom_id = res[0][0] 
  10.  
  11.     return chatroom_id 

第 7 步,獲取群聊消息

擁有群聊 ID 之后,緊接著查詢 message 表,獲取當(dāng)前群聊的所有消息內(nèi)容。

 

  1. # message表:聊天記錄表 
  2. # isSend=0:對方發(fā)送的;isSend=1:自己發(fā)送的 
  3. sql = "SELECT content FROM message WHERE talker='{}' and isSend=0".format(chatroom_id) 
  4.  
  5. # 查詢表,獲取所有的聊天記錄 
  6. result = self.db.query(sql) 

為了獲取有效的消息內(nèi)容,可以清洗掉自己發(fā)送的消息、系統(tǒng)消息、紅包消息等內(nèi)容

 

  1. # 循環(huán)查詢到的所有的消息 
  2. for item in result: 
  3.     # 過濾數(shù)據(jù) 
  4.     if not item or not item[0] or item[0].find('xml') != -1 or item[0].find('sysmsg') != -1 or item[0].find( 
  5.                     '<msg>') != -1 or item[0].find('chatroom') != -1 or item[0].find('weixinhongbao') != -1: 
  6.          continue 
  7.     # 過濾掉自己發(fā)送的內(nèi)容,不包含: 
  8.     temps = item[0].split(':'
  9.     if len(temps) < 2: 
  10.         # print('自己發(fā)送的內(nèi)容:' + item[0]) 
  11.         continue 
  12.     # 每一條聊天記錄,過濾掉發(fā)送者,只保留消息正文 
  13.     # 發(fā)送者 
  14.     send_from = item[0].split(':')[0] 
  15.  
  16.     # 發(fā)送內(nèi)容 
  17.     send_msg = "".join(item[0].split(':')[1:]).strip().replace("\""""
  18.     # 過長的消息,也過濾掉 
  19.     if len(send_msg) > 200: 
  20.          continue 

對于群其他成員發(fā)送的內(nèi)容,再過濾掉消息內(nèi)容的前半部分,只保留消息正文

 

 

 

 

第 8 步,生成詞云

使用 jieba 對群內(nèi)有效的消息進行分詞,然后使用 wordcloud 生成詞云圖。

 

  1. def generate_wordcloud(self, word): 
  2.     ""
  3.     生成詞云 
  4.     :param word: 
  5.     :return
  6.     ""
  7.  
  8.     img = WordCloud(font_path="./DroidSansFallbackFull.ttf", width=2000, height=2000, 
  9.                         margin=2, collocations=False).generate(word) 
  10.     plt.imshow(img) 
  11.     plt.axis("off"
  12.     plt.show() 
  13.  
  14.     # 保存圖片 
  15.     img.to_file("{}.png".format("群聊")) 
  16.  
  17. # 分詞 
  18. temp = " ".join(jieba.cut(words, cut_all=True)) 
  19.  
  20. # 生成詞云 
  21. generate_wordcloud(temp

第 9 步,新建排名表,插入數(shù)據(jù)

為了統(tǒng)計群聊活躍度排名,我們需要新建一張表,包含:id、微信昵稱、消息內(nèi)容 3 個字段。

 

  1. def __create_top_table(self): 
  2.    ""
  3.    創(chuàng)建Top表 
  4.    :return
  5.    ""
  6.    # 創(chuàng)建Top表,如果存在就不重新創(chuàng)建 
  7.    result = self.db.execute
  8.             "CREATE TABLE IF NOT EXISTS top(uid integer primary key,name varchar(200),msg varchar(200))"

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

 

  1. # 定義一個列表,加入所有要統(tǒng)計的數(shù)據(jù) 
  2. msg_pre = [] 
  3.  
  4. for item in result: 
  5.     # 發(fā)送者 
  6.     send_from = item[0].split(':')[0] 
  7.     # 發(fā)送內(nèi)容 
  8.     send_msg = "".join(item[0].split(':')[1:]).strip().replace("\""""
  9.     msg_pre.append((send_from, send_msg)) 
  10.  
  11.  # 把要統(tǒng)計的數(shù)據(jù),插入到top表中 
  12.  self.db.execute("insert into top(uid,name,msg) values (NULL,?,?);", msg_pre) 

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

從 Top 數(shù)據(jù)表中,通過微信昵稱查詢出每一位成員發(fā)言的次數(shù),并保存到一個列表中

 

  1. def get_top_partner(self): 
  2.     ""
  3.     排名前15的成員 
  4.     :return
  5.     ""
  6.     sql = "SELECT name as 姓名,COUNT(*) as times FROM top GROUP BY name ORDER BY times DESC limit %d;" % self.top_num 
  7.     result = self.db.query(sql) 
  8.  
  9.     for item in result: 
  10.         # 用戶id 
  11.         id = item[0] 
  12.         # 發(fā)言次數(shù) 
  13.         count = item[1] 
  14.  
  15.         # 獲取用戶的昵稱,即:微信昵稱 
  16.         username = self.get_username(id) 
  17.  
  18.         self.top_data.append({ 
  19.             'username': username, 
  20.             'count'count 
  21.             }) 

最后,去除微信昵稱的特殊符號,使用 pyecharts 將數(shù)據(jù)可視化。

 

  1. def draw_image(self): 
  2.     ""
  3.     數(shù)據(jù)可視化 
  4.     :return
  5.     ""
  6.     usernames = [] 
  7.     counts = [] 
  8.     for user in self.top_data: 
  9.          # 去除昵稱中的特殊符號 
  10.          usernames.append(get_ava_string(user.get('username').strip())[0:8]) 
  11.          counts.append(user.get('count')) 
  12.  
  13.     def bar_chart() -> Bar: 
  14.             c = ( 
  15.                 Bar() 
  16.                     .add_xaxis(usernames) 
  17.                     .add_yaxis("活躍度", counts) 
  18.                     .reversal_axis() 
  19.                     .set_series_opts(label_opts=opts.LabelOpts(position="right")) 
  20.                     .set_global_opts(title_opts=opts.TitleOpts(title="最活躍的%d個小伙伴" % self.top_num)) 
  21.             ) 
  22.             return c 
  23.  
  24.     # 需要安裝 snapshot-selenium 或者 snapshot-phantomjs 
  25.     make_snapshot(driver, bar_chart().render(), "bar.png"

3. 最后

上面的操作,通過生成的詞云了解到當(dāng)前群聊過去一段時間都在聊的話題及價值,通過對聊天記錄的數(shù)據(jù)分析,獲取到微信群聊活躍度排名。

 

 

 

 

當(dāng)然,也可以分析群成員潛水排名及某一位群成員的數(shù)據(jù)分析。

責(zé)任編輯:華軒 來源: AirPython
相關(guān)推薦

2018-03-06 10:46:42

代碼Python買水果

2017-03-06 14:45:28

戴爾

2016-01-21 17:49:52

云之家Agora語音會議

2018-03-09 10:09:07

程序媛體驗女生

2024-08-08 08:00:00

2018-04-13 17:37:13

SAP上云

2017-10-15 10:39:06

2021-11-04 17:48:44

編程游戲代碼

2018-02-26 09:28:42

程序員Bug體驗

2021-02-23 15:18:27

程序員國企工程師

2015-11-20 10:37:36

KeystoneOpenStackDocker

2018-06-06 17:17:45

GitHub工程師代碼

2018-12-29 10:37:05

HTTP緩存URL

2015-11-23 10:02:16

產(chǎn)品設(shè)計體驗

2016-12-30 15:47:39

云計算發(fā)展CTO

2017-12-21 14:51:41

程序員轉(zhuǎn)行30歲

2021-05-06 16:15:12

Java代碼

2015-06-11 11:43:56

NoSQLBI商務(wù)智能

2021-09-26 13:21:20

Python微服務(wù)JAVA

2017-10-30 14:54:50

點贊
收藏

51CTO技術(shù)棧公眾號