微信好友大揭祕,使用Python抓取朋友圈資料,通過人臉識別全面分析好友,一起看透你的“朋友圈”
微信:一個提供即時通訊服務的應用程式,更是一種生活方式,超過數十億的使用者,越來越多的人選擇使用它來溝通交流。
不知從何時起,我們的生活離不開微信,每天睜開眼的第一件事就是開啟微信,關注著朋友圈裡好友的動態,而朋友圈中或虛或實的狀態更新,似乎都在證明自己的“有趣”,尋找那份或有或無的存在感。
有人選擇在朋友圈記錄生活的點滴,有人選擇在朋友圈展示自己的觀點。有時我們想去展示自己,有時又想去窺探著別人的生活,而有時又不想別人過多的瞭解自己的生活,或是遮蔽對方,或是不給對方看朋友圈,又或是不想看對方的朋友圈。
作者本人(湯小洋 )也是微信的重度依賴者,每天的工作生活都離不開它,也會關注朋友圈裡好友的動態,我個人認為微信朋友圈是一種文化的體現,諸如:髮圈、點贊、留言等,都能側面的反應一個人的生活、工作、心態、愛好、修養、上進心、努力程度等。
今天就跟著 湯老師 一起來揭祕微信朋友圈,利用 Python+AI人工智慧 進行多角度分析,一起看透你的“朋友圈”。
我們將使用Python抓取朋友圈資料,並對獲取到的資料進行全面分析,包含好友性別、地理位置分佈、個性簽名、備註名、好友型別等,逐一進行分析,同時還會使用人臉識別技術對好友頭像進行分析,分析到你懷疑人生。。。。。。 _
整個過程分為四步:
- 獲取資料
- 處理資料
- 儲存資料
- 資料視覺化
一、獲取資料
關於微信好友資料的獲取,可以通過itchat庫,itchat是一個開源的微信個人號的介面,可以實現資訊收發、獲取好友列表等功能。
具體的用法和說明,在程式碼中已經做了詳細的註釋。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
# 匯入itchat模組,操作微信個人號的介面
import itchat
# 獲取資料
def get_data():
# 掃描二維碼登陸微信,實際上就是通過網頁版微信登陸
itchat.auto_login()
# 獲取所有好友資訊
friends = itchat.get_friends(update=True) # 返回一個包含使用者資訊字典的列表
return friends
if __name__ == '__main__' :
print(get_data())
執行程式碼時電腦螢幕會出現一個二維碼,手機微信掃描後即可完成登陸
二、處理資料
對獲取的資料進行處理,篩選出需要的資料。
通過對返回的使用者資訊進行分析,發現列表中第一個元素是使用者自己,可以排除掉。同時我們只取需要的欄位資料,各個欄位及其取值的含義已在程式碼中做了說明。
# 處理資料
def parse_data(data):
friends = []
for item in data[1:]: # 第一個元素是自己,排除掉
friend = {
'NickName': item['NickName'], # 暱稱
'RemarkName': item['RemarkName'], # 備註名
'Sex': item['Sex'], # 性別:1男,2女,0未設定
'Province': item['Province'], # 省份
'City': item['City'], # 城市
'Signature': item['Signature'].replace('\n', ' ').replace(',', ' '), # 個性簽名(處理簽名內容換行的情況)
'StarFriend': item['StarFriend'], # 星標好友:1是,0否
'ContactFlag': item['ContactFlag'] # 好友型別及許可權:1和3好友,259和33027不讓他看我的朋友圈,65539不看他的朋友圈,65795兩項設定全禁止
}
print(friend)
friends.append(friend)
return friends
if __name__ == '__main__':
print(parse_data(get_data()))
三、儲存資料
為了便於分析資料並進行視覺化操作,這裡將資料儲存到文字檔案中。
# 儲存資料,儲存到文字檔案
def save_to_txt():
friends = parse_data(get_data())
for item in friends:
with open('friends.txt', mode='a', encoding='utf-8') as f:
f.write('%s,%s,%d,%s,%s,%s,%d,%d\n' % (
item['NickName'], item['RemarkName'], item['Sex'], item['Province'], item['City'], item['Signature'],
item['StarFriend'], item['ContactFlag']))
if __name__ == '__main__':
save_to_txt()
**重要說明:**這裡我獲取的是自己的微信好友資料(共計950條,因工作關係,好友數比較多),考慮到個人隱私,部分資訊做了處理。
四、資料視覺化
這裡使用的是pyecharts,pyecharts是一個用於生成Echarts圖表的類庫,便於在Python中根據資料生成視覺化的圖表。
Echarts是百度開源的一個數據視覺化JS庫,主要用於資料視覺化。
# 安裝pyecharts
pip install pyecharts
1. 好友性別分析
程式碼實現:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
# 匯入Pie元件,用於生成餅圖
from pyecharts import Pie
# 獲取所有性別
sex = []
with open('friends.txt', mode='r', encoding='utf-8') as f:
rows = f.readlines()
for row in rows:
sex.append(row.split(',')[2])
# print(sex)
# 統計每個性別的數量
attr = ['帥哥', '美女', '未知']
value = [sex.count('1'), sex.count('2'), sex.count('0')]
pie = Pie('好友性別比例', '好友總人數:%d' % len(sex), title_pos='center')
pie.add('', attr, value, radius=[30, 75], rosetype='area', is_label_show=True,
is_legend_show=True, legend_top='bottom')
# pie.show_config()
pie.render('好友性別比例.html')
視覺化結果:
好友主要為男性,佔比70%,男女比例嚴重失衡
看到這個結果,我是有些淡淡憂桑的,微信好友總人數為950,帥哥佔比70.42%,美女佔比24.53%,男女比例嚴重失衡,但一點也不意外,本人是一名IT工作者,平時喜歡跑步,所以工作、生活接觸到的大部分都是男性朋友,出現男女比例失衡實屬正常。
2. 好友位置分析
pyecharts v0.3.2以後,pyecharts 將不再自帶地圖 js 檔案。如使用者需要用到地圖圖表,可自行安裝對應的地圖檔案包。
# 安裝地圖檔案包
pip install echarts-china-provinces-pypkg # 中國省、市、縣、區地圖
pip install echarts-china-cities-pypkg
pip install echarts-china-counties-pypkg
pip install echarts-china-misc-pypkg
pip install echarts-countries-pypkg # 全球國家地圖
pip install echarts-united-kingdom-pypkg
程式碼實現:
# 匯入Counter類,用於統計值出現的次數
from collections import Counter
# 匯入Geo元件,用於生成地理座標類圖
from pyecharts import Geo
import json
# 匯入Bar元件,用於生成柱狀圖
from pyecharts import Bar
# 資料視覺化
def render():
# 獲取所有城市
cities = []
with open('friends.txt', mode='r', encoding='utf-8') as f:
rows = f.readlines()
for row in rows:
city = row.split(',')[4]
if city != '': # 去掉城市名為空的值
cities.append(city)
# 對城市資料和座標檔案中的地名進行處理
handle(cities)
# 統計每個城市出現的次數
data = Counter(cities).most_common() # 使用Counter類統計出現的次數,並轉換為元組列表
print(data)
# 根據城市資料生成地理座標圖
geo = Geo('好友位置分佈', '', title_color='#fff', title_pos='center', width=1200, height=600,
background_color='#404a59')
attr, value = geo.cast(data)
geo.add('', attr, value, visual_range=[0, 500],
visual_text_color='#fff', symbol_size=15,
is_visualmap=True, is_piecewise=True)
geo.render('好友位置分佈.html')
# 根據城市資料生成柱狀圖
data_top20 = Counter(cities).most_common(20) # 返回出現次數最多的20條
bar = Bar('好友所在城市TOP20', '', title_pos='center', width=1200, height=600)
attr, value = bar.cast(data_top20)
bar.add('', attr, value, is_visualmap=True, visual_text_color='#fff', is_more_utils=True,
is_label_show=True)
bar.render('好友所在城市TOP20.html')
出現的問題:
-
報錯:ValueError: No coordinate is specified for xxx(地名)
-
原因:pyecharts的座標檔案中沒有該地名,實際上是名稱不一致導致的,如資料中地名為’達州’,而座標檔案中為’達州市’
座標檔案所在路徑:
專案/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json
-
解決:修改座標檔案,在原位置下複製個同樣的,然後修改下地名
{
"南京市": [
107.5,
31.22
],
"南京": [
107.5,
31.22
],
}
不過由於要修改的地名太多,上面的方法實在是麻煩,所以我定義了一個函式,用來處理地名資料找不到的問題
# 處理地名資料,解決座標檔案中找不到地名的問題
def handle(cities):
# print(len(cities), len(set(cities)))
# 獲取座標檔案中所有地名
data = None
with open(
'/Users/wangbo/PycharmProjects/python-spider/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json',
mode='r', encoding='utf-8') as f:
data = json.loads(f.read()) # 將str轉換為json
# 迴圈判斷處理
data_new = data.copy() # 拷貝所有地名資料
for city in set(cities): # 使用set去重
# 處理地名為空的資料
if city == '':
while city in cities:
cities.remove(city)
count = 0
for k in data.keys():
count += 1
if k == city:
break
if k.startswith(city): # 處理簡寫的地名,如 達州市 簡寫為 達州
# print(k, city)
data_new[city] = data[k]
break
if k.startswith(city[0:-1]) and len(city) >= 3: # 處理行政變更的地名,如縣改區 或 縣改市等
data_new[city] = data[k]
break
# 處理不存在的地名
if count == len(data):
while city in cities:
cities.remove(city)
# print(len(data), len(data_new))
# 寫入覆蓋座標檔案
with open(
'/Users/wangbo/PycharmProjects/python-spider/venv/lib/python3.6/site-packages/pyecharts/datasets/city_coordinates.json',
mode='w', encoding='utf-8') as f:
f.write(json.dumps(data_new, ensure_ascii=False)) # 將json轉換為str
視覺化結果:
好友主要集中在江蘇及周邊地區
從圖中可以發現:我的微信好友主要集中在江蘇及周邊地區,本人大學讀書時來到南京,現在工作生活也一直在南京,所以南京好友最多,為483個;我自小是在徐州長大的,所以徐州好友數量也較多;同時因為喜歡跑馬拉松,結識了許多跑友,也經常會到周邊沿海城市跑步,所以好友位置主要分佈在沿海一帶。
3. 個性簽名詞雲圖
jieba是一個基於Python的分詞庫,完美支援中文分詞,功能強大
pip install jieba
Matplotlib是一個Python的2D繪相簿,能夠生成高質量的圖形,可以快速生成繪圖、直方圖、功率譜、柱狀圖、誤差圖、散點圖等
pip install matplotlib
wordcloud是一個基於Python的詞雲生成類庫,可以生成詞雲圖
pip install wordcloud
程式碼實現:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
# 匯入jieba模組,用於中文分詞
import jieba
# 匯入matplotlib,用於生成2D圖形
import matplotlib.pyplot as plt
# 匯入wordcount,用於製作詞雲圖
from wordcloud import WordCloud, STOPWORDS
# 獲取所有個性簽名
signatures = []
with open('friends.txt', mode='r', encoding='utf-8') as f:
rows = f.readlines()
for row in rows:
signature = row.split(',')[5]
if signature != '':
signatures.append(signature)
# 設定分詞
split = jieba.cut(str(signatures), cut_all=False) # False精準模式分詞、True全模式分詞
words = ' '.join(split) # 以空格進行拼接
# print(words)
# 設定遮蔽詞,去除個性簽名中的表情、特殊符號等
stopwords = STOPWORDS.copy()
stopwords.add('span')
stopwords.add('class')
stopwords.add('emoji')
stopwords.add('emoji1f334')
stopwords.add('emoji1f388')
stopwords.add('emoji1f33a')
stopwords.add('emoji1f33c')
stopwords.add('emoji1f633')
# 匯入背景圖
bg_image = plt.imread('bg.jpg')
# 設定詞雲引數,引數分別表示:畫布寬高、背景顏色、背景圖形狀、字型、遮蔽詞、最大詞的字型大小
wc = WordCloud(width=1024, height=768, background_color='white', mask=bg_image, font_path='STKAITI.TTF',
stopwords=stopwords, max_font_size=400, random_state=50)
# 將分詞後資料傳入雲圖
wc.generate_from_text(words)
plt.imshow(wc) # 繪製圖像
plt.axis('off') # 不顯示座標軸
# 儲存結果到本地
wc.to_file('個性簽名詞雲圖.jpg')
視覺化結果:
充滿正能量、努力生活
個性簽名可以反映人的一種心態,對所有好友的個性簽名進行分詞後製作如下詞雲圖:
從詞雲圖中可以看到,微信好友個性簽名中出現頻率較高的詞彙有:自己、努力、生活、世界、就是、我們、人生、沒有、需要、不要、時間、一切、一起、永遠、未來、運動、快樂、溫柔、個性等,整體來看,我的微信好友還是充滿正能量的,都是積極向上、努力生活、有個性的年青人。
我們可以來詳細的分析下這些高頻詞:
- **自己、就是、我們、個性:**彰顯個性的自我、自以為是、自大等,也說明了年青人的個性張揚、無所畏懼
- **努力、生活、時間、需要:**說明大家都在努力的工作,追求各自所需,為更好的生活拼博著
- **世界、人生、快樂、未來:**正所謂“世界那麼大,我想去看看”,生活雖不易,但對外面的世界、對人生的追求從未停止過,快樂最重要
- **運動、健康、溫柔、享受:**說明喜歡運動的朋友比較多,大家都越來越關注健康。溫柔、享受也成為共識,活著不易,且活且享受。
4. 備註名詞雲圖
獲取好友的備註名,根據備註名生成詞名圖
程式碼實現:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
# 匯入jieba模組,用於中文分詞
import jieba
# 匯入matplotlib,用於生成2D圖形
import matplotlib.pyplot as plt
# 匯入wordcount,用於製作詞雲圖
from wordcloud import WordCloud, STOPWORDS
# 獲取備註名
remarkNames = []
with open('friends.txt', mode='r', encoding='utf-8') as f:
rows = f.readlines()
for row in rows:
remarkName = row.split(',')[1]
if remarkName != '':
remarkNames.append(remarkName)
# 設定分詞
split = jieba.cut(str(remarkNames), cut_all=False) # False精準模式分詞、True全模式分詞
words = ' '.join(split) # 以空格進行拼接
print(words)
# 匯入背景圖
bg_image = plt.imread('bg.jpg')
# 設定詞雲引數,引數分別表示:畫布寬高、背景顏色、背景圖形狀、字型、遮蔽詞、最大詞的字型大小
wc = WordCloud(width=1024, height=768, background_color='white', mask=bg_image, font_path='STKAITI.TTF',
max_font_size=400, random_state=50)
# 將分詞後資料傳入雲圖
wc.generate_from_text(words)
plt.imshow(wc) # 繪製圖像
plt.axis('off') # 不顯示座標軸
# 儲存結果到本地
wc.to_file('備註名詞雲圖.jpg')
視覺化結果:
好友備註中“跑友”、“南航”出現的頻率最高
從圖中可以看出,我的好友備註中出現的高頻詞有:跑友、南航、wbs17091、wbs18031、wbs17022、wbs17071等
-
本人平時喜歡跑步,也經常參加各種馬拉松活動,認識的跑友比較多,所以不足為奇
-
由於工作上與南航有一定的交集,所以南航的好友也比較多
-
以wbs開頭的備註都是我工作中帶過的學生,數量眾多,身為一名IT教育工作者,深感光榮。
**重要說明:**考慮個人隱私,圖中部分姓名做了化名處理,請勿當真,如有不便,還望諒解。
5. 好友分類分析
根據備註名,對好友進行分類,統計各類好友的數量
PS:我的習慣是對好友新增備註,標記好友的型別或來源,這個屬於個人潔癖的一種吧
程式碼實現:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
# 匯入jieba模組,用於中文分詞
import jieba
# 匯入Counter類,用於統計值出現的次數
from collections import Counter
from pyecharts import Bar
# 獲取備註名
remarkNames = []
with open('friends.txt', mode='r', encoding='utf-8') as f:
rows = f.readlines()
for row in rows:
remarkName = row.split(',')[1]
if remarkName != '':
remarkNames.append(remarkName)
# 設定分詞
words = [x for x in jieba.cut(str(remarkNames), cut_all=False) if x not in ['-', ',', '(', ')', '(', ')', ' ', "'"]] # 排除短橫線、逗號、空格、單引號
data_top10 = Counter(words).most_common(10) # 返回出現次數最多的20條
print(data_top10)
bar = Bar('好友分類TOP10', '', title_pos='center', width=1200, height=600)
attr, value = bar.cast(data_top10)
bar.add('', attr, value, visual_range=[0, 200], is_visualmap=True, is_label_show=True)
bar.render('好友分類TOP10.html')
視覺化結果:
學生最多,其實是跑友
這裡只統計好友分類數量最多的前10,其中跑友160人,南航52人,其他的都是wbs開頭的學生,實際上wbs開頭的學生數是最多的,只是在備註時按班級號進行了劃分。
通過分析統計,自己對各類好友的數量也做到了心裡有數。
6. 特殊好友分析
獲取並統計以下的特殊好友:星標好友、不讓他看我的朋友圈、不看他的朋友圈
程式碼實現:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = '湯小洋'
from pyecharts import Bar
# 獲取特殊好友
star_list = [] # 星標朋友
deny_see_list = [] # 不讓他看我的朋友圈
no_see_list = [] # 不看他的朋友圈
with open('friends.txt',