Python学习-微信好友分析

吐个槽吧!

我也是新手,写个简易教程。供大家娱乐。

正文开始啦!

01

环境搭建

python安装

python版本3.6.4。安装教程网上很多,就不赘述啦!

注意:将python命令和pip命令添加到环境变量

模块安装

#核心模块

pip installitchat

pip installpandas

# 序列化

pip installpickle

# 图表模块

pip install pyecharts

# 图形处理模块

pip install PIL.Image

# 词图模块

pip installwordcloud

pip installmatplotlib.pyplot

# 地图模块

pip install echarts-countries-pypkg

pip install echarts-china-provinces-pypkg

pip install echarts-china-cities-pypkg

# 其他模块

pip installos

pip installre

pip installmath

pip installrandom

02

实现原理

pandas模块进行数据分析

Pandas是一款开放源码的Python库,提供了高性能,易于使用的数据结构和数据分析工具。(来自官方文档)

pickle模块将数据序列化(避免每次扫码登录)

pyecharts模块可视化数据

pyecharts 用于生成 Echarts 图表的类库。方便在 Python 中直接使用数据生成图(来自官方文档)

wordcloud模块分析词云

03

代码实现

项目已上传Github:https://github.com/Derrick-Wang/wechatFriend/tree/master

项目为pyCharm创建,方便调试。

.py文件可用python命令独运行。可不安装pyCharm。

文件列表:

扫码登录微信并获取好友信息

#登录

itchat.login()

#获取好友,返回好友信息字典

my_friends = itchat.get_friends(update=True)[:]

#持久化

withopen('my_friends.pickle','wb')ase:

pickle.dump(my_friends,e)

调用get_friends方法返回一字典列表,第一个是本人信息。字典中每个key表示一个信息,如:性别,昵称。建议断点通过pycharm预览

相关字段说明:

UserName:内部用户名,@开头是好友,@@开头是群聊,itchat提供了 get_chatrooms()方法。每次登录都不一样

ContactFlag:好友类型:好友为1、3。65标星好友,257、259不让他看我的朋友圈,65539不看他的朋友圈,65795两项设置全禁止。

SnsFlag:未知。取值范围为0、1、16、17、49、129、145、177,较多为17,1,49

AttrStatus:未知。。

UniFriend:未知。值为0

StarFriend:标星好友。1是0否

提取微信好友有用信息

#获得所需好友信息

defget_friends_info():

withopen('my_friends.pickle','rb')asf:

#使用pickle的load函数下载被打开被读取到的数据。

friends = pickle.load(f)

#取出需要数据

friends_info =dict(

#省份

province=get_key_info(friends,"Province"),

#城市

city=get_key_info(friends,"City"),

#昵称

nickname=get_key_info(friends,"Nickname"),

#性别

sex=get_key_info(friends,"Sex"),

#签名

signature=get_key_info(friends,"Signature"),

#备注

remarkname=get_key_info(friends,"RemarkName"),

#用户名拼音全拼

pyquanpin=get_key_info(friends,"PYQuanPin")

)

returnfriends_info

#根据key值得到对应信息

defget_key_info(friends_info,key):

returnlist(map(lambdafriend_info: friend_info.get(key),friends_info))

性别分析

#性别分析

defanalysisSex():

friends_info = get_friends_info()

df = pd.DataFrame(friends_info)

sex_count = df.groupby(['sex'],as_index=True)['sex'].count()

temp =dict(zip(list(sex_count.index),list(sex_count)))

data = {}

data['保密'] = temp.pop()

data['男'] = temp.pop(1)

data['女'] = temp.pop(2)

# echarts画图

page = Page()

attr,value = data.keys(),data.values()

chart = Pie('微信好友性别分布')

chart.add('',attr,value,center=[50,50],

redius=[30,70],is_label_show=True,legend_orient='horizontal',legend_pos='center',

legend_top='bottom',is_area_show=True)

page.add(chart)

page.render('SexData.html')

分析结果:

这就是单身的原因么?男生是快到女生的两倍了

好友所在地分析

#省份分析

defanalysisProvince():

friends_info = get_friends_info()

df = pd.DataFrame(friends_info)

province_count = df.groupby('province',as_index=True)['province'].count().sort_values()

temp =list(map(lambdax: xifx !=''else'未知',list(province_count.index)))

# echarts画图

page = Page()

style = Style(width=1000,height=350)

style_middle = Style(width=1000,height=350)

attr,value = temp,list(province_count)

chart1 = Map('好友分布(中国地图)',**style.init_style)

chart1.add('',attr,value,is_label_show=True,is_visualmap=True,visual_text_color='#000')

page.add(chart1)

chart2 = Bar('好友分布柱状图',**style_middle.init_style)

chart2.add('',attr,value,is_stack=True,

label_pos='inside',is_legend_show=True,is_label_show=True,xaxis_rotate=90)

page.add(chart2)

page.render('ProvinceData.html')

结果分析:

还是上海和河南较多啊

获取好友头像并拼接

#获取头像

defheadImg():

itchat.login()

friends = itchat.get_friends(update=True)

#遍历好友数据

forcount,finenumerate(friends):

#根据userName获取头像

img = itchat.get_head_img(userName=f["UserName"])

#根据备注保存头像文件

imgFile =open("img/"+ f["RemarkName"] +".jpg","wb")

imgFile.write(img)

imgFile.close()

#头像拼接

defcreateImg():

x =

y =

imgs = os.listdir("img")

#随机打乱头像

# random.shuffle(imgs)

#创建图片,用于拼接小图

newImg = Image.new('RGBA',(640,640))

# math.sqrt()开平方根计算小图宽高,

width =int(math.sqrt(640*640/len(imgs)))

#每行图片数

numLine =int(640/ width)

foriinimgs:

try:

img = Image.open("img/"+ i)

#缩小图片

img = img.resize((width,width),Image.ANTIALIAS)

#拼接图片,一行排满,换行拼接

newImg.paste(img,(x * width,y * width))

x +=1

ifx >= numLine:

x =

y +=1

exceptIOError:

print("img/ %s can not open"%(i))

newImg.save("weChatFriend.png")

效果展示:

看到你没,哈哈哈。我是不会给肖像使用费的。

获取签名,生成词云

#获取签名

defgetSignature():

itchat.login()

friends = itchat.get_friends(update=True)

file =open('sign.txt','a',encoding='utf-8')

forfinfriends:

signature = f["Signature"].strip().replace("emoji","").replace("span","").replace("class","")

rec = re.compile("1f\d+\w*|[/=]")

signature = rec.sub("",signature)

file.write(signature +"\n")

#生成词云图

defcreate_word_cloud(filename):

#读取文件内容

text =open("{}.txt".format(filename),encoding='utf-8').read()

#注释部分采用结巴分词

# wordlist = jieba.cut(text, cut_all=True)

# wl = " ".join(wordlist)

#设置词云

wc = WordCloud(

#设置背景颜色

background_color="white",

#设置最大显示的词云数

max_words=2000,

#这种字体都在电脑字体中,window在C:\Windows\Fonts\下,mac下可选/System/Library/Fonts/PingFang.ttc字体

font_path='C:\\Windows\\Fonts\\simfang.ttf',

height=500,

width=500,

#设置字体最大值

max_font_size=60,

#设置有多少种随机生成状态,即有多少种配色方案

random_state=30,

)

myword = wc.generate(text)#生成词云 如果用结巴分词的话,使用wl取代text, 生成词云图

#展示词云图

plt.imshow(myword)

plt.axis("off")

plt.show()

wc.to_file('signature.png')#把词云保存下

效果:

有些小伙伴的签名真的是……

就要结束喽!

好了,就这些啦!其实,itchat还有很多好玩的地方,我还在摸索,欢迎感兴趣的小伙伴一起交流哈

源码已上传Github:https://github.com/Derrick-Wang/wechatFriend/tree/master,不定期更新。快来给我点星星啊!

参考:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181201G1DQM700?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券