本文用到的包和工具如下:
微信团队用python写的面向对象模拟机器人登陆网页微信服务器,最为重要的是bot类和itchat类;具体看:https://wxpy.readthedocs.io/zh/latest/
百度收购了一个图形可视化javascript前端项目Echarts,该项目又扩展为pyecharts,可以动态渲染出国家、省份、城市图等。具体看:http://pyecharts.herokuapp.com/
一个图像处理的包,用于拼接图片。具体看:https://pillow.readthedocs.io/en/latest/
#导入需要的模块
from wxpy import * #用于调用bot类来进行访问微信数据
import math
from PIL import Image #用于拼接图片
import os #用于来生成路径
# 创建头像存放文件夹
def createFilePath():
wetChatDir = os.getcwd() + "\\wechat\\"
if not os.path.exists(wetChatDir):
os.mkdir(wetChatDir)
return wetChatDir
# 保存好友头像
def saveWetChatDir(wetChatDir):
bot = Bot()# 初始化机器人,扫码登陆
friends = bot.friends(update=True)
num = 0
for friend in friends:
friend.get_avatar(wetChatDir + '\\' + str(num) + ".jpg")
print('好友昵称:%s' % friend.nick_name)
num = num + 1
def jointWetChatDir(path):
# 获取文件夹内头像个数
length = len(os.listdir(path))
# 设置画布大小
image_size = 2560
# 设置每个头像大小
each_size = math.ceil(2560 / math.floor(math.sqrt(length)))
# 计算所需各行列的头像数量
x_lines = math.ceil(math.sqrt(length))
y_lines = math.ceil(math.sqrt(length))
image = Image.new('RGB', (each_size * x_lines, each_size * y_lines))
x = 0
y = 0
for (root, dirs, files) in os.walk(path):
for pic_name in files:
# 增加头像读取不出来的异常处理
try:
with Image.open(path + pic_name) as img:
img = img.resize((each_size, each_size))
image.paste(img, (x * each_size, y * each_size))
x += 1
if x == x_lines:
x = 0
y += 1
except IOError:
print("头像读取失败")
img = image.save(os.getcwd() + "/wetchat.png")
print('微信好友头像拼接完成!')
if __name__ == '__main__':
wetChatDir = creat_filepath()
saveWetChatDir(wetChatDir)
jointWetChatDir(wetChatDir)
生成wechat文件夹,里面会下载你所有的好友图片。同时也会生成一张wetchat.png即为拼接结果。好友超过2000,可能会犯密集恐惧症。图片超过20M了,放张截图吧。
import itchat
import pandas as pd
from pyecharts import Pie, Map, Style, Page, Bar
# 根据key值得到对应的信息
def get_key_info(friends_info, key):
return list(map(lambda friend_info: friend_info.get(key), friends_info))
# 获得所需的微信好友信息
def get_friends_info():
itchat.auto_login(hotReload=True)
friends = itchat.get_friends()
friends_info = dict(
# 省份
province = get_key_info(friends, "Province"),
# 城市
city = get_key_info(friends, "City"),
# 昵称
nickname = get_key_info(friends, "Nickname"),
# 性别
sex = get_key_info(friends, "Sex"),
# 签名
signature = get_key_info(friends, "Signature"),
# 备注
remarkname = get_key_info(friends, "RemarkName"),
# 用户名拼音全拼
pyquanpin = get_key_info(friends, "PYQuanPin")
)
return friends_info
# 性别分析
def analysisSex():
friends_info = get_friends_info()
df = pd.DataFrame(friends_info)
sex_count = df.groupby(['sex'], as_index=True)['sex'].count()
temp = dict(zip(list(sex_count.index), list(sex_count)))
data = {}
data['保密'] = temp.pop(0)
data['男'] = temp.pop(1)
data['女'] = temp.pop(2)
# 画图
page = Page()
attr, value = data.keys(), data.values()
chart = Pie('微信好友性别比')
chart.add('', attr, value, center=[50, 50],redius=[30, 70], is_label_show=True,legend_orient='horizontal',legend_pos='center',legend_top='bottom', is_area_show=True)
page.add(chart)
page.render('analysisSex.html')
# 省份分析
def analysisProvince():
#得到朋友信息
friends_info = get_friends_info()
#存到pd元组中
df = pd.DataFrame(friends_info)
#省排序
province_count = df.groupby('province', as_index=True)['province'].count().sort_values()
temp = list(map(lambda x: x if x != '' else '未知',list(province_count.index)))
# 画图
page = Page()
style = Style(width=1100, height=600)
style_middle = Style(width=900, height=500)
attr, value = temp, list(province_count)
chart1 = Map('好友分布(中国地图)', **style.init_style)
chart1.add('', attr, value, is_label_show=True, is_visualmap=True, visual_text_color='#000')
page.add(chart1)
chart2 = Bar('好友分布柱状图', **style_middle.init_style)
chart2.add('', attr, value, is_stack=True, is_convert=True,
label_pos='inside', is_legend_show=True, is_label_show=True)
page.add(chart2)
page.render('analysisProvince.html')
# 具体省份分析
def analysisCity(province):
friends_info = get_friends_info()
df = pd.DataFrame(friends_info)
temp1 = df.query('province == "%s"' % province)
city_count = temp1.groupby('city', as_index=True)['city'].count().sort_values()
attr = list(map(lambda x: '%s市' % x if x != '' else '未知', list(city_count.index)))
value = list(city_count)
# 画图
page = Page()
style = Style(width=1100, height=600)
style_middle = Style(width=900, height=500)
chart1 = Map('%s好友分布' % province, **style.init_style)
chart1.add('', attr, value, maptype='%s' % province, is_label_show=True,
is_visualmap=True, visual_text_color='#000')
page.add(chart1)
chart2 = Bar('%s好友分布柱状图' % province, **style_middle.init_style)
chart2.add('', attr, value, is_stack=True, is_convert=True, label_pos='inside', is_label_show=True)
page.add(chart2)
page.render('analysisCity.html')
#主函数
if __name__ == '__main__':
analysisSex()
analysisProvince()
analysisCity("湖南")