今天上班看到一篇关于用Python爬取微信好友签名并生成词云的文章,觉得很有趣,就学着尝试爬取自己的微信好友签名,菜鸟写代码,总是会出现很多问题,摸索了一天,终于成功了。记录下自己的经过,希望能给像自己一样的小白一点点参考
本博客代码参考https://github.com/ablo120/PythonLearn/blob/master/wechat_friend.py
前言:建议Python小白安装anaconda,它集成了Python及Python的很多库。对于小白,Python库的安装是个很头疼的问题,anaconda可以很好地解决这个问题。安装anaconda后,以后安装其他库时,直接pip install 《库名》,基本可以完成安装。
1、用itchat模块登录微信
直接pip install itchat 安装itchat。
#登录微信
import itchat
itchat.login() #有个登录二维码图片弹框,用自己微信扫码登录即可
#获取微信朋友信息
friends=itchat.get_friends(update=True)[0:]
print(friends)
返回一个json数据,如下图:
2、分析微信好友的男女比例
这里定义个函数parse_friends()来表示,用循环来遍历微信好友,获取性别信息保存在text字典文件里
def parse_friends():
itchat.login()
text=dict()
friends=itchat.get_friends(update=True)[0:]
print(friends)
male = 'male'
female='female'
other='other'
for i in friends[1:]:
sex = i['Sex'] #注意Sex大写,表示微信里的性别
if sex==1: #1的来源于上图画线部分,标志位为1,表示男性
text[male]=text.get(male,0)+1
elif sex==2:
text[female]=text.get(female,0)+1
else:
text[other]=text.get(other,0)+1
total=len(friends[1:])
print(
"男性好友:%.2f%%"%(float(text[male])/total*100)+"\n"+
"女性好友: %.2f%%" % (float(text[female]) / total * 100) + "\n" +
"不明性别好友: %.2f%%" % (float(text[other]) / total * 100)
)
print('好友数量:%.2f' % total)
draw(text)
使用plt库画性别柱状图
def draw(datas):
for key in datas.keys():
plt.bar(key,datas[key])
plt.legend()
plt.xlabel('sex')
plt.ylabel('rate')
plt.title("Gender of dudumei's friends")
plt.show()
最后打印的结果以及柱状图如下:
我共有1001个好友,男性同胞占了大部分
3、获取微信好友微信签名
定义一个parse_signature()函数,用for循环,筛选出好友签名,用正则表达式去掉span,class,emoji等字眼。
def parse_signature():
siglist=[]
SIGNATURE_PATH ='F:/files/signature.txt' #尽量先把路径赋值给一个变量,这样就不用考虑符号转义问题
friends =itchat.get_friends(update=True)[1:]
for i in friends:
## 获取个性签名,替换掉span,class,emoji
signature = i["Signature"].strip().replace("span","").replace("class","").replace("emoji","")
# 正则匹配过滤掉emoji表情,例如emoji1f3c3等
rep=re.compile("1f\d+\w*|[<>/=]")
signature=rep.sub("",signature)
siglist.append(signature)
# 拼接字符串
text="".join(siglist)
with io.open(SIGNATURE_PATH,'w',encoding='utf-8')as f:
# jieba分词
wordlist=jieba.cut(text,cut_all=True)
word_space_split=" ".join(wordlist) #这里的“ ”之间一定要有空格,没有空格会引发白板问题
f.write(word_space_split)
f.close()
draw_signature(SIGNATURE_PATH)
4、绘制词云
def draw_signature(path):
f=open(path,'r',encoding='utf-8').read()
cut_text=" ".join(jieba.cut(f))
#找一张图来生成配色方案,图3.png路径在F:/files下
coloring=np.array(Image.open('F:/files/3.png'))
my_wordclound=WordCloud(background_color='white', # 设置背景颜色
max_words=6000, # 设置最大显示的字数
mask=coloring, # 设置背景图片
max_font_size=60, # 设置字体最大值
random_state=42, # 设置有多少种随机生成状态,即有多少种配色方案
scale=2,font_path='C:/Windows/Fonts/simfang.ttf', # 设置字体格式,如不设置会乱码
).generate(cut_text)
image = WordCloud.to_image(my_wordclound)
image.show()
最后生成的词云如图所示:
总结遇到的问题:
1、路径问题,最好把路径赋值给变量,这样就可以减少转义问题
2、函数调用问题,参考网上一些其他人的代码,可能明明代码没有错误,但就是运行不成功,多数要考虑函数调用问题
3、白板问题:在确认代码无误的情况下,依旧显示不出词云,只是一个空白的图像,后来发现是因为少了空格
word_space_split=" ".join(wordlist) #这里的“ ”之间一定要有空格,没有空格会引发白板问题
第一次写Python博客,如有错误,请多指教。下面附上完整代码
import wordcloud
import itchat
import re
import io
import os
from os import path
import jieba
import numpy as np
from PIL import Image
import random
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
from wordcloud import WordCloud
def draw(datas):
for key in datas.keys():
plt.bar(key,datas[key])
plt.legend()
plt.xlabel('sex')
plt.ylabel('rate')
plt.title("Gender of dudumei's friends")
plt.show()
def parse_friends():
itchat.login()
text=dict()
friends=itchat.get_friends(update=True)[0:]
print(friends)
male = 'male'
female='female'
other='other'
for i in friends[1:]:
sex = i['Sex']
if sex==1:
text[male]=text.get(male,0)+1
elif sex==2:
text[female]=text.get(female,0)+1
else:
text[other]=text.get(other,0)+1
total=len(friends[1:])
print(
"男性好友:%.2f%%"%(float(text[male])/total*100)+"\n"+
"女性好友: %.2f%%" % (float(text[female]) / total * 100) + "\n" +
"不明性别好友: %.2f%%" % (float(text[other]) / total * 100)
)
print('好友数量:%.2f' % total)
draw(text)
def parse_signature():
siglist=[]
SIGNATURE_PATH ='F:/files/signature.txt'
friends =itchat.get_friends(update=True)[1:]
for i in friends:
signature = i["Signature"].strip().replace("span","").replace("class","").replace("emoji","")
rep=re.compile("1f\d+\w*|[<>/=]")
signature=rep.sub("",signature)
siglist.append(signature)
text="".join(siglist)
with io.open(SIGNATURE_PATH,'w',encoding='utf-8')as f:
wordlist=jieba.cut(text,cut_all=True)
word_space_split=" ".join(wordlist)
f.write(word_space_split)
f.close()
draw_signature(SIGNATURE_PATH)
def draw_signature(path):
f=open(path,'r',encoding='utf-8').read()
cut_text=" ".join(jieba.cut(f))
coloring=np.array(Image.open('F:/files/3.png'))
my_wordclound=WordCloud(background_color='white',
max_words=6000,mask=coloring,
max_font_size=60,random_state=42,
scale=2,font_path='C:/Windows/Fonts/simfang.ttf',
).generate(cut_text)
image = WordCloud.to_image(my_wordclound)
image.show()
parse_friends()
parse_signature()