Python获取微信好友信息进行分析
这件好玩的事情对于熟练掌握Python的大神简直就是小菜一碟,但对于我而言还是有点难度的,所以参考了一些大神的博客总结了一番,在正式之前,先把python环境搭建好
安装itchat
pip install itchat
itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单。
使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人。
使用itchat
// 使用itchat
import itchat
登录微信
# 如果加上hotReload==True,那么就会保留登录的状态
# 至少在后面的几次登录过程中不会再次扫描二维码
# 该参数生成一个静态文件itchat.pkl用于存储登录状态
# 在保留状态的时候不要关闭二维码图片窗口,不然需要重新扫描二维码登录
itchat.auto_login(hotReload=True)
获取好友信息
# 通过 get_friends()方法获取所有微信好友
friends = itchat.get_friends(update=True)
遍历好友列表,保存好友列表和头像
for count, line in enumerate(friends):
# 由于每一个朋友信息是以字典的形式保存,要先转换成字符串的形式
# 保存好友信息到txt文件
str1 = str(line)
f.writelines(str1 + "\n")
# 根据UserName获取好友头像,保存到提前创建好的img目录
img = itchat.get_head_img(userName=line['UserName'])
imgFile = open("img/" + str(count) + ".jpg", "wb")
imgFile.write(img)
imgFile.close()
遍历的时候用到了Python enumerate函数:
描述
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
对好友头像进行拼接
- 创建一个新的python文件createimg.py
- 安装PIL
PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了。其官方主页为:PIL。 PIL历史悠久,原来是只支持python2.x的版本的,后来出现了移植到python3的库pillow,pillow号称是friendly fork for PIL,其功能和PIL差不多,但是支持python3。
- 执行代码如下
import os, random, math
from PIL import Image
# 对头像进行拼接
def createImg():
x = 0
y = 0
# os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表
imgs = os.listdir('img')
# 打乱图片
random.shuffle(imgs)
# 创建640*640的图片用于填充所有头像
newImg = Image.new("RGBA", (640, 640))
# 以640*640来拼接图片,大图片面积除以小图片数量得到小图片的面积
# 然后math.sqrt()开平方计算每张小图片的宽高
width = int(math.sqrt(640 * 640 / len(imgs)))
# 每行图片数
numLine = int(640 / width)
for i in imgs:
img = Image.open("img/" + i)
# 缩小图片
img = img.resize((width, width), Image.ANTIALIAS)
# 拼接图片,一行排满,换行拼接
newImg.paste(img, (x * width, y * width))
x += 1
if x > numLine:
x = 0
y += 1
newImg.save("all.png")
createImg()
性别统计
import itchat
import matplotlib.pyplot as plt
def getSex():
itchat.auto_login(hotReload=True)
friends = itchat.get_friends(update=True)
sex = dict()
for f in friends:
if f['Sex'] == 1:
sex["man"] = sex.get("man", 0) + 1
elif f["Sex"] == 2:
sex["women"] = sex.get("women", 0) + 1
else:
sex["unknown"] = sex.get("unknown", 0) + 1
# 柱状图展示
for i, key in enumerate(sex):
plt.bar(key, sex[key])
plt.show()
getSex()
哇哈哈哈哈我的朋友男女比例非常均衡 ~
朋友圈个性签名生成词云图
1.先获取朋友的数据签名,保存到文本文件
import itchat, re
def signature():
itchat.auto_login(hotReload=True)
friends = itchat.get_friends(update=True)
file = open("mood.txt", "a", encoding="utf-8")
for f in friends:
# strip()方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
# 注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
sign = f["Signature"].strip().replace("emoji", "").replace("span", "").replace("class", "")
print(sign)
# 正则匹配
reg = re.compile('1f\d+\w*|[<>/=]')
# sub() 替换,第一个参数为空的话就是正则表达式本身
sign = reg.sub("", sign)
file.write(sign + "\n")
signature()
2.用获得的个性签名生成词云图
(1) 安装wordcloud:pip install wordcloud
!!!可能安装失败,这是因为python的版本问题,打开链接https://www.lfd.uci.edu/~gohlke/pythonlibs/:找到对应版本的word下载到python所在的文件夹
打开命令管理器,cd去到它所在的文件夹,pip install ***
***为下载的该wordcloud文件的文件名,安装完即可
(2) 安装jieba:一个中文分词工具:pip install jieba
import wordcloud
import jieba
import matplotlib.pyplot as plt
# 生成词云图
def create_word_cloud(filename):
# 读取文件内容
text = open("{}.txt".format(filename), encoding='utf-8').read()
# 结巴分词
wordlist = jieba.cut(text, cut_all=True)
wl = " ".join(wordlist)
w = wordcloud.WordCloud(
# 设置背景颜色
background_color="white",
# 设置最大显示的词云数
max_words=2000,
# 设置字体:这是我从在电脑字体中复制到项目的
font_path='./font/msyh.ttc',
height=500,
width=500,
# 字体最大值
max_font_size=100,
# 设置有多少种随机生成状态,即有多少种配色方案
random_state=30,
)
# 生成词云图
myword = w.generate(wl)
# 展示词云图
plt.imshow(myword)
plt.axis("off")
plt.show()
# 把词云图保存下来
w.to_file("sign.png")
create_word_cloud("mood")
不用jieba也可以,这样生成的词云图分布的是句子
好友的城市分布
import itchat
import matplotlib.pyplot as plt
itchat.auto_login(hotReload=True)
friends = itchat.get_friends(update=True)
province_dict = {}
city_dict = {}
for f in friends:
province = f['Province']
city = f['City']
if province and province not in province_dict.keys():
province_dict[province] = 1
elif province:
province_dict[province] += 1
if city and city not in city_dict.keys():
city_dict[city] = 1
elif city:
city_dict[city] += 1
# 区域Top10
province_dict_top10 = sorted(province_dict.items(), key=lambda x: x[1], reverse=True)[0:10]
# 城市Top10
city_dict_top10 = sorted(city_dict.items(), key=lambda y: y[1], reverse=True)[0:10]
# 柱状图展示,原理一样,在这里只展示省份
prov_nm, prov_num = [], [] # 省会名 + 数量
for prov_data in province_dict_top10:
prov_nm.append(prov_data[0])
prov_num.append(prov_data[1])
colors = ['#00FFFF', '#7FFFD4', '#F08080', '#90EE90', '#AFEEEE',
'#98FB98', '#B0E0E6', '#00FF7F', '#FFFF00', '#9ACD32']
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 纵坐标
index = range(len(prov_num))
print(index) # 10
plt.bar(index, prov_num, color=colors, width=0.5, align='center')
plt.xticks(range(len(prov_nm)), prov_nm) # 横坐轴标签
for x, y in enumerate(prov_num):
# 在柱子上方1.2处标注值
plt.text(x, y + 1.2, '%s' % y, ha='center', fontsize=10)
plt.ylabel('省会好友人数') # 设置纵坐标标签
prov_title = '微信好友区域Top10'
plt.title(prov_title) # 设置标题
plt.savefig('./微信好友区域Top10.png') # 保存图片
plt.show()
可以把柱状图这一块封装成一个函数
import itchat
import matplotlib.pyplot as plt
itchat.auto_login(hotReload=True)
friends = itchat.get_friends(update=True)
province_dict = {}
city_dict = {}
for f in friends:
province = f['Province']
city = f['City']
if province and province not in province_dict.keys():
province_dict[province] = 1
elif province:
province_dict[province] += 1
if city and city not in city_dict.keys():
city_dict[city] = 1
elif city:
city_dict[city] += 1
# 区域Top10
province_dict_top10 = sorted(province_dict.items(), key=lambda x: x[1], reverse=True)[0:10]
# 城市Top10
city_dict_top10 = sorted(city_dict.items(), key=lambda y: y[1], reverse=True)[0:10]
# 柱状图展示
def show_bar(data):
nm, num = [], [] # 省会名 + 数量
for item in data:
nm.append(item[0])
num.append(item[1])
colors = ['#00FFFF', '#7FFFD4', '#F08080', '#90EE90', '#AFEEEE',
'#98FB98', '#B0E0E6', '#00FF7F', '#FFFF00', '#9ACD32']
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
# 纵坐标
index = range(len(num))
print(index) # 10
plt.bar(index, num, color=colors, width=0.5, align='center')
plt.xticks(range(len(nm)), nm) # 横坐轴标签
for x, y in enumerate(num):
# 在柱子上方1.2处标注值
plt.text(x, y + 1.2, '%s' % y, ha='center', fontsize=10)
plt.ylabel('区域好友人数') # 设置纵坐标标签
prov_title = '微信好友区域Top10'
plt.title(prov_title) # 设置标题
plt.savefig('./微信好友区域Top10.png') # 保存图片
plt.show()
show_bar(city_dict_top10)