微信好友大揭秘

2019-07-01 15:29:32 浏览数 (1)

每天自己手机应用使用时间排行榜,微信都毫不意外地占据榜首,每天睁开眼的第一件事就是拿起手机打开微信,查收消息,关注朋友圈好友的动态。但是除了这些微信还有哪些好玩的东西呢?今天就用python对自己所有微信好友做一次数据分析,看看自己的微信好友存在哪些有趣的东西。

程序介绍

将使用Python抓取微信数据,并对获取到的数据进行全面分析,包含好友性别、地理位置分布、个性签名等,逐一进行分析,分析到你怀疑人生

整个过程分为四步:

  • 获取数据
  • 处理数据
  • 存储数据
  • 数据可视化

具体实现

获取数据:

微信好友数据的获取,可以通过itchat库,itchat是一个开源的微信个人号的接口,可以实现信息收发、获取好友列表等功能。

代码语言:javascript复制
import itchat
# 获取数据
def get_data():
   itchat.auto_login()
   friends = itchat.get_friends(
   update=True)
   return friends

处理数据

对获取的数据进行处理,筛选出需要的数据。

通过对返回的用户信息进行分析,发现列表中第一个元素是用户自己,可以排除掉,同时我们只取需要的字段数据。

代码语言:javascript复制
# 处理数据
def parse_data(data):
  friends = []
  for item in data[1:]:
    friend = {
     'NickName': item['NickName'],
    'RemarkName': item['RemarkName'],
    'Sex': item['Sex'],
    'Province': item['Province'],
    'City': item['City'],
    'Signature':
     item['Signature'].replace('n',' ').
     replace(',', ' '),
    'StarFriend': item['StarFriend'],
    'ContactFlag': item['ContactFlag']
        }
    print(friend)
    friends.append(friend)
  return friends

存储数据

为了便于分析数据并进行可视化操作,这里将数据存储到文本文件中,因个人隐私原因做了打码处理。

代码语言:javascript复制
# 存储数据,存储到文本文件
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,%dn'%(
         item['NickName'],
         item['RemarkName'],
         item['Sex'],
         item['Province'],
         item['City'],
         item['Signature'],
         item['StarFriend'],
         item['ContactFlag']))

数据可视化

没有使用Matplotlib做可视化处理而是使用了pyecharts,pyecharts是一个用于生成Echarts图表的类库,便于在Python中根据数据生成可视化的图表。

好友性别分析

代码语言:javascript复制
# 获取所有性别
sex = []
with open('friends.txt', mode='r',
          encoding='utf-8') as f:
    rows = f.readlines()
    for row in rows:
        sex.append(row.split(',')[2])
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.render('好友性别比例.html')

好友主要是男性,占比59%,可见自己的好友中男女比例失衡。仔细想想自己的微信好友里大多是上大学以后的同学朋友,自己是计算机专业,以男生为主,工所以男女比例失衡是正常的。

好友位置分析

根据 pyecharts使用教程 : 自从 v0.3.2 开始,为了缩减项目本身的体积以及维持 pyecharts 项目的轻量化运行,pyecharts 将不再自带地图 js 文件。如用户需要用到地图图表,可自行安装对应的地图文件包。

(1)、全球国家地图:

echarts-countries-pypkg (1.9MB): 世界地图和 213 个国家,包括中国地图 (2)、中国省级地图:

echarts-china-provinces-pypkg (730KB):23 个省,5 个自治区 (3)、中国市级地图:

echarts-china-cities-pypkg (3.8MB):370 个中国城市 (4)、中国县区级地图:

echarts-china-counties-pypkg (4.1MB):2882 个中国县·区 (5)、中国区域地图:

echarts-china-misc-pypkg (148KB):11 个中国区域地图,比如华南、华北

代码语言:javascript复制
#好友位置分析
from collections import Counter
from pyecharts import Geo
import json
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)
  data=Counter(cities).most_common()
  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)
   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')

不出所料好友最多的地方是日照,从小在日照长大,专科学校又是在日照上的,所以是很正常的,现在在青岛上本科,之前在郑州工作过在济南学习过,所以这几个城市的好友也比较多。

个性签名词云图

生成词云图在之前的文章中有所介绍,同样使用jieba分词库。朋友的个签是千奇百怪,所以做了一些词的屏蔽,终究还有一些特殊表情没有屏蔽。

代码语言:javascript复制
import jieba
import matplotlib.pyplot as plt
fromwordcloudimportWordCloud,
               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)  
words = ' '.join(split)
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('5.jpg')

wc = WordCloud(width=1024, 
    height=768, 
    background_color='white',
    mask=bg_image,
   font_path='D:PycharmProjects
            musicSIMYOU.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')

词云图中可以看到,微信好友个性签名中出现频率较高的词汇有:自己,一个,改变,心存,善念,欢迎,关注。整体来看,我的微信好友应该是心存善念的公众号运营者居多

(这都是什么鬼,是时候请一波好友了)当然还是有很多正能量词语的。

好友头像拼接

好友头像拼接是将所有的微信头像拼接成一张大图,因为好友过多只获取了一部分好友的头像。

代码语言:javascript复制
import os
import itchat
import math
from PIL import Image
def get_image():
    itchat.auto_login()
    friends = itchat.get_friends(
                update=True)
   base_path = 'headImages'
   if not os.path.exists(base_path):
       os.mkdir(base_path)
   for friend in friends:
      img_data = itchat.get_head_img(
        userName=friend['UserName'])
     img_name = friend['RemarkName']
      iffriend['RemarkName'] != '' 
        else friend['NickName']
      img_file=os.path.join(base_path, 
      img_name   '.jpg')
      print(img_file)
      with open(img_file, 'wb') as file:
        file.write(img_data)

拼接头像

代码语言:javascript复制
def join_image():
    base_path = 'headImages'
    files = os.listdir(base_path)
    each_size = int(
    math.sqrt(float(640*640)/len(files)))
    lines=int(640/each_size)
    image=Image.new('RGB', (640, 640))
    x = 0
    y = 0
    for file_name in files:
       img = Image.open(
       os.path.join(base_path,file_name))
       img=img.resize((each_size,
        each_size),Image.ANTIALIAS)
       image.paste(img, 
         (x * each_size, y * each_size))
       x  = 1
       if x == lines:
            x = 0
         y  = 1
    image.save('im.jpg')

看到图片庆幸自己没有获取所有好友的头像,因为自己有密集恐惧症。

程序参考:CSDN汤小洋

0 人点赞