查看原文
其他

微信好友大揭秘

Ahab Ahab杂货铺 2019-02-15

                                                                                                  


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


程序介绍

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

整个过程分为四步:

  • 获取数据

  • 处理数据

  • 存储数据

  • 数据可视化

具体实现

获取数据:

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

import itchat
# 获取数据
def get_data():
  itchat.auto_login()
  friends = itchat.get_friends(
  update=True)
  return friends

处理数据

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

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


# 处理数据
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


存储数据


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


# 存储数据,存储到文本文件
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']))




数据可视化


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


好友性别分析


# 获取所有性别
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 个中国区域地图,比如华南、华北


#好友位置分析
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分词库。朋友的个签是千奇百怪,所以做了一些词的屏蔽,终究还有一些特殊表情没有屏蔽。


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\
           music\SIMYOU.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')




词云图中可以看到,微信好友个性签名中出现频率较高的词汇有:自己,一个,改变,心存,善念,欢迎,关注。整体来看,我的微信好友应该是心存善念的公众号运营者居多(这都是什么鬼,是时候请一波好友了)当然还是有很多正能量词语的。


好友头像拼接


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

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)

拼接头像

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汤小洋

            

欢迎您的点赞和分享

▲长按关注此公众号




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存