继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

python获取微信好友信息以及分析朋友圈,绘制自己朋友圈画像

KenNaNa
关注TA
已关注
手记 63
粉丝 23
获赞 130

python获取微信好友信息以及分析朋友圈,绘制自己朋友圈画像

一、安装python扩展模块
所需工具:

  • pandas
  • itchat
  • pyecharts
pip install 模块名

但是,其实我们可以使用pip一次性安装多个模块,创建一个txt文件,例如:requirements.txt,文件夹内部修改为:

pandas>=0.24.1

itchat>=1.2.32

pyecharts>=1.0.0

通过指令安装requirements.txt依赖pip install -r requirements.txt

二、下载读取微信好友信息

在开始之前,引入模块,因为需要将信息转换为 DataFrame 格式,所以也需要导入 pandas 模块来进行数据处理和分析。

import itchat

import pandas as pd

1、登录微信

对于登录,可以直接使用 itchat 的登录函数,但是我做了一个简单的封装:

def login():
    #% 登录
    try:
        itchat.auto_login(picDir='login.png')
        # 给文件传输助手发送测试信息
        itchat.send('能看到我发的吗 జ్ఞా', toUserName='filehelper')
        return True
    except Exception as e:
        print(e)
        return False

上述函数可以得到是否已经正确的登录,在登录后会自动给文件传输助手发送一条消息。

执行login()函数,将会自动下载并打开微信登录二维码图片,手机扫码后关闭即可。登录过程将在控制台有所显示:

2、获取所有好友信息

friends = itchat.get_friends()
friends_df = pd.DataFrame(friends)
friends_df.index = friends_df['UserName']
myuser = friends_df.iloc[0]['NickName']         # 获取个人名称,一般第一个就是。

上面几行代码的有注释,有的没有注释,主要工作是获取到好友列表并将好友列表转换为DataFrame格式,每一个人的username均为唯一值(注意:每次登陆该变量会发生变化,所以不能以此作为标记,建议以备注作为标记值),然后呢,获取你自己的昵称赋值到myuser,目的主要是生成报告时报告文件的命名。

三、分析微信好友

1、分析并绘制有备注人数,无备注人数比例

在微信好友信息表 friends_df中如果有备注,其NickName值将不为空, 在这里构建了一个函数用于统计是否有备注。返回一个列表。

def getRemarkInfo(data):
    # 有备注
    friends_df = data.copy()
    remark_len = len(friends_df[friends_df['RemarkName']==''])
    remarkdata = [['有备注',remark_len], ['无备注',len(friends_df)-remark_len]]
    return remarkdata
remarkdata = getRemarkInfo(friends_df)          # 计算有无备注信息

结果如下:

remarkdata

Out[5]: [[‘有备注‘, 794], [‘无备注‘, 975]]

绘图

我们使用了pyecharts 模块来进行画图,这个模块从1.0.0版本后将不再向下兼容,仅支持python3.6以上版本。引入所需要的功能,

from pyecharts import options as opts

from pyecharts.charts import Page, Pie, Bar

编写一个饼状图的绘图函数,填入数据和名称即可。

def pie_base(data, title) -> Pie:
    c = (
        Pie()
        .add("", data)
        .set_global_opts(title_opts=opts.TitleOpts(title=title))
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    return c

执行:

pie_base(remarkdata, title=”微信–是否备注“).render()

将直接在py脚本所在目录下生成名为render.html的文件,内含饼状图一张,如图:

2、分析男女比例并绘制饼状图

同样的,设计了一个统计男女比例的函数,返回一个列表数据。

def getFriendSex(data):
    # 好友性别
    friends_df = data.copy()
    friends_df['Sex'] = friends_df['Sex'].apply(lambda x:'未知' if x==0 else  '男'if x==1 else '女')
    friends_sex = friends_df.groupby('Sex').count()['UserName'].to_dict()
    friends_sex = [[k, v] for k, v in friends_sex.items()]
    return friends_sex

执行:

friends_sex = getFriendSex(friends_df)          # 统计朋友性别

使用上一个小结中的绘图函数进行绘图:

pie_base(friends_sex, title=”微信-好友性别”).render(‘2.html’)

注意:这里我将render传入了一个文件名参数,将以 2.html 保存。

3、分析好友省份分布

对于省份来说,稍微有一些麻烦,对于微信好友的资料,由于历史遗留问题有的人的省份信息为空,有的人的省份信息是国外的一些城市,如果是英语国家还好,非英语国家的就会有编码上的问题。这里我们只考虑国内的省份信息,所以需要对字符串进行非中文过滤,只保留中文。函数如下:

def check_contain_chinese(word):
    ''' 检查字符串中是否存在中文
        demo
            check_contain_chinese('www.lizenghai.com')   >>> False
    '''
    for ch in word:
        if not ('\u4e00' <= ch <= '\u9fff'):
            return False
    return True

设计一个统计好友省份信息的函数:

def getProvinceInfo(data):
    # 好友省份
    friends_df = data.copy()
    friends_df['Province'].replace('', '未知', inplace=True)
    friends_province = friends_df.groupby('Province').count()['UserName']#.to_dict()
    # 排除非非中文省份信息
    friends_province = friends_province[friends_province.index.map(lambda x:check_contain_chinese(x))]
    friends_province = friends_province.to_dict()
    return friends_province

执行:

friends_province = getProvinceInfo(friends_df)  # 统计好友省份

这次我们不在绘制饼图,毕竟省份确实太多了,我们需要绘制柱状图来显示,函数如下:

def bar_single_base(data, title, yaxisname, subtitle) -> Bar:
    c = (
        Bar()
        .add_xaxis(list(data.keys()))
        .add_yaxis(yaxisname, list(data.values()))
        .set_global_opts(title_opts=opts.TitleOpts(title=title, subtitle=subtitle))
    )
    return c

绘图:

bar_single_base(friends_province, ‘柱状图‘, ‘省份‘,’好友省份分布‘).render(‘3.html’)

4、分析好友之间共同的群

随着好友、群的日积月累,总会有各种各样的群中有自己的好友,此次分析的目的是分2个维度:a.查看每个群中有哪些好友跟自己一个群。b.反过来统计跟某好友有多少相同的群。

首先,获取群聊信息并重命名索引值为username。对微信好友的备注进行调整,有备注用备注,无备注用原本的昵称。

# 群聊信息
chatrooms = itchat.get_chatrooms()
chatrooms_df = pd.DataFrame(chatrooms)
chatrooms_df.index = chatrooms_df['UserName']
# 交叉统计群聊以及相同群
friend_overlap = friends_df[['UserName','NickName', 'RemarkName']]
# 无备注的名字用好友原本的昵称来替代。
friend_overlap['RemarkName'] = friend_overlap.apply(lambda x:x['RemarkName'] if x['RemarkName']!='' else x['NickName'], axis=1)

设计一个函数,获取处在相同的群,如下:

def getChatroomFriends(chatrooms, friend_overlap):
#% 处在相同的群
    chatroom_friends = {}
    clen = len(chatrooms)
    for i, c in enumerate(chatrooms):
        print('{}/{}'.format(i, clen))
        time.sleep(0.5)
        specifed_chatroom = itchat.update_chatroom(c['UserName'])
        specifed_chatroom_memberList = list(specifed_chatroom['MemberList'])
        chatroom_name = specifed_chatroom['NickName']
        chatroom_friends[chatroom_name] = {'num':0, 'friends':[], 'total':len(specifed_chatroom_memberList)}
        for m in specifed_chatroom_memberList:
            if m['UserName'] in friend_overlap.index:
                chatroom_friends[chatroom_name]['friends'].append(m['UserName'])
                chatroom_friends[chatroom_name]['num'] += 1
    return chatroom_friends

设计一个函数,获取相同的群数, 如下:

def getSameChatroomInfo(chatroom_friends, friend_overlap):
    #% 相同的群数
    def countSameChatroomInfo(username, chatroom_friends):
        
        cnt = 0
        cname = []
        for k in chatroom_friends.keys():
            if username in chatroom_friends[k]['friends']:
                cnt += 1
                cname.append(k)
        cname = '|'.join(cname)
        return cnt, cname
  
    tmp = friend_overlap.index.map(lambda x:countSameChatroomInfo(x, chatroom_friends))
    friend_overlap['sameChatroomNum'] = [x[0] for x in tmp]
    friend_overlap['sameChatroomName'] = [x[1] for x in tmp]
    friend_overlap = friend_overlap[['NickName', 'sameChatroomNum', 'sameChatroomName']] 
    return friend_overlap

通过前面的函数,我们就可以获取到相关数据了:

chatroom_friends = getChatroomFriends(chatrooms, friend_overlap)
#% 置换username为名称
result_chatroom_friends = copy.deepcopy(chatroom_friends)
for k in result_chatroom_friends:
    usernames = result_chatroom_friends[k]['friends']
    result_chatroom_friends[k]['friends'] = ' | '.join(friend_overlap.loc[usernames]['RemarkName'].tolist())
result_chatroom_friends = pd.DataFrame(result_chatroom_friends).T
result_chatroom_friends = result_chatroom_friends[['total', 'num', 'friends']]
# 数据用完,处理friend_overlap
friend_overlap = getSameChatroomInfo(chatroom_friends, friend_overlap)

4、保存报告

报告分为2部分,一部分是html图表的汇总,主要是好友的统计信息。另一部分是excel,主要是统计的相同群的好友以及跟某个(所有)好友相同的群有哪些。报告信息全部保存在脚本所在目录的Report目录下,如果没有请创建Report文件夹。

pyecharts的page可以将所有图表放在一起:

#% 输出内容和报告
page = Page()
page.add(pie_base(friends_sex, title="微信-好友性别"))
page.add(pie_base(remarkdata, title="微信-是否备注"))
page.add(bar_single_base(friends_province, '柱状图', '省份','好友省份分布'))
page.render(r'Report\Report_{}.html'.format(myuser))

保存群的相关信息:

writer = pd.ExcelWriter(r'Report\Report_{}.xlsx'.format(myuser))
result_chatroom_friends.to_excel(writer, '群中相同好友')
friend_overlap.to_excel(writer, '好友相同群数')
writer.save()
打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP