最近几天干啥都不来劲,昨晚偶然了解到 Python 里的 itchat 包,它已经完成了 wechat 的个人账号 API 接口,使爬取个人微信信息更加方便。鉴于自己很早之前就想知道诸如自己微信好友性别比例都来自哪个城市之类的问题,于是乎玩心一起,打算爬一下自己的微信。
首先,在终端安装一下 itchat 包。
- pip install itchat
安装完成后导入包,再登陆自己的微信。过程中会生产一个登陆二维码,扫码之后即可登陆。登陆成功后,把自己好友的相关信息爬下来。
- import itchat itchat.login() #爬取自己好友相关信息, 返回一个json文件 friends = itchat.get_friends(update = True)[0 : ]
有了上面的 friends 数据,我们就可以来做分析啦。
自己微信好友的男女比例
仔细观察了一下返回的数据结构,发现 "性别" 是存放在一个字典里面的,key 是 "Sex",男性值为 1,女性为 2,其他是不明性别的 (就是没有填的)。可以写个循环获取想要的性别数据,得到自己微信好友的性别比例。
- 初始化计数器 male = female = other = 0 #friends[0]是自己的信息,所以要从friends[1]开始
- for i in friends[1 : ] : sex = i["Sex"]
- if sex == 1 : male += 1 elif sex == 2 : female += 1
- else: other += 1 #计算朋友总数 total = len(friends[1 : ]) #打印出自己的好友性别比例 print("男性好友: %.2f%%" % (float(male) / total * 100) + "\n" + "女性好友: %.2f%%" % (float(female) / total * 100) + "\n" + "不明性别好友: %.2f%%" % (float(other) / total * 100))
打印的结果为:
男性好友:37.65%
女性好友:59.23%
不明性别好友:3.12%
啊,一不小心就暴露了自己女性朋友比较多的事实。然而为什么我现在还是一只汪?! 好了,再把这个数据用 R 画成图看看 (Python 作图真的是忍不了,代码就不放了):
自己微信好友的城市分布
再仔细观察 friends 列表,发现里面还包含了好友昵称、省份、城市、个人简介等等的数据,刚好可以用来分析好友城市分布,最好的方式是定义一个函数把数据都爬下来,存到数据框里,再进行分析。
- #定义一个函数,用来爬取各个变量 def get_var(var) : variable = []
- for i in friends: value = i[var] variable.append(value)
- return variable #调用函数得到各变量,并把数据存到csv文件中,保存到桌面 NickName = get_var("NickName") Sex = get_var('Sex') Province = get_var('Province') City = get_var('City') Signature = get_var('Signature') from pandas import DataFrame data = {
- 'NickName': NickName,
- 'Sex': Sex,
- 'Province': Province,
- 'City': City,
- 'Signature': Signature
- } frame = DataFrame(data) frame.to_csv('data.csv', index = True)
以上便得到一个叫 data 的 csv 桌面文件, 用 R 打开并简单做一下数据预处理,得到如下 (涉及隐私的已被预处理):
接着先根据省份、城市进行数据的分组和聚合,选择排名前二十的,利用 ggplot2 包画出如下的城市分布图 (代码太长,不放了,就是这么任性,有需要参考的直接向我拿):
看来我大部分的朋友都是在广东的 (不是废话吗),其中广东的朋友大部分集中在广、深、珠,第二名是在奥克兰, 接着是四川、澳门等。灰色的 NA 值是指没有设置自己所在地的朋友,一共有 70 多人。
另外,在国外的朋友由于微信的设置问题 (很多是直接跳过省份,只有城市可以选择的),很多国外的城市被误当成了省份。
再来一张图看看自己微信朋友在广东的具体分布 (取前八):
自己微信好友个性签名的自定义词云图
好玩的来了。之前已经爬下了每个好友的个性签名,刚好可以分析一下大伙儿个性签名时使用的高频词语是什么,顺便可以做个词云图。
先把原先爬下来的个性签名 (Signature) 打印出来,发现有很多本来是表情的,变成了 emoji、span、class 等等这些无关紧要的词,需要先替换掉,另外,还有类似<>/= 之类的符号,也需要写个简单的正则替换掉,再把所有拼起来,得到 text 字串。
- import re siglist = []
- for i in friends: signature = i["Signature"].strip().replace("span", "").replace("class", "").replace("emoji", "") rep = re.compile("1f\d+\w*|[<>/=]") signature = rep.sub("", signature) siglist.append(signature) text = "".join(siglist)
接着就可以把 JB,啊不,把结巴分词这个包搞进来分词。
- import jieba wordlist = jieba.cut(text, cut_all = True) word_space_split = " ".join(wordlist)
终于可以进入画图阶段了。可以根据自己想要的图片、形状、颜色画出相似的图形 (在这里,我使用的是我的头像,当然,为了颜色可以更加鲜艳使最后画出的词云图更加好看易辨,我先对自己的头像用 PS 做了一点小处理)。为此,我们需要把 matplotlib、wordcloud、numpy、PIL 等包搞进来。
- import matplotlib.pyplot as plt from wordcloud import WordCloud,
- ImageColorGenerator import numpy as np import PIL.Image as Image coloring = np.array(Image.open("/Users/apple/Desktop/wechat.jpg")) my_wordcloud = WordCloud(background_color = "white", max_words = 2000, mask = coloring, max_font_size = 60, random_state = 42, scale = 2, font_path = "/Library/Fonts/Microsoft/SimHei.ttf").generate(word_space_split) image_colors = ImageColorGenerator(coloring) plt.imshow(my_wordcloud.recolor(color_func = image_colors)) plt.imshow(my_wordcloud) plt.axis("off") plt.show()
运行上面的代码,得到下面的图:
看来,在我的微信好友的个人签名里,有人善于聆听,有人强调善良,有人重视灵魂,有人凝视人生。一直在等待,不放弃寻找。历尽曲折,不畏虚伪。真心如一,不能辜负。一步一生多努力,一起一切 one more dream(真编不下去了)。
以上是不是很有趣呢? 是不是又打开了一扇新世界的大门呢
我微信好友也不是太多,如果微信好友有几千个,可以得到几千条数据,分析一下还是很有价值的。
当然,itchat 包还有很多其他的功能还有待发掘,包括自动回复微信信息、自动添加好友、管理微信群等,有时间再慢慢摸索吧。
来源: http://www.tuicool.com/articles/QBJjmur