天天看點

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

目錄

    • Itchat簡介
    • 1. 登入 擷取好友資訊
    • 2. 好友性别統計
    • 3. 好友省份統計
    • 4. 好友城市統計
    • 5. 好友頭像擷取
    • 6. 好友簽名分析
    • 總結

Itchat簡介

itchat官網:https://itchat.readthedocs.io/zh/latest/

itchat是一個開源的微信個人号接口

使用這個接口可以完成擷取微信好友資訊,發送資訊,接收資訊等操作

借此可以開發個人的微信機器人。

(目前發送資訊等功能好像已被官方禁止)

現在我們隻是用最基本的擷取好友資訊功能 來得到微信好友資訊 并進行初步的分析統計

1. 登入 擷取好友資訊

首先當然是要安裝這個開源包

pip install itchat
           

隻需要一條指令就可以進行微信的掃碼登入

import itchat
itchat.auto_login()
           

掃碼後便會提示登陸了網頁版微信 (ps: 新的微信賬号貌似已經不支援網頁版登陸了。。。)

登入之後便可以通過下面這條指令擷取最新的好友資訊

這裡的update參數是代表是否重新擷取最新資訊 如果是False那麼就會使用緩存資訊

為了清楚地了解其内部資料結構 我們這裡會将好友資訊儲存在本地 (效果同update=False一樣)

代碼如下:

if os.path.exists('friends.json') is False:
        with open("friends.json",'w') as f:  
            itchat.auto_login()
            friends = itchat.get_friends(update=True) 
            json.dump(friends,f)
            print("save friends info.")
else:
        with open('friends.json','r') as lf:
            friends = json.load(lf)
            print('load friends info.')
           

此時我們将好友資訊儲存到了friends.json

我們可以檢視一下裡面的資訊存儲結構:

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

根據上圖我們可以對好友的城市、省份、簽名、性别、頭像等進行統計分析

2. 好友性别統計

sex 代表着好友的性别 1:男 2:女 當然不能排除其它情況。。。0.0

def sex_analysis(friends):
    labels = ['男', '女', '其他']
    data = [0, 0, 0]

    # friends[0] 是自己的資訊
    for friend in friends[1:]:
        sex = friend["Sex"]
        if sex == 1:
            data[0] += 1
        elif sex == 2:
            data[1] += 1
        else:
            data[2] += 1
    labels = [labels[i]+':'+str(data[i]) for i in range(len(labels))]
    plt.title("微信好友性别比例")
    plt.pie(data, labels=labels,autopct="%.2f%%")
    plt.savefig("sex.jpg")
    plt.show()
           

我們可以使用matplotlib根據這個統計結果生成一個餅狀圖

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

3. 好友省份統計

我們将各省擁有的好友個數進行統計 并排序 取top10

這裡會有特殊的空(’’)省份需要去除

def prov_analysis(friends):
    prov_dict = defaultdict(int)
    
    for friend in friends[1:]:
        prov = friend['Province']
        prov_dict[prov] +=1
    prov_dict.pop('')
    prov_top10 = sorted(prov_dict.items(),key=lambda x:x[1],reverse=True)[:10]
    prov_name = [x[0] for x in prov_top10]
    prov_num = [x[1] for x in prov_top10]
    plt.bar(prov_name,prov_num,width=0.5,align='center',color='#87CEFA')
    for i in range(len(prov_num)):
        x = prov_name[i]
        y = prov_num[i]
        plt.text(x,y+1,'%s'%y,fontsize=10,ha='center')
    plt.ylabel("好友數量")
    plt.xlabel("省")
    plt.title("各省好友分布 TOP10")
    plt.savefig("province.jpg")
    plt.show()
           

同樣将結果使用plt呈現

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

根據這個明顯的省份分布 幾乎可以斷定。。該微信号是個浙江人

4. 好友城市統計

這個和省份統計基本一緻

def city_analysis(friends):
    city_dict = defaultdict(int)
    for friend in friends[1:]:
        city = friend['City']
        city_dict[city] +=1
    city_dict.pop('')
    city_top10 = sorted(city_dict.items(),key=lambda x:x[1],reverse=True)[:10]
    city_name = [x[0] for x in city_top10]
    city_num = [x[1] for x in city_top10]
    plt.bar(city_name,city_num,width=0.5,align='center',color='#87CEFA')
    for i in range(len(city_num)):
        x = city_name[i]
        y = city_num[i]
        plt.text(x,y+1,'%s'%y,fontsize=10,ha='center')
    plt.ylabel("好友數量")
    plt.xlabel("城市")
    plt.title("各城市好友分布 TOP10")
    plt.savefig("city.jpg")
    plt.show()
           
Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

分析上圖:

該微信号在杭紹兩城市 出生/工作

并在成都生活過一段時間

5. 好友頭像擷取

這個功能好像沒什麼能分析的。。。看看好友的頭像是否非主流。。

這裡需要注意

從緩存的friends.json好友資訊中可以擷取頭像位址

但是下載下傳頭像是需要重新登陸的

我們在這裡繼續進行緩存 将頭像儲存在 photos/檔案夾内

get_photo:下載下傳好友頭像圖檔

photo_merge: 拼接好友頭像 生成一張大圖

def get_photo(path):
    itchat.auto_login()
    friends = itchat.get_friends(update=True)[0:]
    num=0
    for i in friends:
        img = itchat.get_head_img(userName=i["UserName"])
        imgpath = path+str(num)+'.jpg'
        try:
            with open(imgpath,'wb') as imgf:
                imgf.write(img)
        except Exception as e:
            print("get err:",e)
        num+=1
        
def photo_merge(friends):
    path='photos/'      
    
    if os.path.exists(path) is False:
        os.mkdir(path)
    
    flist = os.listdir(path)
    if len(flist)==0:
        get_photo(path)
        flist = os.listdir(path)
    line = int(math.sqrt(len(flist)))
    each_size = int(640/line)
    image= Image.new('RGB',(line*each_size,int(len(flist)/line)*each_size))
    x,y=0,0
    poslist = list(range(len(flist)))
    random.shuffle(poslist)
    for i in flist:
        try:
            pos = poslist.pop()
            img = Image.open(path+str(pos)+'.jpg')
        except IOError as e:
            pass
        else:
            img = img.resize((each_size,each_size),Image.ANTIALIAS)
            image.paste(img,(x*each_size,y*each_size))
            x+=1
            if x==line:
                x=0
                y+=1
    image.save("frinds_photo.jpg")
    img = plt.imread("frinds_photo.jpg")
    plt.imshow(img)
    plt.axis('off')
    plt.show()
           

注意: 為了讓拼接的圖檔沒有黑邊 更加的好看

我們在拼接圖檔時會舍棄掉一些圖檔

假設我們有num張照片 sqrt(num) 取整 = n

我們會拼接n x n 大小的圖檔 整張圖檔大小為640x640 可以自由設定

每位好友的頭像大小(640/n x 640/n)

結果如下圖:

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

看上去挺壯觀。。。。

6. 好友簽名分析

這裡我們會用到中文分詞工具 jieba:https://github.com/fxsjy/jieba

我們将每一個好友簽名 去除停用詞 (這裡隻是初步手動去除 不全面)

拼接後 使用結巴進行分詞

統計分詞後詞組的出現頻率

使用詞雲(wordcloud)https://github.com/amueller/word_cloud 将這些詞組展現出來

頻率越高 詞越大

def sig_analysis(friends):
    text = ''
    rule = re.compile("1fd+w*|[<>/=]")
    for fri in friends:
        sig = fri['Signature'].strip()
        if len(sig)>0 and not sig.startswith('<span'):
            sig = sig.replace("span",'').replace("class",'').replace("emoji","").replace("\n","").replace("00","")
            sig = rule.sub("",sig)
            text += sig + ' '
    jiebatext = list(jieba.cut(text,cut_all=True))
    jiebatext = [x for x in jiebatext if len(x)>1]
    
    wordDic = dict(Counter(jiebatext))
    bgimg = plt.imread('bk.jpg')
    mywordcloud = wordcloud.WordCloud(
            font_path='jdxs.TTF',
            background_color="white",
            mask=bgimg,
            width=1200,
            height=1200)
    mywordcloud.generate_from_frequencies(wordDic)
    plt.imshow(mywordcloud)
    plt.axis("off")
    plt.show()
    mywordcloud.to_file("sigimg.png")
           

結果如下圖

Python 使用itchat 擷取微信好友資訊并解析(性别 區域 頭像 簽名等)

總結

雖然隻是擷取了最基礎的微信好友資訊

但我們已經能夠從這些不起眼的資料中擷取到一些有用的資訊

好友數量 好友性别比例 使用者生活城市等等

細思極恐0.0

那些并未開放 擷取不到的資訊裡 是否已經将我們展示地一覽無餘