微信聊天記錄做成詞雲~

最近快畢業了,所以想把微信聊天記錄全部導出、做成詞雲、然後寄給好友,想想都很浪漫,哈哈。先上詞雲結果圖(結果圖拿《三國演義》做的,想啥呢,我纔不會把我的聊天記錄發到網上,哈哈),然後教大家如何不花錢(也不要C幣)做出高清的聊天記錄詞雲。(想花錢做的請下載“卓師兄”得到聊天記錄,使用微詞雲得到高清詞雲圖,大概200元就可以搞定)

我是個小白,在製作過程中遇到了很多坑,所以我會說很多,也許比較囉嗦,也算是希望大家別踩我的坑,哈哈。

步驟分爲以下幾個部分:1、微信應用數據備份。2、微信數據庫解密。3、微信聊天記錄提取和處理。4、詞雲製作。

1、微信應用數據備份。

微信數據備份網上教程很多(點我進入知乎的備份教程),我的手機型號是華爲暢享8 Plus(FLA-AL10),因此只要你是華爲手機,直接跟着我的教程走就完全沒有問題。華爲手機助手這個坑我踩過,別用,哈哈,還是自帶的老版本備份軟件最好!

(1)卸載本機的華爲備份軟件。新版本的備份軟件不能備份微信應用數據,所以要卸載。如果你找不到“備份”圖標,那就可以這樣卸載:設置->應用和管理->應用管理->備份->卸載。

(2)下載並安裝8.0版的華爲備份軟件。點我下載華爲備份8.0

(3)備份微信應用數據。照着下面圖片的步驟就行,步驟6後面會提示設置密碼,需要點擊跳過。我的最終備份文件路徑爲“內部存儲\Huawei\Backup\backupFiles\2020-05-29_10-54-12\com.tencent.mm.db"。

                           

                    

2、微信數據庫解密。

看雪論壇的newx大神詳細講解過手機版和電腦版解密的方法(點我進入newx大神的主頁),我幾乎照搬他的教程,自己琢磨出了一套我的方法。

(1)微信備份數據庫轉爲文件夾格式。使用樓月安卓手機備份文件提取器來把com.tencent.mm.db變爲文件夾格式。(點我下載樓月軟件)。爲了方便借鑑我的教程,本教程所有文件全部放到D:\weiXinCiYun中。如下圖,把第一節中的數據庫文件放到D:\weiXinCiYun\com.tencent.mm.db,然後提取爲D:\weiXinCiYun\data。

對了,樓月其實還有微信聊天記錄導出恢復助手,但是收費100元,而且效果一般。

(2)獲取IMEI。IMEI(International Mobile Equipment Identity)就是國際移動設備識別碼,即通常所說的手機序列號,用來區分每部手機。如下圖可以從華爲手機的設置中得到IMEI,雙卡的IMEI有兩個,你需要看看自己用的是哪張。也可以通過記事本打開D:\weiXinCiYun\data\data\com.tencent.mm\MicroMsg\compatibleinfo.cfg,裏面的亂碼裏有一串15位的數字,就是IMEI。如果上面倆辦法還是不行,那您進入2-(3)來獲取IMEI。

                      

(3)獲取UIN,計算出最終密碼。UIN(User INformation)就是用戶信息識別碼,每個人的UIN不同。之前可以通過抓取網頁版微信的數據得到,現在個人不能登錄網頁版微信了(反正我登陸不了,哈哈)。首先呢,數據庫破解密碼計算公式如下。如果你問我誰破解出了這個密碼公式,我只能說:有內鬼,終止交易(ΩДΩ)

                                                                       密碼=前7位(MD5((IMEI+KEY)密碼=取前六位(MD5(IMEI + UIN))))

下面我們來破解吧!下載一個Java的集成開發環境,比如我下載了IntelliJ IDEA(其實我不會java,但是我會照着百度新建工程、運行代碼,哈哈)。將D:\weiXinCiYun\data\data\com.tencent.mm\MicroMsg下的兩個文件“compatibleinfo.cfg”(存着IMEI信息)和“systeminfo.cfg”(存着UIN信息)放到java工程D:\weiXinCiYun\JavaPrj下。然後用Java的Hashmap解碼,獲取信息,MD5處理,取其前7位即可。java代碼和操作流程如下:

package com.company;
import java.io.FileInputStream;             // 文件輸入流
import java.io.FileNotFoundException;       // 文件未找到的異常處理
import java.io.IOException;                 // 輸入輸出異常處理
import java.io.ObjectInputStream;           // 輸入流
import java.security.MessageDigest;         // 支持MD5算法
import java.util.HashMap;                   // 支持哈希算法
public class Main {
    // main函數
    public static void main(String[] args) {
        try {
            // 取手機的IMEI
            // 讀入CompatibleInfo.cfg文件
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("CompatibleInfo.cfg"));
            Object DL = in.readObject();
            // java的哈希轉換
            HashMap hashWithOutFormat = (HashMap) DL;
            String s = String.valueOf(hashWithOutFormat.get(Integer.valueOf(258)));
            System.out.println("IMEI:"+s);

            // 獲取微信UIN,與IMEI獲取類似
            ObjectInputStream in1 = new ObjectInputStream(new FileInputStream("systemInfo.cfg"));
            Object DJ = in1.readObject();
            HashMap hashWithOutFormat1 = (HashMap) DJ;
            String t = String.valueOf(hashWithOutFormat1.get(Integer.valueOf(1)));
            System.out.println("uin:"+t);

            //合併到一個字符串,然後使用MD5算法,取其前6位
            s = s + t;
            s = encode(s); // MD5
            System.out.println("密碼是 : " + s.substring(0, 7));
            in.close();
            in1.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // MD5計算
    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();

    }
}

(4)取出聊天記錄。2-(3)裏最後一張圖的調試界面已經顯示出了密碼,我們下載一個數據庫軟件,用密碼對數據庫解密就行。一定要下載sqlcipher2版本,其它數據庫軟件不行,我試過,哈哈,點我下載sqlcipher2。D:\weiXinCiYun\data\data\com.tencent.mm\MicroMsg\c2f9b29c3178c858d04e3ac3382b7c33\enmicromsg.db這個數據庫存放着微信的聊天記錄,最後兩級路徑可能不同,但enmicromsg.db名稱是固定的。用sqlcipher打開enmicromsg.db,將其中的message表輸出爲csv即可,最後把message.csv轉爲message.xlsx。具體操作如下圖:

3、微信聊天記錄提取和處理

將上節的message.xlsx放到D:\weiXinCiYun下面。然後打開,我來講解一下該excel每列內容的含義。我這裏複製了很多簡書“唐九十九藏”大神的內容(點我看唐九十九藏的內容)。

1、msgId:Message Identity,消息標識,取值2,3,4,5...,用來區分每條消息,相當於消息的身份證。

2、msgSvrId:不知道啥意思,哈哈。

3、type:消息類型,1-文本,3-圖片,34-語音,43-視頻,47-微信外部成系列開發的表情包49-做成微信格式的外部網頁鏈接。10000-撤回消息,1048625-微信外部單獨開發的表情包,285212721-微信公衆號推送的自動消息,419430449-微信紅包(未更新時會有類似提示)。

4、status:不知道啥意思,o(╥﹏╥)o

5、isSend:0-收到消息,1-發送消息。

6、isShowTimer:不知道啥意思,我的16萬條消息裏面,它都是空。

7、createTime:消息發送/收到的時間。這裏用的是UNIX時間戳。

8、talker:WXID,即微信號碼。

9、content:聊天記錄。

10、imgPath:Image Path,微信圖像、語音、視頻等大文件的存儲路徑。

11、reserved:不知道啥意思,(ΩДΩ)

12、lvbuffer:幾乎全是“{”,感覺沒啥用。

13、transContent:不知道啥意思,我的16萬條消息裏面,它都是空。

14、transBrandWording:不知道啥意思,我的16萬條消息裏面,它都是空。

15、talkerId:微信好友的唯一號碼,它相當於微信裏的身份證號。

16、bizClientMsgId:如果變量非空,那麼type就是285212721,status就是3,isSend就是3,content就是~SEMI_XML~,所以我猜應該是微信號推送消息的某種號碼。

17、bizChatId:大部分值都是-1,微信運動相關行其值爲空。估計沒啥意義。

18、bizChatUserId:不知道啥意思,我的16萬條消息裏面,它都是空。

19、msgSeq:與msgId差一個常數,感覺很雞肋,有時候還是空。

20、flag:msgSeq有值,則flag=0,msgSeq爲空,則flag也爲空。

將下面的Matlab代碼放到D:\weiXinCiYun下運行,將代碼第13行的yourID改爲你想要微信聯繫人的talkerId就行。代碼運行結果中user.contentText矩陣裏的content那一列就是對應talkerId的用戶的所有文字聊天記錄(圖片和網頁之類的東西我剔除了),把content那一列複製下來,放到'李某某.txt'中。把具體代碼和matlab界面如下:

% 選擇是否從初始化,excel裏導入數據
if(1)
    close all; clear; clc;
    fileName = 'message.xlsx';
    range = 'A1:T2';
    [num, txt, raw] = xlsread(fileName);    
end

% message爲數據庫聊天記錄message表
yourName = '李某某';
myName = '王某某'
message = raw;
yourID = 193;

% user爲your的單個結構體,下面的...Id存儲某列值在message裏的列數
ans = ['開始新建', yourName, '的user數據...']
yourFullName = yourName;                % 你的名字
myFullName = myName;                     % 我的名字
user.talkerId = yourID;                         % 用戶編碼:咱只需要本用戶的數據,其餘數據丟棄
user.typeIndex = 3;                              % 聊天記錄類型的列數:1文字消息,其餘全不要
user.isSendIndex = 5;                           % 發送類型的列數:0接收,1發送
user.creatTimeIndex = 7;                     % 發送時間的列數
user.contentIndex = 9;                         % 發送內容的列數
user.imgPathIndex = 10;                       % 圖像路徑的列數
user.talkerIdIndex = 15;                        % 對方的微信ID的列數
user.contentLengthIndex = 21;            % 內容發送內容長度的列數

% 選取某個人的聊天記錄:將talkerId與對方相同的message留下,其餘的拋棄
user.message = [];
sizeMessage = size(message);
for i = 1:sizeMessage(1)
    i
    if cell2mat(message(i, user.talkerIdIndex)) == user.talkerId
        user.message = [user.message; message(i, :)];
    end
end

% 刪去聊天記錄中的非文本信息
sizeUserMessage = size(user.message);
user.contentText = [];                   % 聊天記錄裏的文本
user.contentOther = [];                 % 聊天記錄除了文本圖片的其它
for i = 1:sizeUserMessage(1)
    i
    switch cell2mat(user.message(i, user.typeIndex))
        case 1          % 文本聊天記錄
            % 嘗試將聊天記錄轉爲字符串類型
            try
                charTmp = char(user.message(i, user.contentIndex));
                catchState = 0;
            catch
                catchState = 1;
            end
            if ~catchState              % 聊天記錄可以轉爲字符串
                % 正則表達式,提取出charTmp裏的漢字,賦給hanZi
                hanZi = char(regexp(charTmp,'[^\x00-\xff]{1,}','match'));
                lengthHanZi = length(hanZi);
                lengthCharTmp = length(charTmp);
                % 如果單個聊天記錄長度大於10,並且漢字數量少於總數量的一半,那麼認爲是系統的紅包、語音、鏈接等無用信息,放入other裏
                if (lengthCharTmp > 10) && (lengthHanZi < (lengthCharTmp / 2))
                    user.contentOther = [user.contentOther; user.message(i, :)];
                else
                    % 將有用數據保存,開闢新的最後一列,保存消息長度,以便後續查找最多消息的一天、查找最多消息等操作。
                    user.contentText = [user.contentText; user.message(i, :) lengthCharTmp];
                    % 將Unix時間改爲Matlab時間
                    unixTime = user.contentText(end, user.creatTimeIndex); 
                    unixTime = unixTime{1};
                    matlabTime = datestr(UnixTime2MatlabTime(unixTime), 'yyyy-mm-dd HH:MM:SS');
                    user.contentText(end, user.creatTimeIndex) = cellstr(matlabTime);
                end
            else                               % 聊天記錄不可以轉爲字符串
                user.contentOther = [user.contentOther; user.message(i, :)];
            end 
        otherwise     % type非1,則不是文本消息,放入other裏
            user.contentOther = [user.contentOther; user.message(i, :)];
    end
end


ans = '運行結束'

4、詞雲製作

詞雲就是把一大篇文章裏的詞語摘出來,根據詞語使用頻率的高低,在圖片里根據不同的大小來顯示,非常直觀,而且很浪漫。詞雲製作我幾乎照搬bilibili up主同濟子豪兄的內容, 如果你有興趣瞭解詞雲製作的細節,可以去看他的b站詞雲製作講解視頻(點我進入同濟子豪兄的b站視頻

(1)安裝相應的詞雲庫和中文分詞組件庫。windows在PowerShell裏運行下面的pip代碼就行。跟詞雲關係最大的兩個模塊就是WordCloud和jieba。WordCloud是製作詞雲的庫,小巧精悍,功能強大,1小時就可以瞭解完它的所有接口函數(點我進入WordCloud官網)。jieba是分析中文詞語的庫,接口函數很多,可以分析各種詞性、短語等(點我進入jieba的github網站)。

pip install numpy matplotlib pillow wordcloud imageio jieba snownlp itchat -i https://pypi.tuna.tsinghua.edu.cn/simple

(2)下面到了激動人心的詞雲製作環節!上一節中,我們已經把某人的聊天記錄全部放到“李某某.txt”裏了,我已經把python代碼給你弄好啦,你直接放到D:\weiXinCiYun跑就行,生成詞雲圖片是5657×4000的,超級高清,剛好是A4紙的打印尺寸,可以彩印出來給同學看,哈哈,代碼大約得運行2分鐘。代碼和結果如下(當然還是三國演義啦,我纔不貼我的聊天記錄):

# 導入詞雲製作庫wordcloud和中文分詞庫jieba
import jieba
import wordcloud

# 導入imageio庫中的imread函數,並用這個函數讀取本地圖片,作爲詞雲形狀圖片
import imageio

# 構建並配置詞雲對象w,注意要加scale參數,提高清晰度
w = wordcloud.WordCloud(width= 5657,
                        height=4000,
                        background_color='white',
                        font_path='msyh.ttc',
                        )

# 對來自外部文件的文本進行中文分詞,得到string
f = open('李某某.txt',encoding='utf-8')
txt = f.read()
txtlist = jieba.lcut(txt)
string = " ".join(txtlist)

# 將string變量傳入w的generate()方法,給詞雲輸入文字
w.generate(string)

# 將詞雲圖片導出到當前文件夾
w.to_file('李某某的詞雲.png')

5、作者的私貨

其實微信聊天記錄導出、python生成詞雲等東西在google裏、百度裏已經是玩爛的東西了,但google和百度裏面竟然沒有一篇完整的、詳盡的教程,所以我纔想做一篇,而且製作過程中自己也提高了很多,很有趣,哈哈。大家要遵紀守法、做一個好公民,微信聊天記錄只許查看自己的呦~

本文的所有代碼和步驟已經說得很明白了,上文也全部給出了。鑑於也許有些C幣大佬願意打賞我,或者懶得挨個下載,我把我的關於微信做詞雲的所有代碼、工程、安裝包等做成了一個壓縮包,裏面包含了所有東西,還夾帶了一點點的matlab微信聊天記錄處理函數(Unix時間、matlab時間、中文時間互相轉換函數),如果你想一股腦地全部下載,想看看我的私貨matlab代碼的話,可以下載我的私貨壓縮包呦——(點我下載全部代碼和資源和私貨的壓縮包!)。

我寫完這篇文章是2020年6月1號,兒童節,希望大家保持童心,保持好奇。昨天ellon musk的spaceX公司發射了載人航天器"龍"號,它的二級火箭和載人航天器都可以回收,太牛逼了。“龍”號和國際空間站對接了,還送了2個NASA的航天員,厲害啊。真的希望我國的航天事業趕緊發展,有生之年看見我國翱翔於星辰大海。

 

 

 

 

 

 

 

        

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章