微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

基于Python实现通过微信搜索功能查看谁把你删除了

场景:查找who删了我,直接copy代码保存到一个python文件who.py,在python环境下运行此文件

代码如下,copy保存到who.py文件在python环境直接运行:

#!/usr/bin/env python
# coding=utf-8
from __future__ import print_function
import os
try:
from urllib import urlencode,quote_plus
except ImportError:
from urllib.parse import urlencode,quote_plus
try:
import urllib2 as wdf_urllib
from cookielib import CookieJar
except ImportError:
import urllib.request as wdf_urllib
from http.cookiejar import CookieJar
import re
import time
import xml.dom.minidom
import json
import sys
import math
import subprocess
import ssl
import thread
DEBUG = False
MAX_GROUP_NUM = 35 # 每组人数
INTERFACE_CALLING_INTERVAL = 20 # 接口调用时间间隔,间隔太短容易出现"操作太频繁",会被限制操作半小时左右
MAX_PROGRESS_LEN = 50
QRImagePath = 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:
xrange
range = xrange
except:
# python 3
pass
def 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 False
return True
def getRequest(url,data=None):
try:
data = data.encode('utf-8')
except:
pass
finally:
return wdf_urllib.Request(url=url,data=data)
def getUUID():
global uuid
url = 'https://login.weixin.qq.com/jslogin'
params = {
'appid': 'wx782c26e4c19acffb','fun': 'new','lang': 'zh_CN','_': int(time.time()),}
request = getRequest(url=url,data=urlencode(params))
response = wdf_urllib.urlopen(request)
data = response.read().decode('utf-8','replace')
# 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 True
return False
def showQRImage():
global tip
url = 'https://login.weixin.qq.com/qrcode/' + uuid
params = {
't': 'webwx',data=urlencode(params))
response = wdf_urllib.urlopen(request)
tip = 1
f = open(QRImagePath,'wb')
f.write(response.read())
f.close()
if sys.platform.find('darwin') >= 0:
subprocess.call(['open',QRImagePath])
elif sys.platform.find('linux') >= 0:
subprocess.call(['xdg-open',QRImagePath])
else:
os.startfile(QRImagePath)
print('请使用微信扫描二维码登录')
def waitForLogin():
global tip,base_uri,redirect_uri,push_uri
url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s' % (
tip,uuid,int(time.time()))
request = getRequest(url=url)
response = wdf_urllib.urlopen(request)
data = response.read().decode('utf-8','replace')
# print(data)
# window.code=500;
regx = r'window.code=(\d+);'
pm = re.search(regx,data)
code = pm.group(1)
if code == '201': # 已扫描
print('成功扫描,请在手机上点击确认以登录')
tip = 0
elif 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_uri
for (searchUrl,pushUrl) in services:
if base_uri.find(searchUrl) >= 0:
push_uri = 'https://%s/cgi-bin/mmwebwx-bin' % pushUrl
break
# closeQRImage
if sys.platform.find('darwin') >= 0: # for OSX with Preview
os.system("osascript -e 'quit app \"Preview\"'")
elif code == '408': # 超时
pass
# elif code == '400' or code == '500':
return code
def login():
global skey,wxsid,wxuin,pass_ticket,BaseRequest
request = getRequest(url=redirect_uri)
response = wdf_urllib.urlopen(request)
data = response.read().decode('utf-8','replace')
# print(data)
doc = xml.dom.minidom.parseString(data)
root = doc.documentElement
for node in root.childNodes:
if node.nodeName == 'skey':
skey = node.childNodes[0].data
elif node.nodeName == 'wxsid':
wxsid = node.childNodes[0].data
elif node.nodeName == 'wxuin':
wxuin = node.childNodes[0].data
elif node.nodeName == 'pass_ticket':
pass_ticket = node.childNodes[0].data
# print('skey: %s,wxsid: %s,wxuin: %s,pass_ticket: %s' % (skey,# wxuin,pass_ticket))
if not all((skey,pass_ticket)):
return False
BaseRequest = {
'Uin': int(wxuin),'Sid': wxsid,'Skey': skey,'deviceid': deviceid,}
return True
def webwxinit():
url = base_uri + \
'/webwxinit?pass_ticket=%s&skey=%s&r=%s' % (
pass_ticket,skey,int(time.time()))
params = {
'BaseRequest': BaseRequest
}
request = getRequest(url=url,data=json.dumps(params))
request.add_header('ContentType','application/json; charset=UTF-8')
response = wdf_urllib.urlopen(request)
data = response.read()
if DEBUG:
f = open(os.path.join(os.getcwd(),'webwxinit.json'),'wb')
f.write(data)
f.close()
data = data.decode('utf-8','replace')
# print(data)
global ContactList,My,SyncKey
dic = json.loads(data)
ContactList = dic['ContactList']
My = dic['User']
SyncKey = dic['SyncKey']
state = responseState('webwxinit',dic['BaseResponse'])
return state
def webwxgetcontact():
url = base_uri + \
'/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s' % (
pass_ticket,int(time.time()))
request = getRequest(url=url)
request.add_header('ContentType','webwxgetcontact.json'),'wb')
f.write(data)
f.close()
# print(data)
data = data.decode('utf-8','replace')
dic = json.loads(data)
MemberList = 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 MemberList
def createChatroom(UserNames):
MemberList = [{'UserName': UserName} for UserName in UserNames]
url = base_uri + \
'/webwxcreatechatroom?pass_ticket=%s&r=%s' % (
pass_ticket,int(time.time()))
params = {
'BaseRequest': BaseRequest,'MemberCount': len(MemberList),'MemberList': MemberList,'Topic': '','application/json; charset=UTF-8')
response = wdf_urllib.urlopen(request)
data = response.read().decode('utf-8','replace')
# print(data)
dic = json.loads(data)
ChatRoomName = dic['ChatRoomName']
MemberList = dic['MemberList']
DeletedList = []
BlockedList = []
for Member in MemberList:
if Member['MemberStatus'] == 4: # 被对方删除了
DeletedList.append(Member['UserName'])
elif Member['MemberStatus'] == 3: # 被加入黑名单
BlockedList.append(Member['UserName'])
state = responseState('createChatroom',dic['BaseResponse'])
return ChatRoomName,DeletedList,BlockedList
def deleteMember(ChatRoomName,UserNames):
url = base_uri + \
'/webwxupdatechatroom?fun=delmember&pass_ticket=%s' % (pass_ticket)
params = {
'BaseRequest': BaseRequest,'ChatRoomName': ChatRoomName,'DelMemberList': ','.join(UserNames),'replace')
# print(data)
dic = json.loads(data)
state = responseState('deleteMember',dic['BaseResponse'])
return state
def addMember(ChatRoomName,UserNames):
url = base_uri + \
'/webwxupdatechatroom?fun=addmember&pass_ticket=%s' % (pass_ticket)
params = {
'BaseRequest': BaseRequest,'AddMemberList': ','replace')
# print(data)
dic = json.loads(data)
MemberList = dic['MemberList']
DeletedList = []
BlockedList = []
for Member in MemberList:
if Member['MemberStatus'] == 4: # 被对方删除了
DeletedList.append(Member['UserName'])
elif Member['MemberStatus'] == 3: # 被加入黑名单
BlockedList.append(Member['UserName'])
state = responseState('addMember',dic['BaseResponse'])
return DeletedList,BlockedList
def syncKey():
SyncKeyItems = ['%s_%s' % (item['Key'],item['Val'])
for item in SyncKey['List']]
SyncKeyStr = '|'.join(SyncKeyItems)
return SyncKeyStr
def syncCheck():
url = push_uri + '/synccheck?'
params = {
'skey': BaseRequest['Skey'],'sid': BaseRequest['Sid'],'uin': BaseRequest['Uin'],'deviceid': BaseRequest['deviceid'],'synckey': syncKey(),'r': int(time.time()),}
request = getRequest(url=url + urlencode(params))
response = wdf_urllib.urlopen(request)
data = response.read().decode('utf-8','replace')
# 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 selector
def webwxsync():
global SyncKey
url = base_uri + '/webwxsync?lang=zh_CN&skey=%s&sid=%s&pass_ticket=%s' % (
BaseRequest['Skey'],BaseRequest['Sid'],quote_plus(pass_ticket))
params = {
'BaseRequest': BaseRequest,'SyncKey': SyncKey,'rr': ~int(time.time()),'replace')
# print(data)
dic = json.loads(data)
SyncKey = dic['SyncKey']
state = responseState('webwxsync',dic['BaseResponse'])
return state
def heartBeatLoop():
while True:
selector = syncCheck()
if selector != '0':
webwxsync()
time.sleep(1)
def main():
try:
ssl._create_default_https_context = ssl._create_unverified_context
opener = wdf_urllib.build_opener(
wdf_urllib.HTTPCookieProcessor(CookieJar()))
opener.addheaders = [
('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')]
wdf_urllib.install_opener(opener)
except:
pass
if not getUUID():
print('获取uuid失败')
return
print('正在获取二维码图片...')
showQRImage()
time.sleep(1)
while waitForLogin() != '200':
pass
os.remove(QRImagePath)
if not login():
print('登录失败')
return
if not webwxinit():
print('初始化失败')
return
MemberList = webwxgetcontact()
print('开启心跳线程')
thread.start_new_thread(heartBeatLoop,())
MemberCount = len(MemberList)
print('通讯录共%s位好友' % MemberCount)
ChatRoomName = ''
result = []
d = {}
for Member in MemberList:
d[Member['UserName']] = (Member['NickName'].encode(
'utf-8'),Member['RemarkName'].encode('utf-8'))
print('开始查找...')
group_num = int(math.ceil(MemberCount / float(MAX_GROUP_NUM)))
for i in range(0,group_num):
UserNames = []
for j in range(0,MAX_GROUP_NUM):
if i * MAX_GROUP_NUM + j >= MemberCount:
break
Member = MemberList[i * MAX_GROUP_NUM + j]
UserNames.append(Member['UserName'])
# 新建群组/添加成员
if ChatRoomName == '':
(ChatRoomName,BlockedList) = createChatroom(
UserNames)
else:
(DeletedList,BlockedList) = addMember(ChatRoomName,UserNames)
# todo BlockedList 被拉黑列表
DeletedCount = len(DeletedList)
if DeletedCount > 0:
result += DeletedList
# 删除成员
deleteMember(ChatRoomName,UserNames)
# 进度条
progress = MAX_PROGRESS_LEN * (i + 1) / group_num
print('[','#' * progress,'-' * (MAX_PROGRESS_LEN - progress),']',end=' ')
print('新发现你被%d人删除' % DeletedCount)
for i in range(DeletedCount):
if d[DeletedList[i]][1] != '':
print(d[DeletedList[i]][0] + '(%s)' % d[DeletedList[i]][1])
else:
print(d[DeletedList[i]][0])
if i != group_num - 1:
print('正在继续查找,请耐心等待...')
# 下一次进行接口调用需要等待的时间
time.sleep(INTERFACE_CALLING_INTERVAL)
# todo 删除群组
print('\n结果汇总完毕,20s后可重试...')
resultNames = []
for r in result:
if d[r][1] != '':
resultNames.append(d[r][0] + '(%s)' % d[r][1])
else:
resultNames.append(d[r][0])
print('---------- 被删除的好友列表(共%d人) ----------' % len(result))
# 过滤emoji
resultNames = map(lambda x: re.sub(r'<span.+/span>','',x),resultNames)
if len(resultNames):
print('\n'.join(resultNames))
else:
print("无")
print('---------------------------------------------')
# windows下编码问题修复
# http://blog.csdn.net/heyuxuanzee/article/details/8442718
class UnicodeStreamFilter:
def __init__(self,target):
self.target = target
self.encoding = 'utf-8'
self.errors = 'replace'
self.encode_to = self.target.encoding
def write(self,s):
if type(s) == str:
s = s.decode('utf-8')
s = s.encode(self.encode_to,self.errors).decode(self.encode_to)
self.target.write(s)
if sys.stdout.encoding == 'cp936':
sys.stdout = UnicodeStreamFilter(sys.stdout)
if __name__ == '__main__':
print('本程序的查询结果可能会引起一些心理上的不适,请小心使用...')
main()
print('回车键退出...')

以上所述是基于Python实现微信搜索查看谁把你删除了的相关内容,希望对大家有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open