目录

第一步:首先抓取微信朋友的资料

第二步:性别统计和地区分布

第三步:生成省份好友分布地图

第四步:最后运用opencv的图像识别进行人像识别,统计微信好友中用人像作为头像的好友人数。


微信一共有多少位好友?这里面你认识多少人?你知道你微信朋友的男女比例嘛?你知道你微信朋友大部分来自什么地方吗?

以下的代码内容只涉及一些简单的Python知识,稍微有一点Python知识的朋友都可以读下去。

第一步:首先抓取微信朋友的资料

既然是要做统计和分析,第一步就是微信朋友的所有可以抓取的资料抓取出来。所谓有用的资料大致来说有以下几个内容:

昵称、微信号、城市、性别、星标好友、头像、个性签名、备注

每一项或者联合项可以做的统计

性别:好友性别统计

城市:好友地区分布

备注+昵称:大致统计认识的好友比例

头像:人脸识别

那么如何抓取呢?这里使用了之前有一位大神写的如何找出被删的好友的代码,修改部分为从提取json数据截断,对返回的json数据进行提取分别找到了以下的所需要的信息:

代码修改为:

#!/usr/bin/env python
# encoding=utf-8
from __future__ import print_functionimport os
import requests
import re
import time
import xml.dom.minidom
import json
import sys
import math
import subprocess
import ssl
import threading
import urllib,urllib2DEBUG = FalseMAX_GROUP_NUM = 2  # 每组人数
INTERFACE_CALLING_INTERVAL = 5  # 接口调用时间间隔, 间隔太短容易出现"操作太频繁", 会被限制操作半小时左右
MAX_PROGRESS_LEN = 50QRImagePath = os.path.join(os.getcwd(), 'qrcode.jpg')tip = 0
uuid = ''base_uri = ''
redirect_uri = ''
push_uri = ''skey = ''
wxsid = ''
wxuin = ''
pass_ticket = ''
deviceId = 'e000000000000000'BaseRequest = {}ContactList = []
My = []
SyncKey = []try:xrangerange = xrange
except:# python 3passdef responseState(func, BaseResponse):ErrMsg = BaseResponse['ErrMsg']Ret = BaseResponse['Ret']if DEBUG or Ret != 0:print('func: %s, Ret: %d, ErrMsg: %s' % (func, Ret, ErrMsg))if Ret != 0:return Falsereturn Truedef getUUID():global uuidurl = 'https://login.weixin.qq.com/jslogin'params = {'appid': 'wx782c26e4c19acffb','fun': 'new','lang': 'zh_CN','_': int(time.time()),}r= myRequests.get(url=url, params=params)r.encoding = 'utf-8'data = r.text# print(data)# window.QRLogin.code = 200; window.QRLogin.uuid = "oZwt_bFfRg==";regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)"'pm = re.search(regx, data)code = pm.group(1)uuid = pm.group(2)if code == '200':return Truereturn Falsedef showQRImage():global tipurl = 'https://login.weixin.qq.com/qrcode/' + uuidparams = {'t': 'webwx','_': int(time.time()),}r = myRequests.get(url=url, params=params)tip = 1f = open(QRImagePath, 'wb')f.write(r.content)f.close()time.sleep(1)if sys.platform.find('darwin') >= 0:subprocess.call(['open', QRImagePath])else:subprocess.call(['xdg-open', QRImagePath])print('请使用微信扫描二维码以登录')def waitForLogin():global tip, base_uri, redirect_uri, push_uriurl = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s' % (tip, uuid, int(time.time()))r = myRequests.get(url=url)r.encoding = 'utf-8'data = r.text# print(data)# window.code=500;regx = r'window.code=(\d+);'pm = re.search(regx, data)code = pm.group(1)if code == '201':  # 已扫描print('成功扫描,请在手机上点击确认以登录')tip = 0elif code == '200':  # 已登录print('正在登录...')regx = r'window.redirect_uri="(\S+?)";'pm = re.search(regx, data)redirect_uri = pm.group(1) + '&fun=new'base_uri = redirect_uri[:redirect_uri.rfind('/')]# push_uri与base_uri对应关系(排名分先后)(就是这么奇葩..)services = [('wx2.qq.com', 'webpush2.weixin.qq.com'),('qq.com', 'webpush.weixin.qq.com'),('web1.wechat.com', 'webpush1.wechat.com'),('web2.wechat.com', 'webpush2.wechat.com'),('wechat.com', 'webpush.wechat.com'),('web1.wechatapp.com', 'webpush1.wechatapp.com'),]push_uri = base_urifor (searchUrl, pushUrl) in services:if base_uri.find(searchUrl) >= 0:push_uri = 'https://%s/cgi-bin/mmwebwx-bin' % pushUrlbreak# closeQRImageif sys.platform.find('darwin') >= 0:  # for OSX with Previewos.system("osascript -e 'quit app \"Preview\"'")elif code == '408':  # 超时pass# elif code == '400' or code == '500':return codedef login():global skey, wxsid, wxuin, pass_ticket, BaseRequestr = myRequests.get(url=redirect_uri)r.encoding = 'utf-8'data = r.text# print(data)doc = xml.dom.minidom.parseString(data)root = doc.documentElementfor node in root.childNodes:if node.nodeName == 'skey':skey = node.childNodes[0].dataelif node.nodeName == 'wxsid':wxsid = node.childNodes[0].dataelif node.nodeName == 'wxuin':wxuin = node.childNodes[0].dataelif node.nodeName == 'pass_ticket':pass_ticket = node.childNodes[0].data# print('skey: %s, wxsid: %s, wxuin: %s, pass_ticket: %s' % (skey, wxsid,# wxuin, pass_ticket))if not all((skey, wxsid, wxuin, pass_ticket)):return FalseBaseRequest = {'Uin': int(wxuin),'Sid': wxsid,'Skey': skey,'DeviceID': deviceId,}return Truedef webwxinit():url = (base_uri + '/webwxinit?pass_ticket=%s&skey=%s&r=%s' % (pass_ticket, skey, int(time.time())) )params  = {'BaseRequest': BaseRequest }headers = {'content-type': 'application/json; charset=UTF-8'}r = myRequests.post(url=url, data=json.dumps(params),headers=headers)r.encoding = 'utf-8'data = r.json()if DEBUG:f = open(os.path.join(os.getcwd(), 'webwxinit.json'), 'wb')f.write(r.content)f.close()# print(data)global ContactList, My, SyncKeydic = dataContactList = dic['ContactList']My = dic['User']SyncKey = dic['SyncKey']state = responseState('webwxinit', dic['BaseResponse'])return statedef webwxgetcontact():url = (base_uri + '/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s' % (pass_ticket, skey, int(time.time())) )headers = {'content-type': 'application/json; charset=UTF-8'}r = myRequests.post(url=url,headers=headers)r.encoding = 'utf-8'data = r.json()if DEBUG:f = open(os.path.join(os.getcwd(), 'webwxgetcontact.json'), 'wb')f.write(r.content)f.close()dic = dataMemberList = dic['MemberList']# 倒序遍历,不然删除的时候出问题..SpecialUsers = ["newsapp", "fmessage", "filehelper", "weibo", "qqmail", "tmessage", "qmessage", "qqsync", "floatbottle", "lbsapp", "shakeapp", "medianote", "qqfriend", "readerapp", "blogapp", "facebookapp", "masssendapp","meishiapp", "feedsapp", "voip", "blogappweixin", "weixin", "brandsessionholder", "weixinreminder", "wxid_novlwrv3lqwv11", "gh_22b87fa7cb3c", "officialaccounts", "notification_messages", "wxitil", "userexperience_alarm"]for i in range(len(MemberList) - 1, -1, -1):Member = MemberList[i]if Member['VerifyFlag'] & 8 != 0:  # 公众号/服务号MemberList.remove(Member)elif Member['UserName'] in SpecialUsers:  # 特殊账号MemberList.remove(Member)elif Member['UserName'].find('@@') != -1:  # 群聊MemberList.remove(Member)elif Member['UserName'] == My['UserName']:  # 自己MemberList.remove(Member)return MemberListdef syncKey():SyncKeyItems = ['%s_%s' % (item['Key'], item['Val'])for item in SyncKey['List']]SyncKeyStr = '|'.join(SyncKeyItems)return SyncKeyStrdef syncCheck():url = push_uri + '/synccheck?'params = {'skey': BaseRequest['Skey'],'sid': BaseRequest['Sid'],'uin': BaseRequest['Uin'],'deviceId': BaseRequest['DeviceID'],'synckey': syncKey(),'r': int(time.time()),}r = myRequests.get(url=url,params=params)r.encoding = 'utf-8'data = r.text# print(data)# window.synccheck={retcode:"0",selector:"2"}regx = r'window.synccheck={retcode:"(\d+)",selector:"(\d+)"}'pm = re.search(regx, data)retcode = pm.group(1)selector = pm.group(2)return selectordef webwxsync():global SyncKeyurl = base_uri + '/webwxsync?lang=zh_CN&skey=%s&sid=%s&pass_ticket=%s' % (BaseRequest['Skey'], BaseRequest['Sid'], urllib.quote_plus(pass_ticket))params = {'BaseRequest': BaseRequest,'SyncKey': SyncKey,'rr': ~int(time.time()),}headers = {'content-type': 'application/json; charset=UTF-8'}r = myRequests.post(url=url, data=json.dumps(params))r.encoding = 'utf-8'data = r.json()# print(data)dic = dataSyncKey = dic['SyncKey']state = responseState('webwxsync', dic['BaseResponse'])return statedef heartBeatLoop():while True:selector = syncCheck()if selector != '0':webwxsync()time.sleep(1)def main():global myRequestsif hasattr(ssl, '_create_unverified_context'):ssl._create_default_https_context = ssl._create_unverified_contextheaders = {'User-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.125 Safari/537.36'}myRequests = requests.Session()myRequests.headers.update(headers)if not getUUID():print('获取uuid失败')returnprint('正在获取二维码图片...')showQRImage()while waitForLogin() != '200':passos.remove(QRImagePath)if not login():print('登录失败')returnif not webwxinit():print('初始化失败')returnMemberList = webwxgetcontact()threading.Thread(target=heartBeatLoop)MemberCount = len(MemberList)print('通讯录共%s位好友' % MemberCount)d = {}imageIndex = 0for Member in MemberList:imageIndex = imageIndex + 1name = '/root/Desktop/friendImage/image'+str(imageIndex)+'.jpg'imageUrl = 'https://wx.qq.com'+Member['HeadImgUrl']r = myRequests.get(url=imageUrl,headers=headers)imageContent = (r.content)fileImage = open(name,'wb')fileImage.write(imageContent)fileImage.close()print('正在下载第:'+str(imageIndex)+'位好友头像')d[Member['UserName']] = (Member['NickName'], Member['RemarkName'])city = Member['City']city = 'nocity' if city == '' else  cityname = Member['NickName']name = 'noname' if name == '' else  namesign = Member['Signature']sign = 'nosign' if sign == '' else  signremark = Member['RemarkName']remark = 'noremark' if remark == '' else remarkalias = Member['Alias']alias = 'noalias' if alias == '' else aliasnick = Member['NickName']nick = 'nonick' if nick == '' else nickprint(name,'  ^+*+^  ',city,'  ^+*+^  ',Member['Sex'],' ^+*+^ ',Member['StarFriend'],' ^+*+^ ',sign,' ^+*+^ ',remark,' ^+*+^ ',alias,' ^+*+^ ',nick )if __name__ == '__main__':main()print('回车键退出...')input()

所返回的json结果如下图所示

昵称、微信号、城市、性别、星标好友、头像、个性签名、备注。提取以上信息,对头像图片进行下载,并对数据进行简单的清洗等等,最后一列为微信号不方便显示。

第二步:性别统计和地区分布

使用python的pandas科学计算库进行简单的统计,如果你没有用过,可以转至如下链接进行安装学习:【原】十分钟搞定pandas

只要掌握了非常简单的pandas只是就可以继续往下看做以下统计

(1)、所有好友的男女比例

(2)、所有好友的城市分布

(3)、统计认识的朋友以及占所有朋友的百分比

统计方法:所有朋友 - 没有备注的朋友 - 备注与昵称相同的朋友

(4)、统计认识的朋友中的男女比例

统计方法:对三的结果再进行男女划分即可得到结果

#-*- coding: UTF-8 -*-
import pandas as pd
df = pd.read_csv('/root/Desktop/friend02.csv')def city():'''微信朋友圈的城市'''address = df['city'].value_counts()print addressdef gender():'''微信朋友的性别比例1:男  2:女   3:未知'''gender = df['male'].value_counts()print genderdef star():'''星标好友1:星标   0:非星标'''star = df['star'].value_counts()print stardef remark():remark = df['remark']name = df['name']remarkCount = 0maleCount = 0femaleCount = 0for i in range(1,len(remark)):if str(remark[i]).strip() == str(name[i]).strip() or remark[i] == '  noremark  ':remarkCount = remarkCount + 1else:if judgeGender(i) == 'male':maleCount = maleCount + 1elif judgeGender(i) == 'female':femaleCount = femaleCount + 1print '微信总朋友人数:',str(len(remark)),'\n'print '预计认识的总人数:',str(len(remark)-remarkCount),'\n'print '认识的人中汉子人数:',maleCount,'妹子人数:',femaleCountdef judgeGender(index):'''判断传入的某个位置的用户的性别参数:int行返回结果:字符串'''gender = df['gender']if gender[index] == '1':return 'male'elif gender[index] == '2':return 'female'else:return 'unknown' if __name__=='__main__':remark()

把结果做成简单的图表(主要使用了百度的echarts作图)(不得不说百度其他产品虽然不怎么样,但是百度的echarts还是不错的哟,他的官网:http://echarts.baidu.com/)

使用地图慧江苏省好友分布,这个编码我不知怎么回事,可能是浏览器问题,回头我用其它浏览器查看一下。(地图汇比较傻瓜:http://www.dituhui.com/)

第三步:生成省份好友分布地图

第四步:最后运用opencv的图像识别进行人像识别,统计微信好友中用人像作为头像的好友人数。

OpenCV的全称是:Open Source Computer Vision Library。OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

如果你对opencv不是很了解,你可以按照以下的链接进行学习。

你可以去它的官网:http://opencv.org/ (需要有一定的英语知识)

如下开始是对抓取的朋友头像进行遍历识别是否含有人脸,代码如下。

#!/usr/bin/env python'''
face detection using haar cascadesUSAGE:facedetect.py [--cascade <cascade_fn>] [--nested-cascade <cascade_fn>] [<video_source>]
'''# Python 2/3 compatibility
from __future__ import print_functionimport numpy as np
import cv2# local modules
from video import create_capture
from common import clock, draw_strdef detect(img, cascade):rects = cascade.detectMultiScale(img, scaleFactor=1.3, minNeighbors=4, minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)if len(rects) == 0:return []rects[:,2:] += rects[:,:2]return rectsdef draw_rects(img, rects, color):for x1, y1, x2, y2 in rects:cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)if __name__ == '__main__':import sys, getoptprint(__doc__)count = 0for i in range(1,1192):print(str(i))args, video_src = getopt.getopt(sys.argv[1:], '', ['cascade=', 'nested-cascade='])try:video_src = video_src[0]except:video_src = 0args = dict(args)cascade_fn = args.get('--cascade', "../../data/haarcascades/haarcascade_frontalface_alt.xml")nested_fn  = args.get('--nested-cascade', "../../data/haarcascades/haarcascade_eye.xml")cascade = cv2.CascadeClassifier(cascade_fn)nested = cv2.CascadeClassifier(nested_fn)cam = create_capture(video_src, fallback='synth:bg=../data/friend/friendImage/image'+str(i)+'.jpg:noise=0.05')ret, img = cam.read()gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray = cv2.equalizeHist(gray)rects = detect(gray, cascade)vis = img.copy()draw_rects(vis, rects, (0, 255, 0))if not nested.empty():if len(rects) == 0:print('none')else:count = count + 1print(str(count))input()

执行以上代码统计出最后的结果

使用人像做头像的好友:59 因此不使用人像的1133,看来使用人像的人还是很少的。

运行提取人像头像的代码最后提取出的头像如下所示 ,不得不说Python的库真是十分的有用。(因为涉及到隐私,所以这里不会展示过多的头像)

最近仍然在研究签名以及头像的可用之处,也是欢迎大家一起学习交流。同时希望以上的内容可以提升一下大家的学习兴趣。关于微信好友的更多挖掘会不断进行。

(1)、人像头像与年龄之间的关系(由于微信没有年龄,于是想通过知乎进行推算)

(2)、个性签名与年龄性格之间的关系

(3)、微信号中所包含信息推算年龄层次,预测当前微信号年龄

用Python对微信好友进行简单统计分析相关推荐

  1. Python对微信好友进行简单统计分析

    早些日子有人问我我的微信里面有一共多少朋友,我就随后拉倒了通讯录最下面就找到了微信一共有多少位好友.然后他又问我,这里面你认识多少人?这一句话问的我很无语.一千多个好友我真的不知道认识的人有多少.他还 ...

  2. python微信好友分析_基于python实现微信好友数据分析(简单)

    一.功能介绍 本文主要介绍利用网页端微信获取数据,实现个人微信好友数据的获取,并进行一些简单的数据分析,功能包括: 1.爬取好友列表,显示好友昵称.性别和地域和签名, 文件保存为 xlsx 格式 2. ...

  3. 用python做头像_如何利用python制作微信好友头像照片墙?

    这个不难,主要用到itchat和pillow这2个库,其中itchat用于获取微信好友头像照片,pillow用于拼接头像生成一个照片墙,下面我简单介绍一下实现过程,代码量不多,也很好理解,实验环境wi ...

  4. 使用python生成微信好友个性签名词云图

    生成词云主要使用了itchat.jieba.wordcloud这三个依赖库 itchat itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单. jieba "结巴& ...

  5. python表白代码照片墙-如何利用python制作微信好友头像照片墙?

    这个不难,主要用到itchat和pillow这2个库,其中itchat用于获取微信好友头像照片,pillow用于拼接头像生成一个照片墙,下面我简单介绍一下实现过程,代码量不多,也很好理解,实验环境wi ...

  6. python制作微信个人二维码_如何用Python制作微信好友个性签名词云图

    前言 上次查看了微信好友的位置信息,想了想,还是不过瘾,于是就琢磨起了把微信好友的个性签名拿到,然后分词,接着分析词频,最后弄出词云图来. 1.环境说明 Win10 系统下 Python3,编译器是 ...

  7. 用Python给微信好友自动发送祝福语

    用Python给微信好友自动发送祝福语 学习了Python知识,可以做许多好玩的东西,可以用Python统计分析好友状态.好友性别.年龄.地区,以及好友签名等内容,今天咱们就用Python自动给微信好 ...

  8. Python爬微信好友头像,性别,所在地区

    Python爬微信好友头像,性别,所在地区 本文适合新手(有一定基础的小白) 今天没事,用的网页版微信,于是看源码心理作怪,F12打开,研究了一下,结果发现 /斜眼笑/斜眼笑/斜眼笑 再加上,没事干, ...

  9. python生成词云_今天玩点啥:使用python生成微信好友地域分析、微信昵称、个性签名词云...

    # -*- coding: UTF-8 -*- from wxpy import *from wxpy import * from os import path import re, jieba im ...

  10. 通过python分析微信好友数据

    随着微信的普及,越来越多的人开始使用微信.微信渐渐从一款单纯的社交软件转变成了一个生活方式,人们的日常沟通需要微信,工作交流也需要微信.微信里的每一个好友,都代表着人们在社会里扮演的不同角色.今天这篇 ...

最新文章

  1. python 进程池pool简单实例
  2. php请求接口数据,php curl请求接口并获取数据的示例代码
  3. 如何提升微服务的幸福感?
  4. Cannot open include file: jni.h: No such file or directory解决方法
  5. python摄像头识别快递单号查询_python如何免费对接快递鸟api单号识别查询接口
  6. nginx根据URL地址、user_agent设备类型、文件扩展名 实现动静分离代理转发
  7. 无线通信设备安装工程概预算编制_浙江正规设备安装工程安装-设计安装_天霖工程...
  8. SharePoint开发环境配置
  9. magicbookpro做php开发,荣耀MagicBook Pro锐龙版,一款为大学生量身打造的笔记本
  10. Android Studio插件GsonFormat快速实现JavaBean
  11. 数学知识——概率统计(11)小结:多个变量之间的关系描述
  12. 基于微信小程序的校园外卖订餐个性化推荐系统
  13. 故宫元宵灯会黄牛票最高要5千 律师:小心被拒
  14. Elasticsearch-好文推荐
  15. Core Data 详解
  16. C++ 小帅真的饿了
  17. Java-异常处理(编译时异常、运行时异常及处理机制,自定义异常)
  18. TensorRT报错的一百种姿势 | 【❤️TensorRT抱错砖家❤️】
  19. 百度大脑人脸识别深度验证与思考(十)之素妆对决
  20. 全球与中国色选机行业深度研究调查分析报告

热门文章

  1. 量化分析(6)——K线图、交易量图、动量图、rsi强度图
  2. 【CSP-S 2019模拟】题解
  3. 【修真院java小课堂】Shiro
  4. Ubuntu20.04.iso光盘镜像源文件百度云下载
  5. MVP是什么,不是什么
  6. 如何给外行解释云计算
  7. 熬夜肝出囊括Java后端95%的面试题解析
  8. MySQL系列数据库的安装和基本的使用方法笔记(MySQL,MariaDB)
  9. 科技爱好者周刊(第 190 期):产品化思维
  10. HFSS同轴馈电矩形贴片天线馈电点以及尺寸的计算