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


Posted in Python onJanuary 27, 2016

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

基于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',
'_': 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()
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, wxsid,
# wxuin, pass_ticket))
if not all((skey, wxsid, wxuin, 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, 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 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': '',
}
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, BlockedList
def 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 state
def 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, 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()),
}
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 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, 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_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实现微信搜索查看谁把你删除了的相关内容,希望对大家有所帮助。

Python 相关文章推荐
python实现的jpg格式图片修复代码
Apr 21 Python
详解在Python中处理异常的教程
May 24 Python
Python自定义类的数组排序实现代码
Aug 28 Python
使用python爬取B站千万级数据
Jun 08 Python
python如何创建TCP服务端和客户端
Aug 26 Python
在python下读取并展示raw格式的图片实例
Jan 24 Python
详解Python3中setuptools、Pip安装教程
Jun 18 Python
python for循环remove同一个list过程解析
Aug 14 Python
Python实现病毒仿真器的方法示例(附demo)
Feb 19 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
Python3基于plotly模块保存图片表格
Aug 03 Python
详解Pycharm安装及Django安装配置指南
Sep 15 Python
Python图像灰度变换及图像数组操作
Jan 27 #Python
让python在hadoop上跑起来
Jan 27 #Python
CentOS安装pillow报错的解决方法
Jan 27 #Python
python实现文本去重且不打乱原本顺序
Jan 26 #Python
举例讲解Python设计模式编程中的访问者与观察者模式
Jan 26 #Python
Python函数中*args和**kwargs来传递变长参数的用法
Jan 26 #Python
python中的编码知识整理汇总
Jan 26 #Python
You might like
php指定函数参数默认值示例代码
2013/12/04 PHP
PHP加密解密类实例代码
2016/07/20 PHP
接收键盘指令的脚本
2006/06/26 Javascript
js版本A*寻路算法
2006/12/22 Javascript
在图片上显示左右箭头类似翻页的代码
2013/03/04 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
解析img图片没找到onerror事件 Stack overflow at line: 0
2013/12/23 Javascript
JavaScript实现带播放列表的音乐播放器实例分享
2016/03/07 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
2016/07/09 Javascript
JavaScript String(字符串)对象的简单实例(推荐)
2016/08/31 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
PHP实现记录代码运行时间封装类实例教程
2017/05/08 Javascript
easyUI下拉列表点击事件使用方法
2017/05/18 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
Vue实现数据请求拦截
2019/10/23 Javascript
详解为element-ui的Select和Cascader添加弹层底部操作按钮
2020/02/07 Javascript
vue实现放大镜效果
2020/09/17 Javascript
vue项目开启Gzip压缩和性能优化操作
2020/10/26 Javascript
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
详解Golang 与python中的字符串反转
2017/07/21 Python
python DataFrame 修改列的顺序实例
2018/04/10 Python
python  创建一个保留重复值的列表的补码
2018/10/15 Python
Django用户认证系统 组与权限解析
2019/08/02 Python
python如何查看网页代码
2020/06/07 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
Python与C/C++的相互调用案例
2021/03/04 Python
关于老式浏览器兼容HTML5和CSS3的问题
2016/06/01 HTML / CSS
如何使用canvas绘制可移动网格的示例代码
2020/12/14 HTML / CSS
《雷雨》教学反思
2014/02/20 职场文书
爸爸的花儿落了教学反思
2014/02/20 职场文书
健康教育评估方案
2014/05/25 职场文书
我的中国梦演讲稿初中篇
2014/08/19 职场文书
离婚协议书范本2014
2014/10/27 职场文书
单位综合评价意见
2015/06/05 职场文书
vue中data改变后让视图同步更新的方法
2021/03/29 Vue.js
pycharm无法安装cv2模块问题
2022/05/20 Python