@@ -0,0 +1,2 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# coding: utf-8
|
||||||
@@ -9,7 +9,10 @@ import json
|
|||||||
import time, re, sys, os, random
|
import time, re, sys, os, random
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import platform
|
import platform
|
||||||
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from urlparse import urlparse
|
||||||
|
from lxml import html
|
||||||
|
|
||||||
def catchKeyboardInterrupt(fn):
|
def catchKeyboardInterrupt(fn):
|
||||||
def wrapper(*args):
|
def wrapper(*args):
|
||||||
@@ -17,6 +20,7 @@ def catchKeyboardInterrupt(fn):
|
|||||||
return fn(*args)
|
return fn(*args)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print '\n[*] 强制退出程序'
|
print '\n[*] 强制退出程序'
|
||||||
|
logging.debug('[*] 强制退出程序')
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def _decode_list(data):
|
def _decode_list(data):
|
||||||
@@ -79,16 +83,32 @@ class WebWeixin(object):
|
|||||||
self.GroupList = []
|
self.GroupList = []
|
||||||
self.autoReplyMode = False
|
self.autoReplyMode = False
|
||||||
self.syncHost = ''
|
self.syncHost = ''
|
||||||
|
self.user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36'
|
||||||
|
self.interactive = False
|
||||||
|
self.autoOpen = False
|
||||||
|
self.saveFolder = os.path.join(os.getcwd(), 'saved')
|
||||||
|
self.saveSubFolders = {'webwxgeticon': 'icons', 'webwxgetheadimg': 'headimgs', 'webwxgetmsgimg': 'msgimgs', 'webwxgetvideo': 'videos', 'webwxgetvoice': 'voices', '_showQRCodeImg': 'qrcodes'}
|
||||||
|
self.appid = 'wx782c26e4c19acffb'
|
||||||
|
self.lang = 'zh_CN'
|
||||||
|
|
||||||
|
|
||||||
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
|
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
|
||||||
|
opener.addheaders = [('User-agent', self.user_agent)]
|
||||||
urllib2.install_opener(opener)
|
urllib2.install_opener(opener)
|
||||||
|
|
||||||
|
def loadConfig(self, config):
|
||||||
|
if config['DEBUG']: self.DEBUG = config['DEBUG']
|
||||||
|
if config['autoReplyMode']: self.autoReplyMode = config['autoReplyMode']
|
||||||
|
if config['user_agent']: self.user_agent = config['user_agent']
|
||||||
|
if config['interactive']: self.interactive = config['interactive']
|
||||||
|
if config['autoOpen']: self.autoOpen = config['autoOpen']
|
||||||
|
|
||||||
def getUUID(self):
|
def getUUID(self):
|
||||||
url = 'https://login.weixin.qq.com/jslogin'
|
url = 'https://login.weixin.qq.com/jslogin'
|
||||||
params = {
|
params = {
|
||||||
'appid': 'wx782c26e4c19acffb',
|
'appid': self.appid,
|
||||||
'fun': 'new',
|
'fun': 'new',
|
||||||
'lang': 'zh_CN',
|
'lang': self.lang,
|
||||||
'_': int(time.time()),
|
'_': int(time.time()),
|
||||||
}
|
}
|
||||||
data = self._post(url, params, False)
|
data = self._post(url, params, False)
|
||||||
@@ -101,23 +121,20 @@ class WebWeixin(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def genQRCode(self):
|
def genQRCode(self):
|
||||||
if sys.platform.find('win') >= 0:
|
if sys.platform.startswith('win'):
|
||||||
self._showQRCodeImg()
|
self._showQRCodeImg()
|
||||||
else:
|
else:
|
||||||
self._str2qr('https://login.weixin.qq.com/l/' + self.uuid)
|
self._str2qr('https://login.weixin.qq.com/l/' + self.uuid)
|
||||||
|
|
||||||
def _showQRCodeImg(self):
|
def _showQRCodeImg(self):
|
||||||
QRCODE_PATH = os.path.join(os.getcwd(),'qrcode.jpg')
|
|
||||||
url = 'https://login.weixin.qq.com/qrcode/' + self.uuid
|
url = 'https://login.weixin.qq.com/qrcode/' + self.uuid
|
||||||
params = {
|
params = {
|
||||||
't' : 'webwx',
|
't' : 'webwx',
|
||||||
'_' : int(time.time())
|
'_' : int(time.time())
|
||||||
}
|
}
|
||||||
|
|
||||||
data = self._post(url,params,False)
|
data = self._post(url, params, False)
|
||||||
with open(QRCODE_PATH, 'wb') as f:
|
QRCODE_PATH = self._saveFile('qrcode.jpg', data, '_showQRCodeImg')
|
||||||
f.write(data)
|
|
||||||
|
|
||||||
os.startfile(QRCODE_PATH)
|
os.startfile(QRCODE_PATH)
|
||||||
|
|
||||||
def waitForLogin(self, tip = 1):
|
def waitForLogin(self, tip = 1):
|
||||||
@@ -268,6 +285,7 @@ class WebWeixin(object):
|
|||||||
dic = self._post(url, params)
|
dic = self._post(url, params)
|
||||||
if self.DEBUG:
|
if self.DEBUG:
|
||||||
print json.dumps(dic, indent=4)
|
print json.dumps(dic, indent=4)
|
||||||
|
logging.debug(json.dumps(dic, indent=4))
|
||||||
|
|
||||||
if dic['BaseResponse']['Ret'] == 0:
|
if dic['BaseResponse']['Ret'] == 0:
|
||||||
self.SyncKey = dic['SyncKey']
|
self.SyncKey = dic['SyncKey']
|
||||||
@@ -294,41 +312,47 @@ class WebWeixin(object):
|
|||||||
dic = r.json()
|
dic = r.json()
|
||||||
return dic['BaseResponse']['Ret'] == 0
|
return dic['BaseResponse']['Ret'] == 0
|
||||||
|
|
||||||
|
def _saveFile(self, filename, data, api=None):
|
||||||
|
fn = filename
|
||||||
|
if self.saveSubFolders[api]:
|
||||||
|
dirName = os.path.join(self.saveFolder, self.saveSubFolders[api])
|
||||||
|
if not os.path.exists(dirName):
|
||||||
|
os.makedirs(dirName)
|
||||||
|
fn = os.path.join(dirName, filename)
|
||||||
|
logging.debug('Saved file: %s' % fn)
|
||||||
|
with open(fn, 'wb') as f: f.write(data); f.close()
|
||||||
|
return fn
|
||||||
|
|
||||||
def webwxgeticon(self, id):
|
def webwxgeticon(self, id):
|
||||||
url = self.base_uri + '/webwxgeticon?username=%s&skey=%s' % (id, self.skey)
|
url = self.base_uri + '/webwxgeticon?username=%s&skey=%s' % (id, self.skey)
|
||||||
data = self._get(url)
|
data = self._get(url)
|
||||||
fn = 'img_'+id+'.jpg'
|
fn = 'img_'+id+'.jpg'
|
||||||
with open(fn, 'wb') as f: f.write(data)
|
return self._saveFile(fn, data, 'webwxgeticon')
|
||||||
return fn
|
|
||||||
|
|
||||||
def webwxgetheadimg(self, id):
|
def webwxgetheadimg(self, id):
|
||||||
url = self.base_uri + '/webwxgetheadimg?username=%s&skey=%s' % (id, self.skey)
|
url = self.base_uri + '/webwxgetheadimg?username=%s&skey=%s' % (id, self.skey)
|
||||||
data = self._get(url)
|
data = self._get(url)
|
||||||
fn = 'img_'+id+'.jpg'
|
fn = 'img_'+id+'.jpg'
|
||||||
with open(fn, 'wb') as f: f.write(data)
|
return self._saveFile(fn, data, 'webwxgetheadimg')
|
||||||
return fn
|
|
||||||
|
|
||||||
def webwxgetmsgimg(self, msgid):
|
def webwxgetmsgimg(self, msgid):
|
||||||
url = self.base_uri + '/webwxgetmsgimg?MsgID=%s&skey=%s' % (msgid, self.skey)
|
url = self.base_uri + '/webwxgetmsgimg?MsgID=%s&skey=%s' % (msgid, self.skey)
|
||||||
data = self._get(url)
|
data = self._get(url)
|
||||||
fn = 'img_'+msgid+'.jpg'
|
fn = 'img_'+msgid+'.jpg'
|
||||||
with open(fn, 'wb') as f: f.write(data)
|
return self._saveFile(fn, data, 'webwxgetmsgimg')
|
||||||
return fn
|
|
||||||
|
|
||||||
# Not work now for weixin haven't support this API
|
# Not work now for weixin haven't support this API
|
||||||
def webwxgetvideo(self, msgid):
|
def webwxgetvideo(self, msgid):
|
||||||
url = self.base_uri + '/webwxgetvideo?msgid=%s&skey=%s' % (msgid, self.skey)
|
url = self.base_uri + '/webwxgetvideo?msgid=%s&skey=%s' % (msgid, self.skey)
|
||||||
data = self._get(url)
|
data = self._get(url, api='webwxgetvideo')
|
||||||
fn = 'video_'+msgid+'.mp4'
|
fn = 'video_'+msgid+'.mp4'
|
||||||
with open(fn, 'wb') as f: f.write(data)
|
return self._saveFile(fn, data, 'webwxgetvideo')
|
||||||
return fn
|
|
||||||
|
|
||||||
def webwxgetvoice(self, msgid):
|
def webwxgetvoice(self, msgid):
|
||||||
url = self.base_uri + '/webwxgetvoice?msgid=%s&skey=%s' % (msgid, self.skey)
|
url = self.base_uri + '/webwxgetvoice?msgid=%s&skey=%s' % (msgid, self.skey)
|
||||||
data = self._get(url)
|
data = self._get(url)
|
||||||
fn = 'voice_'+msgid+'.mp3'
|
fn = 'voice_'+msgid+'.mp3'
|
||||||
with open(fn, 'wb') as f: f.write(data)
|
return self._saveFile(fn, data, 'webwxgetvoice')
|
||||||
return fn
|
|
||||||
|
|
||||||
def getUserRemarkName(self, id):
|
def getUserRemarkName(self, id):
|
||||||
name = '未知群' if id[:2] == '@@' else '陌生人'
|
name = '未知群' if id[:2] == '@@' else '陌生人'
|
||||||
@@ -344,14 +368,69 @@ class WebWeixin(object):
|
|||||||
return member['UserName']
|
return member['UserName']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _showMsg(self, message):
|
||||||
|
|
||||||
|
srcName = None
|
||||||
|
dstName = None
|
||||||
|
groupName = None
|
||||||
|
content = None
|
||||||
|
|
||||||
|
msg = message
|
||||||
|
logging.debug(msg)
|
||||||
|
|
||||||
|
if msg['raw_msg']:
|
||||||
|
srcName = self.getUserRemarkName(msg['raw_msg']['FromUserName'])
|
||||||
|
dstName = self.getUserRemarkName(msg['raw_msg']['ToUserName'])
|
||||||
|
content = msg['raw_msg']['Content'].replace('<','<').replace('>','>')
|
||||||
|
message_id = msg['raw_msg']['MsgId']
|
||||||
|
|
||||||
|
if content.find('http://weixin.qq.com/cgi-bin/redirectforward?args=') != -1:
|
||||||
|
# 地理位置消息
|
||||||
|
data = self._get(content).decode('gbk').encode('utf-8')
|
||||||
|
pos = self._searchContent('title', data, 'xml')
|
||||||
|
tree = html.fromstring(self._get(content))
|
||||||
|
url = tree.xpath('//html/body/div/img')[0].attrib['src']
|
||||||
|
|
||||||
|
for item in urlparse(url).query.split('&'):
|
||||||
|
if item.split('=')[0] == 'center': loc = item.split('=')[-1:]
|
||||||
|
|
||||||
|
content = '%s 发送了一个 位置消息 - 我在 [%s](%s) @ %s]' % (srcName, pos, url, loc)
|
||||||
|
|
||||||
|
if msg['raw_msg']['ToUserName'] == 'filehelper':
|
||||||
|
# 文件传输助手
|
||||||
|
dstName = '文件传输助手'
|
||||||
|
|
||||||
|
if msg['raw_msg']['FromUserName'][:2] == '@@':
|
||||||
|
# 接收到来自群的消息
|
||||||
|
[people, content] = content.split(':<br/>')
|
||||||
|
groupName = srcName
|
||||||
|
srcName = self.getUserRemarkName(people)
|
||||||
|
dstName = 'GROUP'
|
||||||
|
elif msg['raw_msg']['ToUserName'][:2] == '@@':
|
||||||
|
# 自己发给群的消息
|
||||||
|
groupName = dstName
|
||||||
|
dstName = 'GROUP'
|
||||||
|
|
||||||
|
# 指定了消息内容
|
||||||
|
if 'message' in msg.keys(): content = msg['message']
|
||||||
|
|
||||||
|
if groupName != None:
|
||||||
|
print '%s |%s| %s -> %s: %s' % (message_id, groupName.strip(), srcName.strip(), dstName.strip(), content.replace('<br/>','\n'))
|
||||||
|
logging.info('%s |%s| %s -> %s: %s' % (message_id, groupName.strip(), srcName.strip(), dstName.strip(), content.replace('<br/>','\n')))
|
||||||
|
else:
|
||||||
|
print '%s %s -> %s: %s' % (message_id, srcName.strip(), dstName.strip(), content.replace('<br/>','\n'))
|
||||||
|
logging.info('%s %s -> %s: %s' % (message_id, srcName.strip(), dstName.strip(), content.replace('<br/>','\n')))
|
||||||
|
|
||||||
def handleMsg(self, r):
|
def handleMsg(self, r):
|
||||||
for msg in r['AddMsgList']:
|
for msg in r['AddMsgList']:
|
||||||
print '[*] 你有新的消息,请注意查收'
|
print '[*] 你有新的消息,请注意查收'
|
||||||
|
logging.debug('[*] 你有新的消息,请注意查收')
|
||||||
|
|
||||||
if self.DEBUG:
|
if self.DEBUG:
|
||||||
fn = 'msg' + str(int(random.random() * 1000)) + '.json'
|
fn = 'msg' + str(int(random.random() * 1000)) + '.json'
|
||||||
with open(fn, 'w') as f: f.write(json.dumps(msg))
|
with open(fn, 'w') as f: f.write(json.dumps(msg))
|
||||||
print '[*] 该消息已储存到文件: ' + fn
|
print '[*] 该消息已储存到文件: ' + fn
|
||||||
|
logging.debug('[*] 该消息已储存到文件: %s' % (fn))
|
||||||
|
|
||||||
msgType = msg['MsgType']
|
msgType = msg['MsgType']
|
||||||
name = self.getUserRemarkName(msg['FromUserName'])
|
name = self.getUserRemarkName(msg['FromUserName'])
|
||||||
@@ -359,77 +438,82 @@ class WebWeixin(object):
|
|||||||
msgid = msg['MsgId']
|
msgid = msg['MsgId']
|
||||||
if msgType == 51:
|
if msgType == 51:
|
||||||
print '[*] 成功截获微信初始化消息'
|
print '[*] 成功截获微信初始化消息'
|
||||||
|
logging.debug('[*] 成功截获微信初始化消息')
|
||||||
elif msgType == 1:
|
elif msgType == 1:
|
||||||
if content.find('http://weixin.qq.com/cgi-bin/redirectforward?args=') != -1:
|
raw_msg = { 'raw_msg': msg }
|
||||||
# 地理位置消息
|
self._showMsg(raw_msg)
|
||||||
data = self._get(content).decode('gbk').encode('utf-8')
|
|
||||||
pos = self._searchContent('title', data, 'xml')
|
|
||||||
print '%s 给你发送了一个位置消息 [我在%s]' % (name, pos)
|
|
||||||
elif msg['ToUserName'] == 'filehelper':
|
|
||||||
print '%s -> 文件传输助手: %s' % (name, content.replace('<br/>','\n'))
|
|
||||||
elif msg['FromUserName'] == self.User['UserName']:
|
|
||||||
pass
|
|
||||||
elif msg['FromUserName'][:2] == '@@':
|
|
||||||
[people, content] = content.split(':<br/>')
|
|
||||||
group = self.getUserRemarkName(msg['FromUserName'])
|
|
||||||
name = self.getUserRemarkName(people)
|
|
||||||
print '|%s| %s: %s' % (group, name, content.replace('<br/>','\n'))
|
|
||||||
else:
|
|
||||||
print name+': '+content
|
|
||||||
if self.autoReplyMode:
|
if self.autoReplyMode:
|
||||||
ans = self._xiaodoubi(content)+'\n[微信机器人自动回复]'
|
ans = self._xiaodoubi(content)+'\n[微信机器人自动回复]'
|
||||||
if self.webwxsendmsg(ans, msg['FromUserName']):
|
if self.webwxsendmsg(ans, msg['FromUserName']):
|
||||||
print '自动回复: '+ans
|
print '自动回复: '+ans
|
||||||
|
logging.info('自动回复: '+ans)
|
||||||
else:
|
else:
|
||||||
print '自动回复失败'
|
print '自动回复失败'
|
||||||
|
logging.info('自动回复失败')
|
||||||
elif msgType == 3:
|
elif msgType == 3:
|
||||||
image = self.webwxgetmsgimg(msgid)
|
image = self.webwxgetmsgimg(msgid)
|
||||||
print '%s 给你发送了一张图片: %s' % (name, image)
|
raw_msg = { 'raw_msg': msg, 'message': '%s 发送了一张图片: %s' % (name, image) }
|
||||||
|
self._showMsg(raw_msg)
|
||||||
self._safe_open(image)
|
self._safe_open(image)
|
||||||
elif msgType == 34:
|
elif msgType == 34:
|
||||||
voice = self.webwxgetvoice(msgid)
|
voice = self.webwxgetvoice(msgid)
|
||||||
print '%s 给你发了一段语音: %s' % (name, voice)
|
raw_msg = { 'raw_msg': msg, 'message': '%s 发了一段语音: %s' % (name, voice) }
|
||||||
|
self._showMsg(raw_msg)
|
||||||
self._safe_open(voice)
|
self._safe_open(voice)
|
||||||
elif msgType == 42:
|
elif msgType == 42:
|
||||||
info = msg['RecommendInfo']
|
info = msg['RecommendInfo']
|
||||||
print '%s 给你发送了一张名片:' % name
|
print '%s 发送了一张名片:' % name
|
||||||
print '========================='
|
print '========================='
|
||||||
print '= 昵称: %s' % info['NickName']
|
print '= 昵称: %s' % info['NickName']
|
||||||
print '= 微信号: %s' % info['Alias']
|
print '= 微信号: %s' % info['Alias']
|
||||||
print '= 地区: %s %s' % (info['Province'], info['City'])
|
print '= 地区: %s %s' % (info['Province'], info['City'])
|
||||||
print '= 性别: %s' % ['未知', '男', '女'][info['Sex']]
|
print '= 性别: %s' % ['未知', '男', '女'][info['Sex']]
|
||||||
print '========================='
|
print '========================='
|
||||||
|
logging.info('%s 发送了一张名片: %s' % (name.strip(), json.dumps(info)))
|
||||||
elif msgType == 47:
|
elif msgType == 47:
|
||||||
url = self._searchContent('cdnurl', content)
|
url = self._searchContent('cdnurl', content)
|
||||||
print '%s 给你发了一个动画表情,点击下面链接查看:\n%s' % (name, url)
|
raw_msg = { 'raw_msg': msg, 'message': '%s 发了一个动画表情,点击下面链接查看: %s' % (name, url) }
|
||||||
|
self._showMsg(raw_msg)
|
||||||
self._safe_open(url)
|
self._safe_open(url)
|
||||||
elif msgType == 49:
|
elif msgType == 49:
|
||||||
appMsgType = defaultdict(lambda : "")
|
appMsgType = defaultdict(lambda : "")
|
||||||
appMsgType.update({5:'链接', 3:'音乐', 7:'微博'})
|
appMsgType.update({5:'链接', 3:'音乐', 7:'微博'})
|
||||||
print '%s 给你分享了一个%s:' % (name, appMsgType[msg['AppMsgType']])
|
print '%s 分享了一个%s:' % (name, appMsgType[msg['AppMsgType']])
|
||||||
print '========================='
|
print '========================='
|
||||||
print '= 标题: %s' % msg['FileName']
|
print '= 标题: %s' % msg['FileName']
|
||||||
print '= 描述: %s' % self._searchContent('des', content, 'xml')
|
print '= 描述: %s' % self._searchContent('des', content, 'xml')
|
||||||
print '= 链接: %s' % msg['Url']
|
print '= 链接: %s' % msg['Url']
|
||||||
print '= 来自: %s' % self._searchContent('appname', content, 'xml')
|
print '= 来自: %s' % self._searchContent('appname', content, 'xml')
|
||||||
print '========================='
|
print '========================='
|
||||||
|
string = "%s 分享了一个%s:" % (name, appMsgType[msg['AppMsgType']])
|
||||||
elif msgType == 62:
|
elif msgType == 62:
|
||||||
print name+' 给你发了一个小视频,请在手机上查看'
|
video = self.webwxgetvideo(msgid)
|
||||||
|
raw_msg = { 'raw_msg': msg, 'message': '%s 发了一段语音: %s' % (name, video) }
|
||||||
|
self._showMsg(raw_msg)
|
||||||
|
self._safe_open(video)
|
||||||
elif msgType == 10002:
|
elif msgType == 10002:
|
||||||
print name+' 撤回消息'
|
print name+' 撤回消息'
|
||||||
|
logging.info(name+' 撤回消息')
|
||||||
else:
|
else:
|
||||||
print '[*] 该消息类型为: %d,可能是表情,图片或链接' % msg['MsgType']
|
print '[*] 该消息类型为: %d,可能是表情,图片或链接' % msg['MsgType']
|
||||||
print msg
|
logging.debug('[*] 该消息类型为: %d,可能是表情,图片或链接: %s' % (msg['MsgType'], json.dumps(msg)))
|
||||||
|
|
||||||
def listenMsgMode(self):
|
def listenMsgMode(self):
|
||||||
print '[*] 进入消息监听模式 ... 成功'
|
print '[*] 进入消息监听模式 ... 成功'
|
||||||
|
logging.debug('[*] 进入消息监听模式 ... 成功')
|
||||||
self._run('[*] 进行同步线路测试 ... ', self.testsynccheck)
|
self._run('[*] 进行同步线路测试 ... ', self.testsynccheck)
|
||||||
playWeChat = 0
|
playWeChat = 0
|
||||||
while True:
|
while True:
|
||||||
[retcode, selector] = self.synccheck()
|
[retcode, selector] = self.synccheck()
|
||||||
if self.DEBUG: print 'retcode: %s, selector: %s' % (retcode, selector)
|
if self.DEBUG: print 'retcode: %s, selector: %s' % (retcode, selector)
|
||||||
|
logging.debug('retcode: %s, selector: %s' % (retcode, selector))
|
||||||
if retcode == '1100':
|
if retcode == '1100':
|
||||||
print '[*] 你在手机上登出了微信,债见'
|
print '[*] 你在手机上登出了微信,债见'
|
||||||
|
logging.debug('[*] 你在手机上登出了微信,债见')
|
||||||
|
break
|
||||||
|
if retcode == '1101':
|
||||||
|
print '[*] 你在其他地方登录了 WEB 版微信,债见'
|
||||||
|
logging.debug('[*] 你在其他地方登录了 WEB 版微信,债见')
|
||||||
break
|
break
|
||||||
elif retcode == '0':
|
elif retcode == '0':
|
||||||
if selector == '2':
|
if selector == '2':
|
||||||
@@ -438,6 +522,7 @@ class WebWeixin(object):
|
|||||||
elif selector == '7':
|
elif selector == '7':
|
||||||
playWeChat += 1
|
playWeChat += 1
|
||||||
print '[*] 你在手机上玩微信被我发现了 %d 次' % playWeChat
|
print '[*] 你在手机上玩微信被我发现了 %d 次' % playWeChat
|
||||||
|
logging.debug('[*] 你在手机上玩微信被我发现了 %d 次' % playWeChat)
|
||||||
r = self.webwxsync()
|
r = self.webwxsync()
|
||||||
elif selector == '0':
|
elif selector == '0':
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
@@ -458,10 +543,13 @@ class WebWeixin(object):
|
|||||||
else:
|
else:
|
||||||
if self.webwxsendmsg(word, id):
|
if self.webwxsendmsg(word, id):
|
||||||
print '[*] 消息发送成功'
|
print '[*] 消息发送成功'
|
||||||
|
logging.debug('[*] 消息发送成功')
|
||||||
else:
|
else:
|
||||||
print '[*] 消息发送失败'
|
print '[*] 消息发送失败'
|
||||||
|
logging.debug('[*] 消息发送失败')
|
||||||
else:
|
else:
|
||||||
print '[*] 此用户不存在'
|
print '[*] 此用户不存在'
|
||||||
|
logging.debug('[*] 此用户不存在')
|
||||||
|
|
||||||
def sendMsgToAll(self, word):
|
def sendMsgToAll(self, word):
|
||||||
for contact in self.ContactList:
|
for contact in self.ContactList:
|
||||||
@@ -476,23 +564,26 @@ class WebWeixin(object):
|
|||||||
|
|
||||||
@catchKeyboardInterrupt
|
@catchKeyboardInterrupt
|
||||||
def start(self):
|
def start(self):
|
||||||
print '[*] 微信网页版 ... 开动'
|
self._echo('[*] 微信网页版 ... 开动'); print; logging.debug('[*] 微信网页版 ... 开动')
|
||||||
self._run('[*] 正在获取 uuid ... ', self.getUUID)
|
self._run('[*] 正在获取 uuid ... ', self.getUUID)
|
||||||
print '[*] 正在获取二维码 ... 成功'; self.genQRCode()
|
self._echo('[*] 正在获取二维码 ... 成功'); print; logging.debug('[*] 微信网页版 ... 开动'); self.genQRCode()
|
||||||
self._run('[*] 请使用微信扫描二维码以登录 ... ', self.waitForLogin)
|
self._run('[*] 请使用微信扫描二维码以登录 ... ', self.waitForLogin)
|
||||||
self._run('[*] 请在手机上点击确认以登录 ... ', self.waitForLogin, 0)
|
self._run('[*] 请在手机上点击确认以登录 ... ', self.waitForLogin, 0)
|
||||||
self._run('[*] 正在登录 ... ', self.login)
|
self._run('[*] 正在登录 ... ', self.login)
|
||||||
self._run('[*] 微信初始化 ... ', self.webwxinit)
|
self._run('[*] 微信初始化 ... ', self.webwxinit)
|
||||||
self._run('[*] 开启状态通知 ... ', self.webwxstatusnotify)
|
self._run('[*] 开启状态通知 ... ', self.webwxstatusnotify)
|
||||||
self._run('[*] 获取联系人 ... ', self.webwxgetcontact)
|
self._run('[*] 获取联系人 ... ', self.webwxgetcontact)
|
||||||
print '[*] 共有 %d 位联系人' % len(self.ContactList)
|
self._echo('[*] 共有 %d 位联系人' % len(self.ContactList)); print; logging.debug('[*] 微信网页版 ... 开动')
|
||||||
if self.DEBUG: print self
|
if self.DEBUG: print self
|
||||||
|
logging.debug(self)
|
||||||
|
|
||||||
if raw_input('[*] 是否开启自动回复模式(y/n): ') == 'y':
|
if self.interactive and raw_input('[*] 是否开启自动回复模式(y/n): ') == 'y':
|
||||||
self.autoReplyMode = True
|
self.autoReplyMode = True
|
||||||
print '[*] 自动回复模式 ... 开启'
|
print '[*] 自动回复模式 ... 开启'
|
||||||
|
logging.debug('[*] 自动回复模式 ... 开启')
|
||||||
else:
|
else:
|
||||||
print '[*] 自动回复模式 ... 关闭'
|
print '[*] 自动回复模式 ... 关闭'
|
||||||
|
logging.debug('[*] 自动回复模式 ... 关闭')
|
||||||
|
|
||||||
listenProcess = multiprocessing.Process(target=self.listenMsgMode)
|
listenProcess = multiprocessing.Process(target=self.listenMsgMode)
|
||||||
listenProcess.start()
|
listenProcess.start()
|
||||||
@@ -502,6 +593,7 @@ class WebWeixin(object):
|
|||||||
if text == 'quit':
|
if text == 'quit':
|
||||||
listenProcess.terminate()
|
listenProcess.terminate()
|
||||||
print('[*] 退出微信')
|
print('[*] 退出微信')
|
||||||
|
logging.debug('[*] 退出微信')
|
||||||
exit()
|
exit()
|
||||||
elif text[:2] == '->':
|
elif text[:2] == '->':
|
||||||
[name, word] = text[2:].split(':')
|
[name, word] = text[2:].split(':')
|
||||||
@@ -512,10 +604,13 @@ class WebWeixin(object):
|
|||||||
self.sendMsg(name, file, True)
|
self.sendMsg(name, file, True)
|
||||||
elif text[:3] == 'f->':
|
elif text[:3] == 'f->':
|
||||||
print '发送文件'
|
print '发送文件'
|
||||||
|
logging.debug('发送文件')
|
||||||
elif text[:3] == 'i->':
|
elif text[:3] == 'i->':
|
||||||
print '发送图片'
|
print '发送图片'
|
||||||
|
logging.debug('发送图片')
|
||||||
|
|
||||||
def _safe_open(self, path):
|
def _safe_open(self, path):
|
||||||
|
if self.autoOpen:
|
||||||
if platform.system() == "Linux":
|
if platform.system() == "Linux":
|
||||||
os.system("xdg-open %s &" % path)
|
os.system("xdg-open %s &" % path)
|
||||||
else:
|
else:
|
||||||
@@ -523,8 +618,8 @@ class WebWeixin(object):
|
|||||||
|
|
||||||
def _run(self, str, func, *args):
|
def _run(self, str, func, *args):
|
||||||
self._echo(str)
|
self._echo(str)
|
||||||
if func(*args): print '成功'
|
if func(*args): print '成功'; logging.debug('%s... 开启' % (str))
|
||||||
else: print('失败\n[*] 退出程序');exit()
|
else: print('失败\n[*] 退出程序'); logging.debug('%s... 失败' % (str)); logging.debug('[*] 退出程序'); exit()
|
||||||
|
|
||||||
def _echo(self, str):
|
def _echo(self, str):
|
||||||
sys.stdout.write(str)
|
sys.stdout.write(str)
|
||||||
@@ -552,10 +647,14 @@ class WebWeixin(object):
|
|||||||
result = data.decode('utf-8')
|
result = data.decode('utf-8')
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get(self, url):
|
def _get(self, url, api=None):
|
||||||
request = urllib2.Request(url = url)
|
request = urllib2.Request(url = url)
|
||||||
|
request.add_header('Referer', 'https://wx.qq.com/')
|
||||||
|
if api == 'webwxgetvoice': request.add_header('Range', 'bytes=0-')
|
||||||
|
if api == 'webwxgetvideo': request.add_header('Range', 'bytes=0-')
|
||||||
response = urllib2.urlopen(request)
|
response = urllib2.urlopen(request)
|
||||||
data = response.read()
|
data = response.read()
|
||||||
|
logging.debug(url)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _post(self, url, params, jsonfmt = True):
|
def _post(self, url, params, jsonfmt = True):
|
||||||
@@ -590,7 +689,7 @@ class WebWeixin(object):
|
|||||||
pm = re.search(key+'\s?=\s?"([^"<]+)"', content)
|
pm = re.search(key+'\s?=\s?"([^"<]+)"', content)
|
||||||
if pm: return pm.group(1)
|
if pm: return pm.group(1)
|
||||||
elif fmat == 'xml':
|
elif fmat == 'xml':
|
||||||
pm=re.search('<{0}>([^<]+)</{0}>'.format(key),content)
|
pm = re.search('<{0}>([^<]+)</{0}>'.format(key),content)
|
||||||
if pm: return pm.group(1)
|
if pm: return pm.group(1)
|
||||||
return '未知'
|
return '未知'
|
||||||
|
|
||||||
@@ -615,5 +714,10 @@ if sys.stdout.encoding == 'cp936':
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
import coloredlogs
|
||||||
|
coloredlogs.install(level='DEBUG')
|
||||||
|
|
||||||
webwx = WebWeixin()
|
webwx = WebWeixin()
|
||||||
webwx.start()
|
webwx.start()
|
||||||
|
|||||||
Reference in New Issue
Block a user