diff --git a/.gitignore b/.gitignore index c0ca475b..27bda904 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ test.py itchat.pkl QR.jpg .DS_Store +venv/* +.idea/* +.vscode/* \ No newline at end of file diff --git a/README.md b/README.md index 75767d9b..bb3e5f83 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,16 @@ itchat是一个开源的微信个人号接口,使用python调用微信从未 如今微信已经成为了个人社交的很大一部分,希望这个项目能够帮助你扩展你的个人的微信号、方便自己的生活。 + + +## 安装 UOS Patch + +暂时请通过github安装 + +``` +pip3 install git+https://github.com/luvletter2333/ItChat.git +``` + ## 安装 可以通过本命令安装itchat: diff --git a/itchat/components/login.py b/itchat/components/login.py index c1fb0391..5c725b76 100644 --- a/itchat/components/login.py +++ b/itchat/components/login.py @@ -19,6 +19,7 @@ logger = logging.getLogger('itchat') + def load_login(core): core.login = login core.get_QRuuid = get_QRuuid @@ -30,6 +31,7 @@ def load_login(core): core.get_msg = get_msg core.logout = logout + def login(self, enableCmdQR=False, picDir=None, qrCallback=None, loginCallback=None, exitCallback=None): if self.alive or self.isLogging: @@ -97,7 +99,9 @@ def get_QRuuid(self): url = '%s/jslogin' % config.BASE_URL params = { 'appid' : 'wx782c26e4c19acffb', - 'fun' : 'new', } + 'fun' : 'new', + 'redirect_uri' : 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?mod=desktop', + 'lang' : 'zh_CN' } headers = { 'User-Agent' : config.USER_AGENT } r = self.s.get(url, params=params, headers=headers) regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)";' @@ -151,7 +155,11 @@ def process_login_info(core, loginContent): ''' regx = r'window.redirect_uri="(\S+)";' core.loginInfo['url'] = re.search(regx, loginContent).group(1) - headers = { 'User-Agent' : config.USER_AGENT } + headers = { 'User-Agent' : config.USER_AGENT, + 'client-version' : config.UOS_PATCH_CLIENT_VERSION, + 'extspam' : config.UOS_PATCH_EXTSPAM, + 'referer' : 'https://wx.qq.com/?&lang=zh_CN&target=t' + } r = core.s.get(core.loginInfo['url'], headers=headers, allow_redirects=False) core.loginInfo['url'] = core.loginInfo['url'][:core.loginInfo['url'].rfind('/')] for indexUrl, detailedUrl in ( @@ -170,15 +178,24 @@ def process_login_info(core, loginContent): core.loginInfo['deviceid'] = 'e' + repr(random.random())[2:17] core.loginInfo['logintime'] = int(time.time() * 1e3) core.loginInfo['BaseRequest'] = {} - for node in xml.dom.minidom.parseString(r.text).documentElement.childNodes: - if node.nodeName == 'skey': - core.loginInfo['skey'] = core.loginInfo['BaseRequest']['Skey'] = node.childNodes[0].data - elif node.nodeName == 'wxsid': - core.loginInfo['wxsid'] = core.loginInfo['BaseRequest']['Sid'] = node.childNodes[0].data - elif node.nodeName == 'wxuin': - core.loginInfo['wxuin'] = core.loginInfo['BaseRequest']['Uin'] = node.childNodes[0].data - elif node.nodeName == 'pass_ticket': - core.loginInfo['pass_ticket'] = core.loginInfo['BaseRequest']['DeviceID'] = node.childNodes[0].data + cookies = core.s.cookies.get_dict() + core.loginInfo['skey'] = core.loginInfo['BaseRequest']['Skey'] = "" + core.loginInfo['wxsid'] = core.loginInfo['BaseRequest']['Sid'] = cookies["wxsid"] + core.loginInfo['wxuin'] = core.loginInfo['BaseRequest']['Uin'] = cookies["wxuin"] + core.loginInfo['pass_ticket'] = core.loginInfo['BaseRequest']['DeviceID'] = core.loginInfo['deviceid'] + # A question : why pass_ticket == DeviceID ? + # deviceID is only a randomly generated number + + # UOS PATCH By luvletter2333, Sun Feb 28 10:00 PM + # for node in xml.dom.minidom.parseString(r.text).documentElement.childNodes: + # if node.nodeName == 'skey': + # core.loginInfo['skey'] = core.loginInfo['BaseRequest']['Skey'] = node.childNodes[0].data + # elif node.nodeName == 'wxsid': + # core.loginInfo['wxsid'] = core.loginInfo['BaseRequest']['Sid'] = node.childNodes[0].data + # elif node.nodeName == 'wxuin': + # core.loginInfo['wxuin'] = core.loginInfo['BaseRequest']['Uin'] = node.childNodes[0].data + # elif node.nodeName == 'pass_ticket': + # core.loginInfo['pass_ticket'] = core.loginInfo['BaseRequest']['DeviceID'] = node.childNodes[0].data if not all([key in core.loginInfo for key in ('skey', 'wxsid', 'wxuin', 'pass_ticket')]): logger.error('Your wechat account may be LIMITED to log in WEB wechat, error info:\n%s' % r.text) core.isLogging = False diff --git a/itchat/config.py b/itchat/config.py index 36ca488b..1a78ac63 100644 --- a/itchat/config.py +++ b/itchat/config.py @@ -1,6 +1,6 @@ import os, platform -VERSION = '1.3.10' +VERSION = '1.4.0' BASE_URL = 'https://login.weixin.qq.com' OS = platform.system() # Windows, Linux, Darwin DIR = os.getcwd() @@ -8,3 +8,6 @@ TIMEOUT = (10, 60) USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36' + +UOS_PATCH_CLIENT_VERSION = '2.0.0' +UOS_PATCH_EXTSPAM = 'Gp8ICJkIEpkICggwMDAwMDAwMRAGGoAI1GiJSIpeO1RZTq9QBKsRbPJdi84ropi16EYI10WB6g74sGmRwSNXjPQnYUKYotKkvLGpshucCaeWZMOylnc6o2AgDX9grhQQx7fm2DJRTyuNhUlwmEoWhjoG3F0ySAWUsEbH3bJMsEBwoB//0qmFJob74ffdaslqL+IrSy7LJ76/G5TkvNC+J0VQkpH1u3iJJs0uUYyLDzdBIQ6Ogd8LDQ3VKnJLm4g/uDLe+G7zzzkOPzCjXL+70naaQ9medzqmh+/SmaQ6uFWLDQLcRln++wBwoEibNpG4uOJvqXy+ql50DjlNchSuqLmeadFoo9/mDT0q3G7o/80P15ostktjb7h9bfNc+nZVSnUEJXbCjTeqS5UYuxn+HTS5nZsPVxJA2O5GdKCYK4x8lTTKShRstqPfbQpplfllx2fwXcSljuYi3YipPyS3GCAqf5A7aYYwJ7AvGqUiR2SsVQ9Nbp8MGHET1GxhifC692APj6SJxZD3i1drSYZPMMsS9rKAJTGz2FEupohtpf2tgXm6c16nDk/cw+C7K7me5j5PLHv55DFCS84b06AytZPdkFZLj7FHOkcFGJXitHkX5cgww7vuf6F3p0yM/W73SoXTx6GX4G6Hg2rYx3O/9VU2Uq8lvURB4qIbD9XQpzmyiFMaytMnqxcZJcoXCtfkTJ6pI7a92JpRUvdSitg967VUDUAQnCXCM/m0snRkR9LtoXAO1FUGpwlp1EfIdCZFPKNnXMeqev0j9W9ZrkEs9ZWcUEexSj5z+dKYQBhIICviYUQHVqBTZSNy22PlUIeDeIs11j7q4t8rD8LPvzAKWVqXE+5lS1JPZkjg4y5hfX1Dod3t96clFfwsvDP6xBSe1NBcoKbkyGxYK0UvPGtKQEE0Se2zAymYDv41klYE9s+rxp8e94/H8XhrL9oGm8KWb2RmYnAE7ry9gd6e8ZuBRIsISlJAE/e8y8xFmP031S6Lnaet6YXPsFpuFsdQs535IjcFd75hh6DNMBYhSfjv456cvhsb99+fRw/KVZLC3yzNSCbLSyo9d9BI45Plma6V8akURQA/qsaAzU0VyTIqZJkPDTzhuCl92vD2AD/QOhx6iwRSVPAxcRFZcWjgc2wCKh+uCYkTVbNQpB9B90YlNmI3fWTuUOUjwOzQRxJZj11NsimjOJ50qQwTTFj6qQvQ1a/I+MkTx5UO+yNHl718JWcR3AXGmv/aa9rD1eNP8ioTGlOZwPgmr2sor2iBpKTOrB83QgZXP+xRYkb4zVC+LoAXEoIa1+zArywlgREer7DLePukkU6wHTkuSaF+ge5Of1bXuU4i938WJHj0t3D8uQxkJvoFi/EYN/7u2P1zGRLV4dHVUsZMGCCtnO6BBigFMAA=' \ No newline at end of file diff --git a/itchat/utils.py b/itchat/utils.py index e217368c..dd73b4d4 100644 --- a/itchat/utils.py +++ b/itchat/utils.py @@ -18,6 +18,10 @@ emojiRegex = re.compile(r'') htmlParser = HTMLParser() +if not hasattr(htmlParser, 'unescape'): + import html + htmlParser.unescape = html.unescape + # FIX Python 3.9 HTMLParser.unescape is removed. See https://docs.python.org/3.9/whatsnew/3.9.html try: b = u'\u2588' sys.stdout.write(b + '\r') @@ -71,7 +75,7 @@ def _emoji_formatter(m): def msg_formatter(d, k): emoji_formatter(d, k) d[k] = d[k].replace('
', '\n') - d[k] = htmlParser.unescape(d[k]) + d[k] = htmlParser.unescape(d[k]) def check_file(fileDir): try: