當 Python 遇到了你的微信好友

僱個城管打天下發表於2019-04-21

臨近畢業,慢慢的也感傷起來,回想大學這幾年,除了技術的成長,最值得慶幸的就是結交了一幫志同道合的好友。後期自己做了公眾號,微信好友的數量也越來越多,身邊人所扮演的角色也越來越豐富,有早已結婚生子為人父母的同學,有沉迷科研學術的教師,當然也少不了一眾還在996的程式猿。事實上,你所處圈子的質量很大程度上就決定了你的人生質量,那麼今天我們就來看看當 Python 遇到了你的微信好友後能擦出怎樣的火花。

完整程式碼可在公眾號:「01二進位制」後臺回覆:「微信好友」獲取

前言

這次我們直奔主題,本文要做的是以下幾件事:

  1. 分析微信好友的總人數、男生數、女生數、男女比
  2. 分析好友的地域分佈
  3. 利用 自然語言處理 的方法分析出你好友的情感傾向
  4. 獲取微信好友的頭像並拼接成指定圖片

準備

還是老樣子,做實驗前,先做好準備工作,實驗環境如下:

  • Python 3.6 (虛擬環境的管理為Pipenv)

  • Pycharm

  • 主要使用到的包有:

    • itchat
    • pyecharts
    • baidu-aip
    • photomosaic
    • pillow

對Pipenv這個虛擬環境管理工具不熟悉的可以去看我之前的文章:《Python 管理哪家強?》,裡面對於 Pipenv 這個虛擬環境管理工具有一些介紹。

itchat是一個開源的微信個人號介面,可以讓我們使用python來呼叫微信

pyecharts是python+echarts的結合,用於進行資料的視覺化

baidu-aip是百度推出的一個nlp的包

photomosaic是用來生成蒙太奇馬賽克圖片的

大家獲取到原始碼之後只需要將 Pipfile 複製到你們的專案根路徑下,然後再終端執行 pipenv install 即可建立一個安裝好所有包的虛擬環境了(前提是你的電腦上已經安裝了pipenv了)

做好準備工作後我們就開始吧。

開始

1. 初始化 itchat

只需一行程式碼即可初始化 itchat:

itchat.auto_login(hotReload=True)
複製程式碼

hotReload(熱載入),True表示其短時間內不需要再次掃碼登陸

2. 獲取好友列表

同樣的也只需要一行程式碼即可獲取:

friends = itchat.get_friends(update=True)[0:]
複製程式碼

返回的資料是類 JSON 格式的,我們用 Python可以很方便的解析,因為篇幅原因,返回的示例我就不展示了,你們自己輸出檢視就可以了。

3. 分析男女分佈情況

首先我們需要獲取好友的性別資訊,通過分析返回的 JSON 字串我們發現,在好友的資訊中有 Sex 標籤,其規律是當其值為1是表示男生,2表示女生,0表示沒有填寫的,因而我們可以這樣

# 對好友數進行分析
def analyze_friends_num(friends):
    # 初始化性別的變數(男、女、其他,其他表示的是註冊時沒有填寫性別資訊的)
    male = female = others = 0
    # 迴圈得到的全部好友
    # 在好友的資訊中有Sex標籤,發現規律是當其值為1是表示男生,2表示女生,0表示沒有填寫的
    for i in friends[1:]:
        sex = i['Sex']
        if sex == 1:
            male += 1
        elif sex == 2:
            female += 1
        else:
            others += 1
    # 總人數
    total = len(friends[2:])
    print("總人數為", total, "其中男性", male, "人,女性", female, "人,男女比為", round((male / female), 2), ":1")
複製程式碼

執行的結果為:

總人數為 387 其中男性 228 人,女性 116 人,男女比為 1.97 :1
複製程式碼

更加直觀的顯示如下(視覺化的程式碼在 utiils 包下,這裡就不放出了,有需要的自己看原始碼):

friends_num

我的好友裡男女比竟然是 2:1(那些沒填性別資訊的人裡面不知道還有多少男生),活該沒有女朋友啊,看來下次要多加一些女生的微信了。

4. 好友地域分佈

這裡我們只要獲取到好友的地域資訊,然後用兩個 dict (分別是省和市)儲存即可,key 為地域, value 為該地域的好友數,迴圈遍歷 friends 最後用餅圖表示分佈最多的5個省,用柱狀圖表示分佈最多的15個市,程式碼如下:

# 分析好友的地域分佈
def analyze_friends_location(friends):
    province = {}
    city = {}
    for i in friends[1:]:
        if i['Province'] == '':
            i['Province'] = '其他'
        if i['City'] == '':
            i['City'] = '其他'

        province[i['Province']] = province.get(i['Province'], 0) + 1
        city[i['City']] = city.get(i['City'], 0) + 1
    sorted_province = sorted(province.items(), key=lambda item: item[1], reverse=True)
    sorted_city = sorted(city.items(), key=lambda item: item[1], reverse=True)

    # 畫出分佈圖
    draw_friends_location(sorted_province[0:5], sorted_city[0:15])
複製程式碼

結果如下:

當 Python 遇到了你的微信好友

當 Python 遇到了你的微信好友

看到這大家應該也能猜到我主要的活動區域是哪了吧,有興趣的大家可以猜一猜然後在文末留言哦。

5. 好友情感分析

當你想要了解一個人心態(注意是心態而不是動態)的時候,你往往都會去看他的簽名而不是朋友圈,因為簽名更改的頻率很低,很大程度上會反映這個人的情緒和心態。相比之下,朋友圈更新的頻率較高,因為是要分享自己近期的動態的(我就見過有的女生一條朋友圈分成好幾條發,每次只發幾個字)。因此對好友的簽名進行分析是可以分析出她的情緒的,那麼我們該如何分析情感呢?

這裡實名誇獎一下百度,作為國內技術的老大哥,很久之前百度就已經免費開放了他的一些人工智慧介面,其中就有情感傾向分析,官網是ai.baidu.com/tech/nlp_ap…,這些免費的人工智慧介面的開放對於我們這些個人開發者無疑是個福音。下面是他的功能演示截圖:

當 Python 遇到了你的微信好友

他的用法也很簡單,安裝好baidu-aip包之後,申請下appkey、appid和secretkey後即可使用:

client = AipNlp(APP_ID, API_KEY, SECRET_KEY)

def analyze_text(text):
    res = client.sentimentClassify(text.strip())
    return res['items'][0]['sentiment']
複製程式碼

因此我們要做的無非就是獲取好友的簽名,然後傳入analyze_text函式即可:

# 分析好友的簽名
def analyze_friends_signature(friends):
    positive = 0
    negative = 0
    others = 0

    print('簽名情感分析中,請稍後......')
    for index, item in enumerate(friends[1:]):
        text = item['Signature']
        if text != '':
            try:
                print('正在分析第', index, '條簽名:', text, '他的作者是:', item['NickName'], '你給他的備註是:', item['RemarkName'])
                res = analyze_text(text)
                if res == 0:
                    negative = negative + 1
                if res == 1:
                    others = others + 1
                if res == 2:
                    positive = positive + 1
            except:
                continue
複製程式碼

看到這有人會有疑問了,我的好友人數有上千,免費的介面能用這麼多次嗎?事實上,他真的可以用這麼多次?

當 Python 遇到了你的微信好友

看到這我突然想給百度打call,這也太良心了吧。請問貴公司還缺實習生嗎,我想去應聘?。然後我們來看看我的好友的情緒分析圖吧。

friends_signature_emotion

沒想到我的好友裡面竟然還有17.83%的人有消極情緒,看來必要的時候得"we need to talk"了。

6. 利用好友的微信頭像生成指定的照片

看標題你們可能不懂是什麼意思,直接放圖你們就明白了:

當 Python 遇到了你的微信好友

這張圖遠看是一張一個人跳舞的圖片,其實仔細看就知道了,構成這張圖的是我的 300 多張微信好友的影像,這裡我使用到了一個名為photomosaic的庫,它是專門用來製作這種蒙太奇馬賽克風格的圖片的,是我無意中在知乎上看到的,所以大家有事沒事還是逛逛知乎,多少能發現些好玩意。

接下來我們來看看如何生成上述圖片。

第一步,我們先獲取好友的頭像:

# 獲取好友頭像
def get_friends_avatar(friends):
    for index, item in enumerate(friends):
        print("正在下載第 %d 張頭像" % index)
        img = itchat.get_head_img(userName=item["UserName"])
        file_image = open(os.getcwd() + "/app/temp/" + item["UserName"] + ".jpg", 'wb')
        file_image.write(img)
        file_image.close()
複製程式碼

也很簡單,直接呼叫itchat的get_head_img方法然後儲存到本地指定資料夾下即可。

第二步,利用photomosaic生成目標圖片

# 利用好友頭像生成蒙太奇馬賽克圖片
def draw_friends_mosaic_image():
    # 讀取基準圖,即要生成的蒙太奇馬賽克圖片的原始圖
    image = pm.imread(os.getcwd() + '/assets/cxk.jpg')
    # 定義圖片庫
    pool = pm.make_pool(os.getcwd() + '/temp/*.jpg')
    # 製作50*50的拼圖馬賽克,(50, 50)是指每一行和每一列使用圖片庫中的影像的個數
    mosaic = pm.basic_mosaic(image, pool, (50, 50))
    # 儲存製作好的圖片
    pm.imsave(os.getcwd() + '/output/friends_mosaic_image.jpg', mosaic)
複製程式碼

四行程式碼即可,原理的話知乎上有寫,有興趣的可以自己去搜一搜。

當然了,不是每個人的微信好友都有上千人,所以拼接出來的效果就不是很好,比如我自己的那個就不是很好,既然這樣的話我就推薦另一個拼接頭像的方法,不過效果要稍微差點,拼成的圖長這樣:

friends_avators

這裡的程式碼來自我關注的一個公眾號,就不放出程式碼了,大夥感興趣的可以去看下他的文章:《一鍵拼出你的微信好友圖片牆》

這張圖雖然觀賞效果不如上一張,但好在每個頭像都很清楚,大夥兒看看能不能快速找到自己的頭像呢?歡迎在留言區評論互動哦~

最後

完整程式碼可在公眾號:「01二進位制」後臺回覆:「微信好友」獲取

方法教給大家了,圖片素材可以優化,大家可以生成自己喜歡的蒙太奇圖片,發到朋友圈,讓程式碼騷動起來吧!

寫到這,我想說的是,你朋友的質量決定你生命的質量,想成為一個高層次的人,那就請跟優秀的朋友為舞?

當 Python 遇到了你的微信好友

相關文章