热腾网

 找回密码
 加入热腾

QQ登录

只需一步,快速开始

搜索
热腾网 首页 腾讯手机 QQ微信 查看内容

不知道被谁删了微信好友?用 Python 来帮忙呀!

2017-11-5 11:19| 发布者: 热腾网| 查看: 2858| 评论: 0

摘要: 原标题:不知道被谁删了微信好友?用 Python 来帮忙呀! 还在苦恼不知道被谁删了微信好友么?这里有个gaosen 编写的工具可帮到你: 查看被删的微信好友。原理就是新建群组,如果加不进来就是被删 ...

原标题:不知道被谁删了微信好友?用 Python 来帮忙呀!

还在苦恼不知道被谁删了微信好友么?这里有个gaosen 编写的工具可帮到你:

查看被删的微信好友。原理就是新建群组,如果加不进来就是被删好友了(不要在群组里讲话,别人是看不见的)。

用的是微信网页版的接口。查询结果可能会引起一些心理上的不适,请小心使用……

gaosen 说还有些小问题:

  • 结果好像有疏漏一小部分,原因不明..

  • 最终会遗留下一个只有自己的群组,需要手工删一下

  • 没试过被拉黑的情况

Mac OS用法:启动终端

$ python wdf.py

不过大家要先把源代码下载保存到 wdf.y 文件中。源码下面:

#!/usr/bin/env python

# coding=utf-8

from__future__importprint_function

importos

try:

fromurllibimporturlencode

exceptImportError:

fromurllib.parse importurlencode

try:

importurllib2aswdf_urllib

fromcookielibimportCookieJar

exceptImportError:

importurllib.request aswdf_urllib

fromhttp.cookiejar importCookieJar

importre

importtime

importxml.dom.minidom

importjson

importsys

importmath

importsubprocess

importssl

DEBUG= False

MAX_GROUP_NUM= 35# 每组人数

INTERFACE_CALLING_INTERVAL= 16# 接口调用时间间隔, 值设为13时亲测出现"操作太频繁"

MAX_PROGRESS_LEN= 50

QRImagePath= os.path.join(os.getcwd(),'qrcode.jpg')

tip= 0

uuid= ''

base_uri= ''

redirect_uri= ''

skey= ''

wxsid= ''

wxuin= ''

pass_ticket= ''

deviceId= 'e000000000000000'

BaseRequest= {}

ContactList= []

My= []

SyncKey= ''

try:

xrange

range= xrange

except:

# python 3

pass

defgetRequest(url,data=None):

try:

data= data.encode('utf-8')

except:

pass

finally:

returnwdf_urllib.Request(url=url,data=data)

defgetUUID():

globaluuid

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)

ifcode== '200':

returnTrue

returnFalse

defshowQRImage():

globaltip

url= 'https://login.weixin.qq.com/qrcode/'+ uuid

params= {

't': 'webwx',

'_': int(time.time()),

}

request= getRequest(url=url,data=urlencode(params))

response= wdf_urllib.urlopen(request)

tip= 1

f= open(QRImagePath,'wb')

f.write(response.read())

f.close()

ifsys.platform.find('darwin')>= 0:

subprocess.call(['open',QRImagePath])

elifsys.platform.find('linux')>= 0:

subprocess.call(['xdg-open',QRImagePath])

else:

os.startfile(QRImagePath)

defwaitForLogin():

globaltip,base_uri,redirect_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)

ifcode== '201': # 已扫描

print('成功扫描,请在手机上点击确认以登录')

tip= 0

elifcode== '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('/')]

# closeQRImage

ifsys.platform.find('darwin')>= 0: # for OSX with Preview

os.system("osa -e 'quit app "Preview"'")

elifcode== '408': # 超时

pass

# elif code == '400' or code == '500':

returncode

deflogin():

globalskey,wxsid,wxuin,pass_ticket,BaseRequest

request= getRequest(url=redirect_uri)

response= wdf_urllib.urlopen(request)

data= response.read().decode('utf-8','replace')

# print(data)

'''

<error>

<ret>0</ret>

<message>OK</message>

<skey>xxx</skey>

<wxsid>xxx</wxsid>

<wxuin>xxx</wxuin>

<pass_ticket>xxx</pass_ticket>

<isgrayscale>1</isgrayscale>

</error>

'''

doc= xml.dom.minidom.parseString(data)

root= doc.documentElement

fornode inroot.childNodes:

ifnode.nodeName== 'skey':

skey= node.childNodes[0].data

elifnode.nodeName== 'wxsid':

wxsid= node.childNodes[0].data

elifnode.nodeName== 'wxuin':

wxuin= node.childNodes[0].data

elifnode.nodeName== 'pass_ticket':

pass_ticket= node.childNodes[0].data

# print('skey: %s, wxsid: %s, wxuin: %s, pass_ticket: %s' % (skey, wxsid,

# wxuin, pass_ticket))

ifnotall((skey,wxsid,wxuin,pass_ticket)):

returnFalse

BaseRequest= {

'Uin': int(wxuin),

'Sid': wxsid,

'Skey': skey,

'DeviceID': deviceId,

}

returnTrue

defwebwxinit():

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()

ifDEBUG:

f= open(os.path.join(os.getcwd(),'webwxinit.json'),'wb')

f.write(data)

f.close()

data= data.decode('utf-8','replace')

# print(data)

globalContactList,My,SyncKey

dic= json.loads(data)

ContactList= dic['ContactList']

My= dic['User']

SyncKeyList= []

foritem indic['SyncKey']['List']:

SyncKeyList.append('%s_%s'% (item['Key'],item['Val']))

SyncKey= '|'.join(SyncKeyList)

ErrMsg= dic['BaseResponse']['ErrMsg']

ifDEBUG:

print("Ret: %d, ErrMsg: %s"% (dic['BaseResponse']['Ret'],ErrMsg))

Ret= dic['BaseResponse']['Ret']

ifRet!= 0:

returnFalse

returnTrue

defwebwxgetcontact():

url= base_uri+

'/webwxgetcontact?pass_ticket=%s&skey=%s&r=%s'% (

pass_ticket,skey,int(time.time()))

request= getRequest(url=url)

request.add_header('ContentType','application/json; charset=UTF-8')

response= wdf_urllib.urlopen(request)

data= response.read()

ifDEBUG:

f= open(os.path.join(os.getcwd(),'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"]

foriinrange(len(MemberList)- 1,-1,-1):

Member= MemberList[i]

ifMember['VerifyFlag']& 8!= 0: # 公众号/服务号

MemberList.remove(Member)

elifMember['UserName']inSpecialUsers: # 特殊账号

MemberList.remove(Member)

elifMember['UserName'].find('@@')!= -1: # 群聊

MemberList.remove(Member)

elifMember['UserName']== My['UserName']: # 自己

MemberList.remove(Member)

returnMemberList

defcreateChatroom(UserNames):

# MemberList = []

# for UserName in UserNames:

# MemberList.append({'UserName': UserName})

MemberList= [{'UserName': UserName}forUserName inUserNames]

url= base_uri+

'/webwxcreatechatroom?pass_ticket=%s&r=%s'% (

pass_ticket,int(time.time()))

params= {

'BaseRequest': BaseRequest,

'MemberCount': len(MemberList),

'MemberList': MemberList,

'Topic': '',

}

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().decode('utf-8','replace')

# print(data)

dic= json.loads(data)

ChatRoomName= dic['ChatRoomName']

MemberList= dic['MemberList']

DeletedList= []

forMember inMemberList:

ifMember['MemberStatus']== 4: # 被对方删除了

DeletedList.append(Member['UserName'])

ErrMsg= dic['BaseResponse']['ErrMsg']

ifDEBUG:

print("Ret: %d, ErrMsg: %s"% (dic['BaseResponse']['Ret'],ErrMsg))

returnChatRoomName,DeletedList

defdeleteMember(ChatRoomName,UserNames):

url= base_uri+

'/webwxupdatechatroom?fun=delmember&pass_ticket=%s'% (pass_ticket)

params= {

'BaseRequest': BaseRequest,

'ChatRoomName': ChatRoomName,

'DelMemberList': ','.join(UserNames),

}

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().decode('utf-8','replace')

# print(data)

dic= json.loads(data)

ErrMsg= dic['BaseResponse']['ErrMsg']

Ret= dic['BaseResponse']['Ret']

ifDEBUG:

print("Ret: %d, ErrMsg: %s"% (Ret,ErrMsg))

ifRet!= 0:

returnFalse

returnTrue

defaddMember(ChatRoomName,UserNames):

url= base_uri+

'/webwxupdatechatroom?fun=addmember&pass_ticket=%s'% (pass_ticket)

params= {

'BaseRequest': BaseRequest,

'ChatRoomName': ChatRoomName,

'AddMemberList': ','.join(UserNames),

}

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().decode('utf-8','replace')

# print(data)

dic= json.loads(data)

MemberList= dic['MemberList']

DeletedList= []

forMember inMemberList:

ifMember['MemberStatus']== 4: # 被对方删除了

DeletedList.append(Member['UserName'])

ErrMsg= dic['BaseResponse']['ErrMsg']

ifDEBUG:

print("Ret: %d, ErrMsg: %s"% (dic['BaseResponse']['Ret'],ErrMsg))

returnDeletedList

defsyncCheck():

url= base_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"}

defmain():

try:

ssl._create_default_https_context= ssl._create_unverified_context

opener= wdf_urllib.build_opener(

wdf_urllib.HTTPCookieProcessor(CookieJar()))

wdf_urllib.install_opener(opener)

except:

pass

ifnotgetUUID():

print('获取uuid失败')

return

showQRImage()

time.sleep(1)

whilewaitForLogin()!= '200':

pass

os.remove(QRImagePath)

ifnotlogin():

print('登录失败')

return

ifnotwebwxinit():

print('初始化失败')

return

MemberList= webwxgetcontact()

MemberCount= len(MemberList)

print('通讯录共%s位好友'% MemberCount)

ChatRoomName= ''

result= []

d= {}

forMember inMemberList:

d[Member['UserName']]= (Member['NickName'].encode(

'utf-8'),Member['RemarkName'].encode('utf-8'))

print('开始查找...')

group_num= int(math.ceil(MemberCount/ float(MAX_GROUP_NUM)))

foriinrange(0,group_num):

UserNames= []

forjinrange(0,MAX_GROUP_NUM):

ifi* MAX_GROUP_NUM+ j>= MemberCount:

break

Member= MemberList[i* MAX_GROUP_NUM+ j]

UserNames.append(Member['UserName'])

# 新建群组/添加成员

ifChatRoomName== '':

(ChatRoomName,DeletedList)= createChatroom(UserNames)

else:

DeletedList= addMember(ChatRoomName,UserNames)

DeletedCount= len(DeletedList)

ifDeletedCount> 0:

result+= DeletedList

# 删除成员

deleteMember(ChatRoomName,UserNames)

# 进度条

progress_len= MAX_PROGRESS_LEN

progress= '-'* progress_len

progress_str= '%s'% ''.join(

map(lambdax: '#',progress[:(progress_len* (i+ 1))/ group_num]))

print(''.join(

['[',progress_str,''.join('-'* (progress_len- len(progress_str))),']']))

print('新发现你被%d人删除'% DeletedCount)

foriinrange(DeletedCount):

ifd[DeletedList[i]][1]!= '':

print(d[DeletedList[i]][0]+ '(%s)'% d[DeletedList[i]][1])

else:

print(d[DeletedList[i]][0])

ifi!= group_num- 1:

print('正在继续查找,请耐心等待...')

# 下一次进行接口调用需要等待的时间

time.sleep(INTERFACE_CALLING_INTERVAL)

# todo 删除群组

print('n结果汇总完毕,20s后可重试...')

resultNames= []

forrinresult:

ifd[r][1]!= '':<


杯具

无语

很好

蛋定

愤怒

最新评论


热腾网X

未实名认证用户将不可发帖!

即日起,未实名认证用户将不可发帖,注册后,发帖请遵守当地法律法规。 【点击进行实名认证】...

点击查看详情