基于Python的微信好友分析

“如果我比别人看得远,那是因为我站在巨人的肩膀上”–不知道牛顿说了没 本文利用Python3的itchat包简单的分析了一下自己的微信好友。

itchat

itchat

itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单。 使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人。 当然,该api的使用远不止一个机器人,更多的功能等着你来发现,比如这些。 该接口与公众号接口itchatmp共享类似的操作方式,学习一次掌握两个工具。 如今微信已经成为了个人社交的很大一部分,希望这个项目能够帮助你扩展你的个人的微信号、方便自己的生活。

运行环境

本文采用Python3,然后顺便吐槽下Python的向后不兼容真的好烦好烦,真的是体验超差。当然为了解决这个不是问题的小问题,我装了两个运行环境,毕竟是要站在巨人肩膀上去瞭望远方,那就站在两个肩膀上好了。sublime的Python3和2的配置(点进去往下翻。。。) =_+ 关于Pycharm里面Py2和Py3的转换更是简单,百度一下就ok。转换如下:

准备

需要安装itchat、matplotlib、numpy等依赖。 老生常谈之安装方式:

pip install itchat
pip install matplotlib
pip install numpy
pip install PIL/Pillow

注意:是不是上面的命令我早都忘了(我此时此刻觉得应该是这样的!),所以。。你们自己看着安装吧,反正不出问题都感觉不正常。按照使用的Python运行环境来安装相应的依赖包。pip/pip3

安装包介绍

itchat

本文的主角,我给它起个slogan吧“不仅仅是微信机器人。”

Matplotlib

Matplotlib是Python的可视化包。

Matplotlib是Python中最常用的可视化工具之一,可以非常方便地创建海量类型地2D图表和一些基本的3D图表。Matplotlib最早是为了可视化癫痫病人的脑皮层电图相关的信号而研发,因为在函数的设计上参考了MATLAB,所以叫做Matplotlib。Matplotlib首次发表于2007年,在开源和社区的推动下,现在在基于Python的各个科学计算领域都得到了广泛应用。Matplotlib的原作者John D. Hunter博士是一名神经生物学家,2012年不幸因癌症去世,感谢他创建了这样一个伟大的库。

numpy

Numpy是Python的科学计算包。

numpy(Numerical Python extensions)是一个第三方的Python包,用于科学计算。这个库的前身是1995年就开始开发的一个用于数组运算的库。经过了长时间的发展,基本上成了绝大部分Python科学计算的基础包,当然也包括所有提供Python接口的深度学习框架。

关于Matplotlib和numpy,推荐知乎上的一篇文章,感觉不错:给深度学习入门者的Python快速教程 - numpy和Matplotlib篇

PIL/Pillow

PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。 Pillow 是 PIL的对Python3支持的另外一个分支,当然他对Python2也兼容,由于PIL安装起来比较烦,而使用pip可以很轻松的安装Pillow,所以我选择Pillow使用,但是其核心还是PIL库的。

开始

好了,奠基石和肩膀都已经准备好了,上车!

 #-*-coding:utf-8-*-

import itchat
import re
import os
import matplotlib as mpl
from matplotlib import pyplot as plt
import numpy as np
import PIL.Image as Image
from os import listdir
import math


plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
zhfont = mpl.font_manager.FontProperties(fname='E:\PythonWorkSpace\WeChat\msyh.ttf', size=14)

有时候不得不说说外国的月亮比较圆啊。 使用的Matplotlib绘图是不能显示中文字符的,需要做一点小设置。 这两句:

plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

这一句为指定字体的设置:

zhfont = mpl.font_manager.FontProperties(fname='E:\PythonWorkSpace\WeChat\msyh.ttf', size=14)

关于上面的xx.tff为c盘windows下front字体包里的字体,我拷到目录下面了。 这样,我们就可以好好编程了+_+ ,想编个程序心也是蛮累的,不是在配置环境的路上,就是在改bug的路上,奈何程序员都是打不死的小强!

登录

爬取目标网站的时候,看看有没有 HTML样式更友好的移动版(把自己的请求头设置成处于移动设备的状态,然后接收网站移动版。移动版是一个获取数据非常好的渠道。当有一个网页很难爬去的时候,应该去试试它的移动版。)

微信就已经是移动设备上的了,腾讯粑粑又没有开发微信的API,所以我们只能另辟蹊径!反向思维->Web端有木有!This is itChat!

使用itchat登录Web端的微信,代码很简单:

itchat.auto_login(hotReload=True)

注: 传入True hotReload使得程序关闭后一定时间内也可以登录,该方法会生一个静态文件itchat.pkl,用于存储登陆的状态。即使程序关闭,一定时间内重新开启也可以不用重新扫码。

执行上面这句代码后会弹出一个Web微信登录的二维码QR,拿手机微信扫一扫后有以下显示:

这样就登录成功了!好简单有木有!用大神的包就是好,自己写模拟登陆的话还得抓包,分析报头,然后模拟登录。itchat简直良心到想哭。>_<

获取好友信息

friends = itchat.get_friends(update=True)  
# 爬取好友的相关信息,返回json文件

上面这个json文件就包括了微信好友的信息。

好友性别

直接上代码:

def friend_analysis(friends):
    labels = ['男', '女', '其他']
    data = [0, 0, 0]

    # friends[0] 是自己的信息
    for friend in friends[1:]:
        sex = friend["Sex"]
        if sex == 1:
            data[0] += 1
        elif sex == 2:
            data[1] += 1
        else:
            data[2] += 1

    fig = plt.figure()
    plt.pie(data, labels=labels,autopct="%.2f%%")
    plt.title("微信好友分析",fontsize=18,fontproperties=zhfont)
    plt.show()

labels是我们要画的饼图的标注。 男、女和其他性别的提取很简单了,当然需要注意的是如果没有我们准备阶段对于Matplotlib绘图的中文字符的处理,画出来的图是显示不了汉字滴! 运行结果:

看来我的微信好友男女差不多是1:1吧,还有那5.31%不知性别的好友,他们可能对性别的要求并不是那么严格吧,毕竟人与人也没那么多的隔阂是不是 =_*

区域分析

关于这个,自己之前写了一个简单的省份分析,就是从friends里去匹配Province,但是画的太丑了。所以,又找到一个肩膀

# extract the variables: NickName, Sex, City, Province, Signature
def get_features(friends):
    features = []
    for friend in friends:
        feature = {'NickName': friend['NickName'], 'Sex': friend['Sex'], 'City': friend['City'], 
                  'Province': friend['Province'], 'Signature': friend['Signature']}
        features.append(feature)
    return pd.DataFrame(features)
features = get_features(friends[1:])
print(features.columns)
features.head()
locations = features.loc[:, ['Province', 'City']]  # get location columns
locations = locations[locations['Province'] != '']  # clean empty city or province records
data = locations.groupby(['Province', 'City']).size().unstack()  # group by and count
count_subset = data.take(data.sum(1).argsort())[-20:]  # obtain the 20 highest data

# plot
subset_plot = count_subset.plot(kind='bar', stacked=True, figsize=(24, 24))

# set fonts
xtick_labels = subset_plot.get_xticklabels()
for label in xtick_labels: 
    label.set_fontproperties(font)
legend_labels = subset_plot.legend().texts
for label in legend_labels:
    label.set_fontproperties(font)
    label.set_fontsize(10)

plt.xlabel('Province', fontsize=20)
plt.ylabel('Number', fontsize=20)
plt.show()

上面这段代码更是厉害,提取了昵称,性别, 城市, 省份, 签名。 我只用他的省市画图部分locations,结果如下;

emmmm,放不大了,全图看不到,而且放大拖动起来巨卡,这个图也是辛苦了i3了。 从上面可以看到,我大陕西的乡党们在哪里!!我大西安的乡党们在哪里!! 排名第二、三的北京和广东,就是那群在北(上?)广深那一波人吧,向他们致敬! 从排名第四开始,某种程度上可以说是在陕西的各省学霸的分布了吧!尤其是河北、河南、山东!这些省份的同学一直都是学神一样的存在,陕西欢迎你们,学生生涯请轻虐+_+

签名

def signature_analysis(friends):
    signature_list = list()

    for friend in friends[1:]:
        signature = friend['Signature'].strip()
        signature_list.append(signature)
        print(friend['NickName'] + "\t" + signature)

这是从friends中分析出好友签名的,.strip()是用来删除空白符。 最后的输出是打印出昵称+签名。这个比较隐私就不展示了哈。有时间的还可以整理下这些签名,使用jieba分词+Wordcloud云词生成一个图片。

获取好友头像

def getImage(friends):
    #下载所有好友的头像图片
    num = 0
    for i in friends:
     img = itchat.get_head_img(i["UserName"])
     with open('./headImg/' + str(num) + ".png",'wb') as f:
      f.write(img)
      f.close()
      num += 1
    #获取文件夹内的文件个数
    length = len(os.listdir('./headImg'))
    #根据总面积求每一个的大小
    each_size = int(math.sqrt(float(810*810)/length))
    #每一行可以放多少个
    lines = int(810/each_size)
    #生成白色背景新图片
    image = Image.new('RGBA', (810, 810),'white')
    x = 0
    y = 0
    for i in range(0,length):
     try:
      img = Image.open('./headImg/' + str(i) + ".png")
     except IOError:
      print(i)
      print("Error")
     else:
      img = img.resize((each_size, each_size), Image.ANTIALIAS) #resize image with high-quality
      image.paste(img, (x * each_size, y * each_size))
      x += 1
      if x == lines:
       x = 0
       y += 1
    image.save('./headImg/' + "all.png")
    #通过文件传输助手发送到自己微信中
    itchat.send_image('./headImg/' + "all.png",'filehelper')
    image.show()

注释里写的应该算很清楚,需要注意的是: 开始想截取好友头像图片遇到了一个报错:

cannot write mode rgba as jpg

google后如下:

这是因为,JPG只有三个通道,而程序中一定用到了RGBA四个通道,所以程序不知道多出来的一个通道怎么处理,就会报错了。

解决如下:

  1. PNG图像有RGBA四个通道,而BMP和JPG图像只有RGB三个通道,所以我们可以将程序中所有图片的保存形式改为PNG.(本文采用的是这种方法。)
  2. 不想改变图片格式,就添加判断,进行转换
if len(toImage.split())==4:
   r,g,b,a=toImage.split()        #利用split和merge将通道从四个转换为三个
   toImage=Image.merge("RGB",(r,g,b))
    toImage.save(user + ".jpg")

“全世界的程序员们联合起来,那些bug的坑我们填一个它就少一个!” 结果:

来来来,找自己,找到三个自己就可以Bingo了…

最后,人生苦短,且行且珍惜

强烈建议仅使用小号(小号怎么会有好友?反正我给你们建议了…日后可不要搞个大新闻把我批判一番) 小道消息:从近期 (17年6月下旬)反馈来看,使用itchat及其他微信机器人(类爬虫程序)存在一定概率被限制登录的可能性。主要表现为无法登陆 Web 微信 (但不影响手机等其他平台)。 现在感觉都是爬一次少一次,Web微信有时候也登不上去+_+,前几天还被封号两天,微信消息只能看,不能回复,朋友圈不能评论,不能点赞,这对一个话痨来说简直就是无声的摧残!

最后的最后:反思

微信是不是太强大了,生活、学习、工作中真的是一分一秒都离不开!所以,还是建议大家时不时的用下QQ,用下微博,多和新老好友们尬聊下,不然,真到了微信垄断那一天,你我联系只能靠漂流瓶了!全看缘分!

后记

一晚上的访问量破三百了!三百!1024程序员节日快乐! 盖个戳!本文的访问数据,google analytics: 访问数据:

访问者国家和地区:

地理位置:

访问者城市分布:

服务提供商:

网页浏览分析:

访问者行为流:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏天天

网页图片的压缩优化

在网页建设过程中,图片的使用时必不可少的,甚至有些网站的80%~90%的部分都是图片,那么如此之多的图片怎么才能保证良好的用户体验,好的加载速度呢,其实从很多角...

22540
来自专栏用户2442861的专栏

ffmpeg 入门

http://einverne.github.io/post/2015/12/ffmpeg-first.html

39420
来自专栏FreeBuf

谈谈鱼叉式网络钓鱼黑箱粉碎机

美国加州大学伯克利分校和劳伦斯伯克利国家实验室(LBNL)的几位安全研究人员开发了鱼叉式网络钓鱼黑箱粉碎机,通过分析鱼叉式网络钓鱼攻击的根本特点设计了一组新的信...

42570
来自专栏Coding迪斯尼

VUE+WebPack精美游戏设计:实现微信红包铜钱转动特性和页面数据的本地存储

22940
来自专栏VRPinea

VR建模工具Blocks发布新版本,将更加易于使用

37590
来自专栏CDA数据分析师

手把手教你用Python分析电影 | 以《蚁人2》为例

《蚁人2》自8月24日在中国大陆上映以来,已经有将近一个月。作为《复仇者联盟3》之后漫威出品的首部电影,《蚁人2》对漫威宇宙电影的剧情承转起着关键作用。9月20...

28720
来自专栏编程

UG数控编程“新手必看”

1.坐标详解 1. 绝对坐标系:是模型空中的概念性位置和方向,将绝对坐标系为X=0,Y=0,Z=0.不可见不能移动。 2. 视图三重轴:是在建模最左下角有个正方...

249100
来自专栏黄希彤的专栏

用 FaaS 实现比优图更灵活的大量图片快速加工能力

前几天有个朋友的一个公益策划不小心泄漏后,实在在太火,在朋友圈刷屏了,导致后台服务器的处理能力成为瓶颈,不得不临时扩容了数十台服务器来处理大量的图片...

736130
来自专栏机器学习算法与Python学习

资源 | 让你事半功倍的小众Python库

Python 是世界上发展最快的编程语言之一。它一次又一次地证明了自己在开发人员和跨行业的数据科学中的实用性。Python 及其机器学习库的整个生态系统使全世界...

12020
来自专栏即时通讯技术

全面掌握移动端主流图片格式的特点、性能、调优等

图片通常是移动端应用流量耗费最多的部分,并且占据着重要的视觉空间。以大家最常用的即时通讯IM应用为例,应用中存在大量的图片数据往来(比如图片消息、用户相册、用户...

16320

扫码关注云+社区

领取腾讯云代金券