用python快速分析你的微信好友

简介: 写在前面  itchat基于python开发,封装了大量调取微信功能的接口,使得开发人员可以快速基于这个框架来完成一些微信操作,在这之前我们要做的就是扫码登录,实际上这相当于登录网页版的微信(新注册的账号似乎不支持)。

写在前面

  itchat基于python开发,封装了大量调取微信功能的接口,使得开发人员可以快速基于这个框架来完成一些微信操作,在这之前我们要做的就是扫码登录,实际上这相当于登录网页版的微信(新注册的账号似乎不支持)。更多介绍在官网和Github上都有详细的文档。
  下面介绍基于itchat完成微信数据(好友、群聊等)的分析和展示。

环境说明

  • python3
  • numpy
  • matplotlib
  • pillow

相关代码

  • wx_itchat.py
import os
import math

import itchat
import numpy as np
import PIL.Image as Image
import matplotlib.pyplot as plt

# 抽取出来的工具类
from utils import match_util


class WxChat(object):

    def __init__(self):
        """初始化(扫码登录或手机端确认)"""
        itchat.auto_login(hotReload=True)

        # 登录用户
        self.login_user = None
        # 好友总数
        self.num_of_friend = 0
        # 男性好友数
        self.male_num = 0
        # 女性好友数
        self.female_num = 0
        # 未知性别好友数
        self.unknown_gender = 0
        # K=省名 V=人数
        self.num_of_province = {}
        # 未知省份
        self.unknown_province = '其它'
        # 绘图大小
        plt.figure(figsize=(6.4, 4.8))
        # 图片存放文件夹
        self.images_dir = 'wxImages'
        self.avatar_dir = '{}{}{}'.format(self.images_dir, os.sep, "avatarImages")
        if not os.path.exists(self.images_dir):
            os.mkdir(self.images_dir)
            os.mkdir(self.avatar_dir)

    def _reset_data(self):
        """数据重置"""

        self.male_num = 0
        self.female_num = 0
        self.unknown_gender = 0
        self.num_of_province = {}

    def analysis_friends(self):
        """获取好友列表 , 第一个是本人"""
        print("--->开始分析您的好友数据")

        all_user = itchat.get_friends(update=True)
        self.login_user = all_user[0]
        self.num_of_friend = len(all_user) - 1
        friends = all_user[1:]
        for i, friend in enumerate(friends):
            self._count_sex(friend['Sex'])
            self._count_province(friend['Province'])

            nickname = friend['NickName']  # 昵称
            remark = friend['RemarkName']  # 备注
            signature = ''.join(friend['Signature'].split())  # 个性签名
            # city = friend['City'] # 所在城市

            # 下载好友头像(不包括自己)
            avatar_data = itchat.get_head_img(userName=friend["UserName"])
            with open("{}{}{}.jpg".format(self.avatar_dir, os.sep, i), 'wb') as f:
                f.write(avatar_data)

            print("%d.好友昵称: %s ,备注: %s ,个性签名: %s " % (i + 1, nickname, remark, signature))

        print('共有 %d 位微信好友 , 其中男性好友 %d 位,女性好友 %d 位 , %d 位未知性别好友' % (
            self.num_of_friend, self.male_num, self.female_num, self.unknown_gender))

        # 省份数据处理(可选)
        self._handle_province(self.num_of_friend)
        # 绘制性别柱图, 绘制省份饼图(可选)
        title = 'WeChatFriends'
        wx._plt_gender_bar(title), wx._plt_province_pie(title)
        # 将头像拼图(可选)
        self._puzzle_avatar(title)
        self._reset_data()

    def analysis_chat_rooms(self):
        """获取群聊列表"""
        print("--->开始分析您的群聊数据")

        chat_rooms = itchat.get_chatrooms(update=True)
        for chat_room in chat_rooms[:-1]:
            chat_room_name = chat_room['NickName']  # 群聊名称
            user_name = chat_room['UserName']  # 群聊id标志
            room = itchat.update_chatroom(user_name, detailedMember=True)
            member_count = room['MemberCount']  # 群聊人数
            # 群聊用户列表
            for member in room['MemberList']:
                # avatar = 'https://wx.qq.com'.format(member['HeadImgUrl']) # 头像
                self._count_sex(member['Sex'])
                self._count_province(member['Province'])

            print('群聊 %s 共有 %d 人 , 其中 %d 位男性 , %d 位女性 , %d 位性别未知' % (
                chat_room_name, member_count, self.male_num, self.female_num, self.unknown_gender))

            # 省份数据处理(可选)
            self._handle_province(member_count)
            # 绘制性别柱图, 省份饼图(可选)
            self._plt_gender_bar(chat_room_name), self._plt_province_pie(chat_room_name)
            self._reset_data()

    def _count_sex(self, sex):
        """统计性别情况"""

        # 0-未知 , 1-男 , 2-女
        if sex == 1:
            self.male_num += 1
        elif sex == 2:
            self.female_num += 1
        else:
            self.unknown_gender += 1

    def _count_province(self, province_name):
        """统计省份情况"""

        if not province_name or not match_util.is_all_chinese(province_name):
            # 未设置省份名或非国内城市
            other_province_num = self.num_of_province.get(self.unknown_province)
            self.num_of_province.__setitem__(self.unknown_province,
                                             1 if other_province_num is None else other_province_num + 1)
        else:
            province_num = self.num_of_province.get(province_name)
            self.num_of_province.__setitem__(province_name, 1 if province_num is None else province_num + 1)

    def _handle_province(self, member_count):
        """处理所在省份人数占比较低(少于2%)的数据
        :param member_count: 总人数
        """

        for province in list(self.num_of_province.keys()):
            number = self.num_of_province[province]
            if number / member_count < .02:
                other_province_num = self.num_of_province.get(self.unknown_province)
                self.num_of_province.__setitem__(self.unknown_province, other_province_num + number)
                del self.num_of_province[province]

    def _plt_gender_bar(self, title):
        """ 绘制性别柱状图
        :param title: 名称
        """

        plt.bar('男', self.male_num, color='yellow')
        plt.bar('女', self.female_num, color='pink')
        plt.bar('未知', self.unknown_gender, color='gray')
        plt.xlabel('性别'), plt.ylabel('人数'), plt.title(title)
        for a, b in zip([0, 1, 2], np.array([self.male_num, self.female_num, self.unknown_gender])):
            plt.text(a, b, '%.0f' % b, ha='center', va='bottom')
        plt.savefig('{}{}{}(性别统计).png'.format(self.images_dir, os.sep, title))
        plt.show()

    def _plt_province_pie(self, title):
        """ 绘制省份圆饼图
        :param title: 名称
        """

        data = np.array(list(self.num_of_province.values()))
        labels = list(self.num_of_province.keys())
        plt.pie(data, labels=labels, autopct='%.1f%%', )
        plt.axis('equal')
        plt.legend(loc=2, prop={'size': 5.5})
        plt.title(title)
        plt.savefig('{}{}{}(省份分布).png'.format(self.images_dir, os.sep, title))
        plt.show()

    def _puzzle_avatar(self, title='wx'):
        """用pillow拼图"""
        pic_size = 1080  # (正方形)

        avatar_size = int(math.sqrt(float(pic_size * pic_size) / self.num_of_friend))  # 定义头像的尺寸
        lines = int(pic_size / avatar_size) + 1  # 一共要画多少行
        new_image = Image.new('RGB', (pic_size, pic_size))  # 定义空白底图

        x, y = 0, 0  # 起始坐标
        for i in range(0, self.num_of_friend):
            try:
                img = Image.open("{}{}{}.jpg".format(self.avatar_dir, os.sep, i))
            except IOError:
                print("Error: No file or Read file error")
            else:
                img = img.resize((avatar_size, avatar_size), Image.ANTIALIAS)  # 调整原头像大小为定义尺寸
                new_image.paste(img, (x * avatar_size, y * avatar_size))  # 将该头像绘制到底图
                # 改变绘制坐标
                x += 1
                if x == lines:
                    x, y = 0, y + 1

        file_path = '{}{}{}.jpg'.format(self.images_dir, os.sep, title)
        new_image.save(file_path)
        # 发送到手机上(可选)
        self.send_image_to_filehelper(file_path)

    @staticmethod
    def send_msg_to_file_helper(msg):
        """给文件助手发消息"""
        itchat.send(msg, 'filehelper')

    @staticmethod
    def send_image_to_filehelper(img):
        """给文件助手发图片"""
        itchat.send_image(img, 'filehelper')

    @staticmethod
    def get_mps():
        """获取公众号列表"""
        return itchat.get_mps()

    @staticmethod
    def logout():
        """退出登录"""
        itchat.logout()


if __name__ == '__main__':
    wx = WxChat()

    # 分析微信好友
    wx.analysis_friends()
    # 分析微信群聊
    wx.analysis_chat_rooms()

    wx.logout()
  • match_util.py
def is_all_chinese(text):
    """判断text是否全部为中文
    
    :param text: 
    :return: True or False
    """

    return u'\u4e00' <= text <= u'\u9fff'

效果展示

  原是三张清晰的图片,这里截成一张图大概展示下效果。

img_84c27cfb21da1bf4c362130ee5aec1c8.png
饼图+柱状图+大合照

示例代码:Github

目录
相关文章
|
9天前
|
缓存 Rust 算法
从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,主要原因包括历史发展的随意性、社区的分散性、多样化的使用场景、向后兼容性的挑战、缺乏统一治理以及生态系统的快速变化。依赖管理工具用于处理项目中的依赖关系,确保不同环境下的依赖项一致性,避免软件故障和兼容性问题。常用的 Python 依赖管理工具如 pip、venv、pip-tools、Pipenv、Poetry 等各有优缺点,选择时需根据项目需求权衡。新工具如 uv 和 Pixi 在性能和功能上有所改进,值得考虑。
62 35
|
17天前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
在现代数据分析中,高维时间序列数据的处理和预测极具挑战性。基于矩阵分解的长期事件(MFLEs)分析技术应运而生,通过降维和时间序列特性结合,有效应对大规模数据。MFLE利用矩阵分解提取潜在特征,降低计算复杂度,过滤噪声,并发现主要模式。相比传统方法如ARIMA和深度学习模型如LSTM,MFLE在多变量处理、计算效率和可解释性上更具优势。通过合理应用MFLE,可在物联网、金融等领域获得良好分析效果。
34 0
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
|
11天前
|
数据采集 数据可视化 数据挖掘
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
本文探讨了金融资产波动率建模中的三种主流方法:GARCH、GJR-GARCH和HAR模型,基于SPY的实际交易数据进行实证分析。GARCH模型捕捉波动率聚类特征,GJR-GARCH引入杠杆效应,HAR整合多时间尺度波动率信息。通过Python实现模型估计与性能比较,展示了各模型在风险管理、衍生品定价等领域的应用优势。
136 65
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
|
2月前
|
Python
自动化微信朋友圈:Python脚本实现自动发布动态
本文介绍如何使用Python脚本自动化发布微信朋友圈动态,节省手动输入的时间。主要依赖`pyautogui`、`time`、`pyperclip`等库,通过模拟鼠标和键盘操作实现自动发布。代码涵盖打开微信、定位朋友圈、准备输入框、模拟打字等功能。虽然该方法能提高效率,但需注意可能违反微信使用条款,存在风险。定期更新脚本以适应微信界面变化也很重要。
158 61
|
20天前
|
数据可视化 算法 数据挖掘
Python时间序列分析工具Aeon使用指南
**Aeon** 是一个遵循 scikit-learn API 风格的开源 Python 库,专注于时间序列处理。它提供了分类、回归、聚类、预测建模和数据预处理等功能模块,支持多种算法和自定义距离度量。Aeon 活跃开发并持续更新至2024年,与 pandas 1.4.0 版本兼容,内置可视化工具,适合数据探索和基础分析任务。尽管在高级功能和性能优化方面有提升空间,但其简洁的 API 和完整的基础功能使其成为时间序列分析的有效工具。
66 37
Python时间序列分析工具Aeon使用指南
|
15天前
|
机器学习/深度学习 运维 数据可视化
Python时间序列分析:使用TSFresh进行自动化特征提取
TSFresh 是一个专门用于时间序列数据特征自动提取的框架,支持分类、回归和异常检测等机器学习任务。它通过自动化特征工程流程,处理数百个统计特征(如均值、方差、自相关性等),并通过假设检验筛选显著特征,提升分析效率。TSFresh 支持单变量和多变量时间序列数据,能够与 scikit-learn 等库无缝集成,适用于大规模时间序列数据的特征提取与模型训练。其工作流程包括数据格式转换、特征提取和选择,并提供可视化工具帮助理解特征分布及与目标变量的关系。
55 16
Python时间序列分析:使用TSFresh进行自动化特征提取
|
14天前
|
数据采集 缓存 API
python爬取Boss直聘,分析北京招聘市场
本文介绍了如何使用Python爬虫技术从Boss直聘平台上获取深圳地区的招聘数据,并进行数据分析,以帮助求职者更好地了解市场动态和职位需求。
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费市场分析的深度学习模型
使用Python实现智能食品消费市场分析的深度学习模型
138 36
|
2月前
|
数据可视化 算法 数据挖掘
Python量化投资实践:基于蒙特卡洛模拟的投资组合风险建模与分析
蒙特卡洛模拟是一种利用重复随机抽样解决确定性问题的计算方法,广泛应用于金融领域的不确定性建模和风险评估。本文介绍如何使用Python和EODHD API获取历史交易数据,通过模拟生成未来价格路径,分析投资风险与收益,包括VaR和CVaR计算,以辅助投资者制定合理决策。
86 15
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费趋势分析的深度学习模型
使用Python实现智能食品消费趋势分析的深度学习模型
144 18

热门文章

最新文章