itchat+pyecharts+jieba+PIL实现可视化分析微信好友

本次涉及到的知识:

  1. itchat模块的使用
  2. pyecharts模块的使用
  3. jieba模块的使用
  4. PIL模块的使用

python版本

python3.6

准备工作

1.安装itchat、pyecharts、jieba、pillow模块

pip3 install itchat
pip3 install pyecharts
pip3 install jieba
pip3 install pillow

2.阅读文档

itchat模块可以实现登录微信,获取微信好友的信息等等功能。itchat文档:https://itchat.readthedocs.io/zh/latest/api/

pyecharts模块可以实现数据可视化,pyecharts文档:http://pyecharts.org/#/zh-cn/charts_configure?id=xyaxis

jieba模块可以实现中文分词,结巴分词文档:https://github.com/fxsjy/jieba

编写代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import itchat
import jieba
import math
from pyecharts import Pie, Geo, WordCloud
import PIL.Image as Image


class Analyse(object):

    def __init__(self, friends, uuid):
        super(Analyse, self).__init__()
        self.friends = friends
        # 停用词文件
        self.break_words_file = '哈工大停用词.txt'
        # 停用词
        self.break_words = []
        self.uuid = uuid

    # 生成男女性别比例图
    def friends_sex_ratio(self):
        sex = ['未知', '男', '女']
        ratio = [0, 0, 0]
        for item in self.friends:
            ratio[item['Sex']] += 1
        pie = Pie(self.friends[0]['NickName'] +
                  "的微信好友性别比例", title_pos='center')
        pie.add(
            "",
            sex,
            ratio,
            radius=[40, 75],
            label_text_color=None,
            is_label_show=True,
            legend_orient="vertical",
            legend_pos="left",
            background_color='#FFF'
        )
        pie.render('./html/%s_sex_ratio.html' % self.uuid)
        pie.render(path='./img/%s_sex_ratio.png' % self.uuid)
        # 通过文件传输助手发送到自己微信中
        itchat.send_image('./img/%s_sex_ratio.png' %
                          self.uuid, 'filehelper')

    # 生成好友地图分布图和热力图
    def friends_map(self):
        citys = []
        values = []
        geo = Geo(
            self.friends[0]['NickName'] + "的微信好友分布图",
            title_color="#fff",
            title_pos="center",
            width='100wh',
            height='100vh',
            background_color="#404a59",
        )
        for item in self.friends:
            if item['City'] not in citys and item['City'] and self.is_chinese(item['City']):
                citys.append(item['City'])
                values.append(1)
            elif item['City'] and self.is_chinese(item['City']):
                values[citys.index(item['City'])] += 1
        types = ['heatmap', 'scatter']
        for item in types:
            geo.add(
                "",
                citys,
                values,
                visual_range=[0, max(values)],
                visual_text_color="#fff",
                symbol_size=15,
                # type为地图样式,scatter为地图,heatmap为热力图
                type=item,
                tooltip_formatter="{b}:{c}",
                is_visualmap=True,
                background_color='#FFF'
            )
            geo.render('./html/%s_frends_city_%s.html' %
                       (self.uuid, item))
            geo.render(path='./img/%s_frends_city_%s.png' %
                       (self.uuid, item))
            itchat.send_image('./img/%s_frends_city_%s.png' %
                              (self.uuid, item), 'filehelper')

    # 判断是否是中文
    def is_chinese(self, words):
        for word in words:
            if not(u'\u4e00' <= word <= u'\u9fa5'):
                return False
        return True

    # 获取停用词
    def get_break_stopWords(self):
        with open(self.break_words_file, 'r', encoding='UTF-8-sig') as f:
            for line in f:
                self.break_words.append(line.replace('\n', ''))
        f.close()

    # 删除停用词以及非中文
    def delete_break_words(self, word):
        if word not in self.break_words:
            if self.is_chinese(word):
                return word

    # 生成好友签名词云
    def signature_cloud(self):
        words = []
        count = []
        # 获取停用词
        self.get_break_stopWords()
        # 清洗、统计数据
        for item in self.friends:
            for word in jieba.lcut(item['Signature']):
                if word not in words and self.is_chinese(word):
                    words.append(self.delete_break_words(word))
                    count.append(1)
                elif self.is_chinese(word):
                    count[words.index(self.delete_break_words(word))] += 1
        wordcloud = WordCloud('%s的微信好友签名词云' % self.friends[0]['NickName'], width=1300,
                              height=620, background_color='#FFF', title_pos='center')
        wordcloud.add("", words, count, shape='circle')
        wordcloud.render('./html/%s_signature_word_cloud.html' % self.uuid)
        wordcloud.render(
            path='./img/%s_signature_word_cloud.png' % self.uuid)
        itchat.send_image('./img/%s_signature_word_cloud.png' %
                          self.uuid, 'filehelper')

    # 将所有好友的头像拼成一张图
    def head_img_cloud(self):
        num = 1
        for item in self.friends:
            print('当前下载:第%d个好友的头像,昵称:%s' % (num, item['NickName']))
            img = itchat.get_head_img(userName=item["UserName"])
            with open('./head_img/%s_head_img-%d.jpg' % (self.uuid, num), 'wb') as f:
                f.write(img)
            f.close()
            num += 1
        print('开始生成图云...')
        each_size = int(math.sqrt(float(640 * 640) / len(self.friends)))
        lines = int(640 / each_size)
        # 生成白色背景新图片
        image = Image.new('RGBA', (640, 640), 'white')
        # 拼接好友头像
        x = 0
        y = 0
        for i in range(1, len(self.friends)):
            try:
                # 读取头像文件
                img = Image.open('./head_img/%s_head_img-%d.jpg' %
                                 (self.uuid, i))
            except Exception as e:
                print(e)
            else:
                # 设置头像图片尺寸
                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("./img/%s_all_head_img.png" % self.uuid)
        print('生成完成')
        itchat.send_image("./img/%s_all_head_img.png" %
                          self.uuid, 'filehelper')

if __name__ == "__main__":
    # 登录微信
    itchat.auto_login(hotReload=True)
    friends = itchat.get_friends(update=True)
    analyse = Analyse(friends, itchat.get_QRuuid())
    analyse.friends_sex_ratio()
    analyse.friends_map()
    analyse.signature_cloud()
    analyse.head_img_cloud()

还需要在当前目录下创建三个文件才能正常运行:

head_img:保存好友头像

img:保存可视化结果图片

html:保存可视化结果html文件

最终结果

1.好友性别比例

程序员不愧是程序员,好友里面女生挺少的。

2.好友地理位置分布图

才发现自己加了这么多地方的好友呀。 

3.好友地理位置热力图

由于我是居住在成都,因此成都的好友当然很多啦 

4.好友签名词云

努力、人生。。。加油吧骚年!!! 

5.好友头像 

哇哦。。。

最后

关于怎样将所有微信好友的头像拼接成一张图片,可以参考https://blog.csdn.net/Monster_H7/article/details/80370204

关于出现地理位置不匹配的错误,请下载我github项目里的city_coordinates.json文件,并将其复制到$PYTHON_HOMR\Lib\site-packages\pyecharts\datasets目录下。pyecharts自带的地理位置库真的坑,很多地方都匹配不到。

关于哈工大停用词文件,请到我的github下载。

本次项目github地址:https://github.com/RickyHal/analyse_wechat_friends

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值