Python学习资料整理Web

用python对微信好友进行数据分析

2019-04-15  本文已影响43人  c067527d47c2

微信好友分析

基于 Python 对微信好友进行数据分析,这里选择的维度主要有:性别、头像、签名、位置,主要采用图表和词云两种形式来呈现结果,其中,对文本类信息会采用词频分析和情感分析两种方法。在正式开始这篇文章前,简单介绍下本文中使用到的第三方模块:

image
当然在学习Python的道路上肯定会困难,没有好的学习资料,怎么去学习呢? 学习Python中有不明白推荐加入交流群号:973783996 群里有志同道合的小伙伴,互帮互助, 群里有不错的视频学习教程和PDF!
# 首先导入用到的第三方模块
import itchat
import numpy as np
import os
from collections import Counter
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']#绘图时可以显示中文
plt.rcParams['axes.unicode_minus']=False#绘图时可以显示中文
from wordcloud import WordCloud,STOPWORDS,ImageColorGenerator
from PIL import Image
import math
import re
import snownlp
import jieba
import jieba.analyse
import pandas as pd

分析微信好友数据的前提是获得好友信息,通过使用 itchat 这个模块

itchat.auto_login(hotReload=True)
friends = itchat.get_friends(update=True)

同平时登录网页版微信一样,我们使用手机扫描二维码就可以登录,这里返回的friends对象是一个集合

好友性别

分析好友性别,我们首先要获得所有好友的性别信息,这里我们将每一个好友信息的Sex字段提取出来,然后分别统计出男、女 和保密的数目,我们将这三个数值组装到一个列表中,即可使用matplotlib模块绘制出饼图来,其代码实现如下:

def fun_analyse_sex(friends):
    # 性别分析
    sexs = list(map(lambda x:x['Sex'],friends[1:]))#收集性别数据
    counts = list(map(lambda x:x[1],Counter(sexs).items()))#统计不同性别的数量
    counts = sorted(counts)
    labels = ['保密','男','女']#2:女,1:男,0:保密
    colors = ['red','yellow','blue']
    plt.figure(figsize=(20,8), dpi=80)
    plt.axes(aspect=1)
    plt.pie(counts, #性别统计结果
    labels=labels, #性别展示标签
    colors=colors, #饼图区域配色
    labeldistance = 1.1, #标签距离圆点距离
    autopct = '%3.1f%%', #饼图区域文本格式
    shadow = False, #饼图是否显示阴影
    startangle = 90, #饼图起始角度
    pctdistance = 0.6 #饼图区域文本距离圆点距离
    )
    plt.legend(loc='upper left')#标签位置
    plt.title(u'%s的微信好友性别比例' % friends[0]['NickName'])
    plt.show()
img

生成头像

头像分析有两部分,(1)保存好友头像;(2)用所有好友头像生产一张图片

通过用户名找到对应每个好友的头像,写入HeadImages目录中

def get_HeadImage(friends):
    # 保存好友头像
    if "HeadImages" not in os.listdir():
        os.mkdir('HeadImages')
    os.chdir("HeadImages")

    for friend in friends:
        img = itchat.get_head_img(userName=friend["UserName"])

        with open(friend['UserName'].replace('|', '') + '.jpg', "wb") as f:
            print("正在下载%s.jpg" % friend["NickName"])
            f.write(img)

使用PIL模块的Image方法,生成一张图片,再把每一张好友头像缩小贴到这张图片上

def all_head_images():
    # 把所以好友头像生成一张图片
    x = 0
    y = 0
    images = os.listdir("HeadImages")
    print(len(images))
    new_image = Image.new('RGBA', (640, 640))
    # width = int(math.sqrt(640*640 / len(images)))
    # line_num = int(640 / width)
    line_num = int(math.sqrt(len(images)))
    width = int(640/line_num)
    for i in images:
        image = Image.open('HeadImages/' + i)
        image = image.resize((width, width), Image.ANTIALIAS)
        new_image.paste(image, (x*width, y*width))
        x += 1
        if x == line_num:
            x = 0
            y += 1
    new_image.save('all.png')
img

好友签名分析

好友签名分析,也分为两部分:(1)切词构造词云;(2)文本分析,生活态度

def fun_analyse_Signature(friends):
    # 个性签名分析
    signatures = ''
    emotions = []
    for friend in friends:
        signature = friend['Signature']
        if signature != None:
            signature = signature.strip().replace("span","").replace("class","").replace("emoji","")#去除无关数据
            signature = re.sub(r'1f(\d.+)',"",signature)
        if len(signature) > 0:
            nlp = snownlp.SnowNLP(signature)
            emotions.append(nlp.sentiments)#nlp.sentiments:权值
            signatures += " ".join(jieba.analyse.extract_tags(signature,5))#关键字提取
    back_coloring = np.array(Image.open("xiaohuangya.jpg"))#图片可替换
    word_cloud2 = WordCloud(font_path = 'simkai.ttf',
                         background_color = 'white',
                         max_words = 1200,
                         mask = back_coloring,
                         margin = 15)
    word_cloud2.generate(signatures)
    image_colors = ImageColorGenerator(back_coloring)
    plt.figure(figsize=(20, 8),dpi=160)
    plt.imshow(word_cloud2.recolor(color_func=image_colors))
    plt.axis("off")
    plt.show()
    word_cloud2.to_file("signatures.jpg")
    #人生观
    count_positive = len(list(filter(lambda x:x>0.66,emotions)))#大于0.66为积极
    count_negative = len(list(filter(lambda x:x<0.33,emotions)))#小于0.33为消极
    count_neutral = len(list(filter(lambda x:x>=0.33 and x <= 0.66,emotions)))
    labels = [u'积极',u'中性',u'消极']
    values =(count_positive,count_neutral,count_negative)
    plt.rcParams['font.sans-serif'] = ['simHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.xlabel("情感判断")
    plt.ylabel("频数")
    plt.xticks(range(3),labels)
    plt.legend(loc='upper right')
    plt.bar(range(3),values,color='rgb')
    plt.title(u'%s的微信好友签名信息情感分析情况' % friends[0]['NickName'])
    plt.show()
img img

好友位置

将姓名、省份写入csv文件

def analyseLocation(friends):
    # 定义数据头
    headers = ['NickName','Province']
    with open('location.csv','w',encoding='utf-8',newline='',) as csvFile:
        # DictWriter以字典的形式写入内容
        # 设置写入格式
        writer = csv.DictWriter(csvFile, headers)
        #  writeheader()实现添加文件头(数据名)
        writer.writeheader()
        for friend in friends[1:]:
            # 定义一个字典
            row = {}
            # 按属性写入
            row['NickName'] = friend['NickName']
            row['Province'] = friend['Province']
            # 将每个字典写入为一行
            writer.writerow(row)
上一篇下一篇

猜你喜欢

热点阅读