2022年 11月 8日

利用python进行微信好友数据分析

昨天无意中看到一篇文章《基于Python实现的微信好友数据分析》,感觉很有趣,就想自己尝试一下。也不太清楚原作者是谁了,也是公众号转载的,基于原问题进行了代码的优化。

    微信是目前我们用的最多的社交软件,古语云“观其友而知其人”。对微信好友的数据分析也是对自身的一种分析。

一、本文将引用多个第三方模块,引用如下:

  1. import itchat
  2. import numpy as np
  3. import os
  4. from collections import Counter
  5. import matplotlib.pyplot as plt
  6. plt.rcParams['font.sans-serif']=['SimHei']#绘图时可以显示中文
  7. plt.rcParams['axes.unicode_minus']=False#绘图时可以显示中文
  8. import TencentYoutuyun
  9. from wordcloud import WordCloud,STOPWORDS,ImageColorGenerator
  10. from PIL import Image
  11. import time
  12. import re
  13. import snownlp
  14. import jieba
  15. import jieba.analyse
import pandas as pd

本人用的python3,以上模块除了TencentYoutuyun和wordcloud,均可以通过pip install 安装。

(1)TencentYoutuyun安装:点击打开链接

(2)wordcloud安装:

访问https://www.lfd.uci.edu/~gohlke/pythonlibs/#wordcloud下载对应版本的安装包,将下载的安装包保存在工作目录下,直接使用pip install 文件名

二、登录微信,获取好友数据:

  1. if __name__ == "__main__":
  2. itchat.auto_login(hotReload=True)
  3. friends = itchat.get_friends(update=True)

三、微信好友数据分析:

1、性别分析

    

  1. def fun_analyse_sex(friends):
  2. sexs = list(map(lambda x:x['Sex'],friends[1:]))#收集性别数据
  3. counts = list(map(lambda x:x[1],Counter(sexs).items()))#统计不同性别的数量
  4. counts = sorted(counts)
  5. labels = ['保密','男','女']#2:女,1:男,0:保密
  6. colors = ['red','yellow','blue']
  7. plt.figure(figsize=(8,5), dpi=80)
  8. plt.axes(aspect=1)
  9. plt.pie(counts, #性别统计结果
  10. labels=labels, #性别展示标签
  11. colors=colors, #饼图区域配色
  12. labeldistance = 1.1, #标签距离圆点距离
  13. autopct = '%3.1f%%', #饼图区域文本格式
  14. shadow = False, #饼图是否显示阴影
  15. startangle = 90, #饼图起始角度
  16. pctdistance = 0.6 #饼图区域文本距离圆点距离
  17. )
  18. plt.legend(loc='upper left')#标签位置
  19. plt.title(u'%s的微信好友性别比例' % friends[0]['NickName'])
  20. plt.show()

结果如下:

男女比例还是均衡的。

2、头像分析

头像分析有两部分,(1)头像是否是人脸;(2)头像标签的词云

(1)第一部分将会用到腾讯优图提供的人脸识别API,需要自己注册获得appid。详细使用文档:点击打开链接

  1. def fun_analyse_HeadImage(friends):
  2. basePath = os.path.abspath('.')#程序的存储位置
  3. baseFolder = basePath + '\\HeadImages\\'#创建存储图片的文件夹的位置
  4. if(os.path.exists(baseFolder) == False):
  5. os.makedirs(baseFolder)
  6. else:
  7. pass
  8. use_face = 0#使用人脸
  9. not_use_face = 0#未使用人脸
  10. appid = '你的appid'
  11. secret_id = '你的secret_id'
  12. secret_key = '你的secret_key'
  13. end_point = TencentYoutuyun.conf.API_YOUTU_END_POINT
  14. youtu = TencentYoutuyun.YouTu(appid, secret_id, secret_key,end_point)
  15. image_tags = ""
  16. for index in range(1,len(friends)):
  17. friend = friends[index]
  18. #保存头像文件
  19. imgFile = baseFolder + '//Image%s.jpg' %str(index)
  20. imgData = itchat.get_head_img(userName=friend['UserName'])
  21. if (os.path.exists(imgFile) == False):
  22. with open(imgFile,'wb') as file:
  23. file.write(imgData)
  24. #检测人脸
  25. time.sleep(1)
  26. result = youtu.DetectFace(imgFile)
  27. if result['face']:
  28. use_face += 1
  29. else:
  30. not_use_face += 1
  31. #头像分类,做词云
  32. result2 = youtu.imagetag(imgFile)#调用图像标签接口
  33. image_tags += (",".join(list(map(lambda x:x['tag_name'],result2['tags'])))+',')#将标签文件连接到一起
  34. labels = [u'使用人脸头像',u'未使用人脸头像']
  35. counts = [use_face,not_use_face]
  36. colors = ['red','blue','yellow']
  37. plt.figure(figsize=(8,5), dpi=120)
  38. plt.axes(aspect=1)#此处的aspect=1表示正圆,取不同的值,表示的圆形状不同
  39. plt.pie(counts,#计数
  40. labels=labels,
  41. colors = colors,
  42. labeldistance = 1.1,#标签距离圆心的距离
  43. autopct = '%3.1f%%', #饼图区域文本格式
  44. shadow = False,#饼图是否有阴影
  45. startangle = 90,
  46. pctdistance = 0.6)
  47. plt.legend(loc = 'upper right')
  48. plt.title(u'%s的微信好友使用人脸头像的情况' %friends[0]['NickName'])
  49. plt.show()
  50. #绘制头像标签词云
  51. image_tags = image_tags.encode('iso8859-1').decode('utf-8')#加密解密
  52. plt.figure(figsize=(8,5), dpi=160)
  53. back_coloring = np.array(Image.open('face.jpg'))
  54. word_cloud = WordCloud(font_path = 'simkai.ttf',
  55. background_color = 'white',
  56. max_words = 1200,
  57. mask = back_coloring,
  58. max_font_size = 75,
  59. stopwords = STOPWORDS.add('写真照'),#ps:这个词有点太露骨了。
  60. random_state=45,
  61. width=600,
  62. height = 300,
  63. margin = 15)
  64. word_cloud.generate(image_tags)
  65. plt.imshow(word_cloud)
  66. plt.axis("off")
  67. plt.show()

结果如下:

大部分人还是没有使用人脸头像的。

女孩这个词十分显眼,推断是女生更喜欢是用个人头像或女星为头像。词云选择的乔布斯为底图背景。

3、签名分析:

好友签名分析,也分为两部分:(1)切词构造词云;(2)文本分析,生活态度

代码如下:

  1. def fun_analyse_Signature(friends):
  2. signatures = ''
  3. emotions = []
  4. for friend in friends:
  5. signature = friend['Signature']
  6. if signature != None:
  7. signature = signature.strip().replace("span","").replace("class","").replace("emoji","")#去除无关数据
  8. signature = re.sub(r'1f(\d.+)',"",signature)
  9. if len(signature) > 0:
  10. nlp = snownlp.SnowNLP(signature)
  11. emotions.append(nlp.sentiments)#nlp.sentiments:权值
  12. signatures += " ".join(jieba.analyse.extract_tags(signature,5))#关键字提取
  13. back_coloring = np.array(Image.open("xiaohuangren.jpg"))#图片可替换
  14. word_cloud2 = WordCloud(font_path = 'simkai.ttf',
  15. background_color = 'white',
  16. max_words = 1200,
  17. mask = back_coloring,
  18. margin = 15)
  19. word_cloud2.generate(signatures)
  20. image_colors = ImageColorGenerator(back_coloring)
  21. plt.figure(figsize=(8,5),dpi=160)
  22. plt.imshow(word_cloud2.recolor(color_func=image_colors))
  23. plt.axis("off")
  24. plt.show()
  25. word_cloud2.to_file("signatures.jpg")
  26. #人生观
  27. count_positive = len(list(filter(lambda x:x>0.66,emotions)))#大于0.66为积极
  28. count_negative = len(list(filter(lambda x:x<0.33,emotions)))#小于0.33为消极
  29. count_neutral = len(list(filter(lambda x:x>=0.33 and x <= 0.66,emotions)))
  30. labels = [u'积极',u'中性',u'消极']
  31. values =(count_positive,count_neutral,count_negative)
  32. plt.rcParams['font.sans-serif'] = ['simHei']
  33. plt.rcParams['axes.unicode_minus'] = False
  34. plt.xlabel("情感判断")
  35. plt.ylabel("频数")
  36. plt.xticks(range(3),labels)
  37. plt.legend(loc='upper right')
  38. plt.bar(range(3),values,color='rgb')
  39. plt.title(u'%s的微信好友签名信息情感分析情况' % friends[0]['NickName'])
  40. plt.show()

结果如下:

看来好友还都是蛮积极乐观的。

4、好友位置分析:

今天弄懂了pyecharts,就想起来可以用来做位置分析。

再分析之前,还要安装pychart库,直接pip。

pip install pyecharts

不懂得地方参考本篇文章:
http://blog.csdn.net/xxzj_zz2017/article/details/79601135

假设已经配置好环境,接下来进行分析,代码如下:

  1. from pyecharts import Map
  2. def get_attr(friends, key):
  3. return list(map(lambda user: user.get(key), friends))
  4. def fun_pos(friends)
  5. users = dict(province=get_attr(friends, "Province"),
  6. city=get_attr(friends, "City"),
  7. nickname=get_attr(friends, "NickName"))
  8. provinces = pd.DataFrame(users)
  9. provinces_count = provinces.groupby('province', as_index=True)['province'].count().sort_values()
  10. attr = list(map(lambda x: x if x != '' else '未知', list(provinces_count.index)))#未填写地址的改为未知
  11. value = list(provinces_count)
  12. map_1 = Map("微信好友位置分布图",title_pos="center",width=1000, height=500)
  13. map_1.add('', attr, value, is_label_show=True, is_visualmap=True, visual_text_color='#000',visual_range=[0,120])
  14. map_1

看来还是在北京的朋友多。

暂时只对好友进行了以上几方面的分析,感觉还是很有意思的。