為什么80%的碼農都做不了架構師?>>> ??
從Github上的https://github.com/0x5e/wechat-deleted-friends--clone出來的代碼?今天在我的機器上不能運行了,環境為Mac?10.10 python2.7.10中 提示錯誤,
Traceback?(most?recent?call?last):File?"/Users/fengtao/Desktop/codeTest/python/wechat-deleted-friends/wdf.py",?line?6,?in?<module>import?requests
ImportError:?No?module?named?requests
拷貝一份留念:
# wechat-deleted-friends
查看被刪的微信好友
原理就是新建群組,如果加不進來就是被刪好友了(不要在群組里講話,別人是看不見的)
用的是微信網頁版的接口
查詢結果可能會引起一些心理上的不適,請小心使用..(逃
Mac OS用法:
啟動Terminal
`$ python wdf.py`
按指示做即可
### 暫未解決的問題
錯誤1205 "操作太頻繁,請稍后再試。" (存在接口訪問限制)
windows中 可能出現正常掃碼 但是無法獲取正確好友數量的可能,應該是win8 還是什么版本 對應的python版本不正確,修改后,可以正常使用 ?提示出正常好友數量后 稍等即可獲得。
不清楚接口的限制策略是什么,有的同學能用有的不能用
打印被拉黑的列表(被限制了,沒法測試..)
URLError (網絡異常未處理)
最終會遺留下一個只有自己的群組,需要手工刪一下
#!/usr/bin/env?python
#?coding=utf-8
from?__future__?import?print_functionimport?os
try:from?urllib?import?urlencode,?quote_plus
except?ImportError:from?urllib.parse?import?urlencode,?quote_plustry:import?urllib2?as?wdf_urllibfrom?cookielib?import?CookieJar
except?ImportError:import?urllib.request?as?wdf_urllibfrom?http.cookiejar?import?CookieJarimport?re
import?time
import?xml.dom.minidom
import?json
import?sys
import?math
import?subprocess
import?ssl
import?threadDEBUG?=?FalseMAX_GROUP_NUM?=?35??#?每組人數
INTERFACE_CALLING_INTERVAL?=?20??#?接口調用時間間隔,?間隔太短容易出現"操作太頻繁",?會被限制操作半小時左右
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?getRequest(url,?data=None):try:data?=?data.encode('utf-8')except:passfinally:return?wdf_urllib.Request(url=url,?data=data)def?getUUID():global?uuidurl?=?'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?Truereturn?Falsedef?showQRImage():global?tipurl?=?'https://login.weixin.qq.com/qrcode/'?+?uuidparams?=?{'t':?'webwx','_':?int(time.time()),}request?=?getRequest(url=url,?data=urlencode(params))response?=?wdf_urllib.urlopen(request)tip?=?1f?=?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_uriurl?=?'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?=?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,?BaseRequestrequest?=?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.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}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,?SyncKeydic?=?json.loads(data)ContactList?=?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()))request?=?getRequest(url=url)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(),?'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?MemberListdef?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':?'',}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?=?[]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,?BlockedListdef?deleteMember(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)state?=?responseState('deleteMember',?dic['BaseResponse'])return?statedef?addMember(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?=?[]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,?BlockedListdef?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()),}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?selectordef?webwxsync():global?SyncKeyurl?=?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()),}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)SyncKey?=?dic['SyncKey']state?=?responseState('webwxsync',?dic['BaseResponse'])return?statedef?heartBeatLoop():while?True:selector?=?syncCheck()if?selector?!=?'0':webwxsync()time.sleep(1)def?main():try:ssl._create_default_https_context?=?ssl._create_unverified_contextopener?=?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:passif?not?getUUID():print('獲取uuid失敗')returnprint('正在獲取二維碼圖片...')showQRImage()time.sleep(1)while?waitForLogin()?!=?'200':passos.remove(QRImagePath)if?not?login():print('登錄失敗')returnif?not?webwxinit():print('初始化失敗')returnMemberList?=?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:breakMember?=?MemberList[i?*?MAX_GROUP_NUM?+?j]UserNames.append(Member['UserName'])#?新建群組/添加成員if?ChatRoomName?==?'':(ChatRoomName,?DeletedList,?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_numprint('[',?'#'?*?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))#?過濾emojiresultNames?=?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/8442718class?UnicodeStreamFilter:def?__init__(self,?target):self.target?=?targetself.encoding?=?'utf-8'self.errors?=?'replace'self.encode_to?=?self.target.encodingdef?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('回車鍵退出...')
轉載于:https://my.oschina.net/soci/blog/634847
總結
以上是生活随笔為你收集整理的github 上微信判断是否被删除的源码 以及使用解惑的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。