python 3.7 实现 微信朋友信息统计

前提,已安装好python ,pycharm

安装依赖:
file -> setting ,依照下图添加依赖,
在这里插入图片描述
安装下面三个依赖库,
itchat
numpy
pyecharts
在这里插入图片描述
如果安装较慢的话,可以配置仓库,
在这里插入图片描述
https://pypi.tuna.tsinghua.edu.cn/simple
http://mirrors.aliyun.com/pypi/simple/
https://pypi.mirrors.ustc.edu.cn/simple/
在这里插入图片描述
全部代码都在下面,需要在下面
我的代码在itChatTest.py里,在同级目录新建img和result文件夹存放生成的文件
在这里插入图片描述

import itchat
import re
import csv
import os
import random
import numpy as np
import PIL.Image as Image
from collections import Counter
from pyecharts.charts import Bar, Pie, Map, WordCloud
from pyecharts import options as opts


# 登录微信
def itchat_login():
    itchat.auto_login(hotReload=True)
    itchat.dump_login_status()
    # 获取好友信息
    firends = itchat.get_friends(update=True)[:]
    return firends

# 处理数据,获取所需字段
def get_info(firends):
    # 微信名
    nickNames = []
    # 备注
    remarkNames = []
    # 性别
    sexs = []
    # 个性签名
    signatures = []
    # 省份
    provinces = []
    # 城市
    citys = []
    # 用户名
    userNames = []
    for i in firends:
        # 提取主要数据
        nickName = i['NickName'].strip().replace('span','').replace('class','').replace('emoji','')\
            .replace('\n','').replace('\"','').replace('🤣','')
        remarkName = i['RemarkName'].strip().replace('span','').replace('class','').replace('emoji','')\
            .replace('\n','').replace('\"','').replace('🤣','')
        sex = i['Sex']
        signature = i['Signature'].strip().replace('span','').replace('class','').replace('emoji','')\
            .replace('\n','').replace('\"','').replace('\t','').replace('', '').replace("1f60a", " ")\
            .replace("1f497", " ").replace("1f31f", " ")
        rep = re.compile("1f\d+\w*|[<>/=]")
        signature = rep.sub('', signature)
        province = i['Province']
        city = i['City']
        userName = i['UserName']
        nickNames.append(nickName)
        remarkNames.append(remarkName)
        sexs.append(sex)
        signatures.append(signature)
        provinces.append(province)
        citys.append(city)
        userNames.append(userName)
    return zip(nickNames, remarkNames, sexs, signatures, provinces, citys, userNames)

def get_data(firends):
    datas = []
    data = get_info(firends)
    for a,b,c,d,e,f,g in data:
        info = {}
        info['昵称'] = a
        info['备注名称'] = b
        info['性别'] = c
        info['个性签名'] = d
        info['省份'] = e
        info['城市'] = f
        info['用户名'] = g
        datas.append(info)
    return datas

# 存储数据到csv文件
def write2csv(datas):
    print("--------------------------")
    print("正在保存数据")
    # 文件默认保存在项目所在的目录
    with open('wechat.csv','a',newline='',encoding='utf-8-sig') as f:
        # 控制列的顺序
        fieldnames = ['昵称', '备注名称', '性别', '个性签名', '省份', '城市', '用户名']  # 控制列的顺序
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(datas)
        print("保存数据成功")

# 好友性别分析
def sex_info(datas):
    male = female = other = 0
    for i in datas:
        sex = i['性别']
        if sex == 1:
            male += 1
        elif sex == 2:
            female += 1
        else:
            other += 1
    gender = ['男', '女', '其他']
    value = [male, female, other]
    data_pair = [list(z) for z in zip(gender, value)]
    c =(
        Pie()
            .add('', data_pair)
            .set_global_opts(title_opts=opts.TitleOpts(title="微信好友性别比例图", pos_left="center",pos_top="20",subtitle='好友总人数:%d' % len(datas)),
                             legend_opts=opts.LegendOpts(pos_left="legft", orient="vertical"))
            # 在指定目录下生成一个 gender.html的文件
            .render('result/gender.html')
    )
    print('性别分析图完成')

# 微信好友头像获取
def img_info(datas):
    num = 0
    for i in datas:
        img = itchat.get_head_img(userName=i["用户名"])
        imgFile = open("img/" + str(num)+".jpg","wb")
        imgFile.write(img)
        imgFile.close()
        num += 1
    print('微信好友头像获取完成')

# 绘制好友头像拼接图
def img_list():
    x = 0
    y = 0
    imgs = os.listdir("img")
    # 将图片的顺序打乱
    random.shuffle(imgs)
    # 创建640*640的图片能于填充各种小图片
    total_img = Image.new('RGBA',(1000,1000))
    # math.sqrt()开平方根计算每张小图片的宽高
    width = int(np.math.sqrt(1000 * 1000 / len(imgs)))
    # 每行图片数
    row_num = int(1000 / width)
    for i in imgs:
        try:
            img = Image.open("img/" + i)
            img = img.resize((width, width), Image.ANTIALIAS)
            total_img.paste(img, (x * width, y * width))
            x += 1
            if x >= row_num:
                x = 0
                y += 1
        except IOError:
            print("img/ %s can not open" % (i))
        total_img.save("result/头像拼接图.png")
    print('头像拼接图完成')

# 微信好友全国分布地图 & 省份分布统计图
def map_info(datas):
    provinces = []
    for i in datas:
        province = i["省份"]
        provinces.append(province)
    # 去除列表中空白字符,有些微信好友没填城市信息
    provinces = filter(None, provinces)
    res = Counter(provinces)
    province_keys = res.keys()
    province_values = res.values()
    data_pair = [list(z) for z in zip(province_keys, province_values)]
    c = (
        Map().
            add("好友数量", data_pair, "china").
            set_global_opts(title_opts=opts.TitleOpts(title="我的微信好友分布"),
                            visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True)).
            render("result/map.html")
    )
    print('微信好友分布图完成')
    for key2 in list(res.keys()):
        if res.get(key2) < 2:
            del res[key2]
    key2 = list(res.keys())
    value2 = list(res.values())
    c1 = (
        Bar().
            set_global_opts(
            title_opts=opts.TitleOpts(title="我的微信好友省份统计图")
            ).
            add_xaxis(key2).
            add_yaxis("人数",value2).
            render("result/bar_province.html")
    )
    print('微信好友省份统计图完成')

#微信好友城市分布统计图
def city_info(datas):
    citys = []
    for i in datas:
        city = i["城市"]
        citys.append(city)
    # 去除列表中空白字符,有些微信好友没填城市信息
    citys = filter(None, citys)
    res = Counter(citys)
    for key in list(res.keys()):
        if res.get(key) < 3:
            del res[key]
    key = list(res.keys())
    value = list(res.values())
    c = (
        Bar().
            set_global_opts(
            #解决x轴标签名字过长的问题
            xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
            title_opts=opts.TitleOpts(title="我的微信好友城市统计图")
            ).
            add_xaxis(key).
            add_yaxis("人数",value).
            render("result/bar_city.html")
    )
    print('微信好友省份统计图完成')

# 绘制微信昵称词云图谱
def nick_cloud(datas):
    nickNames = []
    for i in datas:
        nickName = i["昵称"]
        rep = re.compile("1f\d+\w*|[<>/=]")
        nickName = rep.sub('', nickName)
        nickNames.append(nickName)
    res = Counter(nickNames)
    data_pair = [list(z) for z in zip(res.keys(), res.values())]
    c = (

           WordCloud().
               add("", data_pair, word_size_range=[20, 100],textstyle_opts=opts.TextStyleOpts(font_family="cursive")).
               set_global_opts(title_opts=opts.TitleOpts(title="昵称词云图")).
               render("result/nick_cloud.html")
       )
    print('昵称词云图完成')

# 绘制个性签名词云图谱
def signature_cloud(datas):
    signatures = []
    for i in datas:
        signature = i["个性签名"]
        rep = re.compile("1f\d+\w*|[<>/=]")
        signature = rep.sub('', signature)
        signatures.append(signature)
    res = Counter(signatures)
    data_pair = [list(z) for z in zip(res.keys(), res.values())]
    c = (

        WordCloud().
            add("", data_pair, word_size_range=[20, 100], textstyle_opts=opts.TextStyleOpts(font_family="cursive")).
            set_global_opts(title_opts=opts.TitleOpts(title="个性签名云图")).
            render("result/signature_cloud.html")
    )
    print('个性签名云图完成')

if __name__ == '__main__':
    firends = itchat_login()
    datas = get_data(firends)
    write2csv(datas)
    sex_info(datas)
    img_info(datas)
    img_list()
    map_info(datas)
    city_info(datas)
    nick_cloud(datas)
    signature_cloud(datas)

代码启动会提示扫描二维码
等待片刻后会发现多了一些文件
在这里插入图片描述
效果图
在这里插入图片描述
个性签名词云图谱
在这里插入图片描述
还有一些昵称词频图谱、头像拼接图等信息涉及隐私我就不放上了,感兴趣的可以试一试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值