微信好友信息分析

python3.6
环境:pycharm
代码中用到的包全部为2019.5.1之前的最新版本
有问题欢迎交流。

思路:通过微信个人号网页版接口ichat对微信数据进行处理(微信朋友圈没有接口),pyecharts对数据进行建表等操作,用Pillow包对头像进行处理。

结果:代码经测试无需更改任何人可以使用,登陆时用微信扫码方式。目前了解,对于2018年之后申请的微信号,腾讯已经关闭了微信网页版登陆权限,无法使用此代码。最终形成了性别比例,省份分布,前top10城市人数,微信头像拼接成一个图片。

扩展:(1)ichat有收发消息功能,这意味着可以做一个聊天机器人,发广告什么的需要用手吗?恩,如果你弄个百度AI的接口,我觉得对方能玩一年。(2)群发消息。粘贴复制的消息大家都看腻了,如果加上对方的名字等信息是不是更暖心呢?总体来说太局限了,暂时还没发现什么好玩的。看看以后能不能扩展吧。

附送运行结果和代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

import itchat, os, re, random, math
from pyecharts.charts import Page, Pie, Geo, Bar
from pyecharts import options as opts
from PIL import Image


def get_key_info(friends_info, key):  # 获取想知道的好友信息组成列表,中间调用了get_friends_info(friends)
    return list(map(lambda friend_info: friend_info.get(key), friends_info))
    # lambda表示匿名函数,对friend_info执行:后面的操作输出的结果。map表示对friends_info每个元素执行其逗号前的操作


def get_friends_info(friends):    # 获取想知道的信息。
    friends_info = dict(
        username=get_key_info(friends, 'UserName'),    # 用户名
        sex=get_key_info(friends, 'Sex'),              # 性别
        province=get_key_info(friends, 'Province'),    # 省份
        city=get_key_info(friends, 'City')             # 城市
    )
    return friends_info


# 处理数据
def count_nums(new_list):   # 对好友信息进行处理,比如:英文的省份不要
    new_dict = {}
    for i in new_list:
        if bool(re.search('[a-z]|[A-Z]', i)):   # 如果匹配到英文字母就跳出本次循环
            continue
        elif not new_dict.__contains__(i):  # 判断字典中有没有这个信息,没有的话加上,有的话计数加一
            new_dict[i] = 1
        else:
            new_dict[i] += 1
    new_dict.pop('')   # 去掉空的键
    return new_dict

def analysis(friends):
    friends_info = get_friends_info(friends)

    # 男女性别比例
    sex_list = friends_info['sex']
    from collections import Counter
    sex_dict = dict(Counter(sex_list))  # 性别计数
    attr = ["未知", "男性", "女性"]
    value = [sex_dict[0], sex_dict[1], sex_dict[2]]
    page = Page() # 创建一个HTML网页
    chart1 = ( # 创建性别分析图标
        Pie()
        .add("", [list(z) for z in zip(attr, value)])
        .set_global_opts(title_opts=opts.TitleOpts(title="好友性别比例"))
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    page.add(chart1) # 将图标加入HTML页面

    # 中国省级分析
    province_list = friends_info['province']
    province_dict = count_nums(province_list)
    attr, value = list(province_dict.keys()), list(province_dict.values())

    chart2 = ( # 创建省份分析表
        Geo()
        .add_schema(maptype="china")
        .add("所在省份", [list(z) for z in zip(attr, value)])
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(
            visualmap_opts=opts.VisualMapOpts(),
            title_opts=opts.TitleOpts(title="好友省级分布(中国地图)"),
        )
    )
    page.add(chart2) # 加入到HTML页面

    # 中国城市分析(取前10个人数最多的城市)
    city_list = friends_info['city']
    city_dict = count_nums(city_list)
    top_ten_city = dict(sorted(city_dict.items(), key=lambda x: x[1], reverse=True)[0:10])
    attr, value = list(top_ten_city.keys()), list(top_ten_city.values())
    chart3 = (  # 创建城市分析表
        Bar()
            .add_xaxis(attr)
            .add_yaxis('城市', value)
            .set_global_opts(title_opts=opts.TitleOpts(title="好友城市分布Top10柱状图"))
    )
    page.add(chart3)  #加入到HTML页面
    page.render('analysisResult.html') # 生成HTML页面文件


def get_head_img(friends):  # 获取好友头像信息
    friends_info = get_friends_info(friends)
    username = friends_info['username']

    for i, uname in enumerate(username):   # 把图片保存在当前文件夹下的headImgs文件夹下面并重命名
        with open("headImgs/" + str(i) + ".png", "wb") as f:
            img = itchat.get_head_img(uname)
            f.write(img)


def create_img(): # 对头像进行拼接
    x = 0
    y = 0
    imgs = os.listdir("headImgs")  # 返回 headImgs 目录下的文件列表
    random.shuffle(imgs)  # 将文件列表随机排序

    input_length = 360
    input_width = 240

    new_img = Image.new('RGBA', (input_width, input_length))   # 创建 长*宽 的图片用于填充各小图片
    width = int(math.sqrt(input_length * input_width / len(imgs)))   # 算出图片总面积然后除以图片数量,math.sqrt()开平方根计算每张小图片的宽高
    num_line = int(input_width / width)   # 每行图片数

    for i in imgs:  #对每一张图片逐个进行处理
        try:
            img = Image.open("headImgs/" + i)
        except IOError:
            print("第{}张图片为空".format(i))
        else:
            img = img.resize((width, width), Image.ANTIALIAS)   # 缩小图片
            new_img.paste(img, (x * width, y * width))   # 拼接图片,一行排满,换行拼接
            x += 1
            if x >= num_line:
                x = 0
                y += 1

    new_img.save("mixedImg.png") # 存放图片


if __name__ == '__main__':
    itchat.auto_login(hotReload=True)   # 登陆
    friends = itchat.get_friends(update=True) # 获取信息
    analysis(friends)  # 函数调用
    curPath = os.getcwd() # 获取当前目录的绝对路径
    tempPath = 'headImgs' # 存放头像图片的文件夹
    targetPath = curPath + os.path.sep + tempPath # 存放头像图片文件夹的路径
    if not os.path.exists(targetPath):   # 创建 文件夹
        os.makedirs(targetPath)
    else:
        print('路径已经存在!')
    get_head_img(friends)   # 函数调用
    create_img()  # 函数调用



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值