diff --git a/.gitignore b/.gitignore index 7db61e6..894a44c 100644 --- a/.gitignore +++ b/.gitignore @@ -101,4 +101,4 @@ venv.bak/ /site # mypy -.mypy_cache/ \ No newline at end of file +.mypy_cache/ diff --git a/CITATION.cff b/CITATION.cff index 7cb012d..73005db 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -5,4 +5,4 @@ authors: title: "DecryptLogin: APIs for loginning some websites by using requests" date-released: 2019-02-25 url: "https://github.com/CharlesPikachu/DecryptLogin" -license: Apache-2.0 +license: Apache-2.0 \ No newline at end of file diff --git a/DecryptLogin/__init__.py b/DecryptLogin/__init__.py index e1389a8..372777a 100644 --- a/DecryptLogin/__init__.py +++ b/DecryptLogin/__init__.py @@ -1,5 +1,5 @@ '''版本号''' -__version__ = '0.3.6' +__version__ = '0.3.7' '''作者''' __author__ = 'Charles' '''标题''' diff --git a/DecryptLogin/login.py b/DecryptLogin/login.py index c60e8ac..2e8f36d 100644 --- a/DecryptLogin/login.py +++ b/DecryptLogin/login.py @@ -6,7 +6,7 @@ Author: 微信公众号: Charles的皮卡丘 更新日期: - 2022-05-09 + 2022-07-19 ''' import warnings from .modules import * @@ -28,7 +28,7 @@ class Login(): 'douyu': douyu().login, 'migu': migu().login, 'qunar': qunar().login, 'mieshop': mieshop().login, 'mpweixin': mpweixin().login, 'baidutieba': baidutieba().login, 'dazhongdianping': dazhongdianping().login, 'jianguoyun': jianguoyun().login, 'cloud189': cloud189().login, 'qqmusic': qqmusic().login, 'ximalaya': ximalaya().login, 'icourse163': icourse163().login, - 'xiaomihealth': xiaomihealth().login, 'baidu': baidu().login, + 'xiaomihealth': xiaomihealth().login, 'baidu': baidu().login, 'alipan': alipan().login } for key, value in self.supported_apis.items(): setattr(self, key, value) @@ -52,7 +52,7 @@ class Client(): 'migu': MiguClient, 'qunar': QunarClient, 'xiaomihealth': XiaomiHealthClient, 'mieshop': MieShopClient, 'mpweixin': MpweixinClient, 'baidutieba': BaiduTiebaClient, 'dazhongdianping': DazhongdianpingClient, 'jianguoyun': JianguoyunClient, 'cloud189': Cloud189Client, 'qqmusic': QQMusicClient, 'ximalaya': XimalayaClient, 'icourse163': Icourse163Client, - 'tencentvideo': TencentVideoClient, 'baidu': BaiduClient, + 'tencentvideo': TencentVideoClient, 'baidu': BaiduClient, 'alipan': AlipanClient, } for key, value in self.supported_clients.items(): setattr(self, key, value) diff --git a/DecryptLogin/modules/__init__.py b/DecryptLogin/modules/__init__.py index 35eee0c..0688af9 100644 --- a/DecryptLogin/modules/__init__.py +++ b/DecryptLogin/modules/__init__.py @@ -4,7 +4,7 @@ from .core import ( toutiao, taobao, jingdong, ifeng, sohu, zgconline, lagou, twitter, eSurfing, renren, w3cschool, fishc, youdao, baidupan, stackoverflow, codalab, pypi, douyu, migu, qunar, mieshop, mpweixin, baidutieba, dazhongdianping, jianguoyun, cloud189, qqmusic, - ximalaya, icourse163, xiaomihealth, tencentvideo, baidu + ximalaya, icourse163, xiaomihealth, tencentvideo, baidu, alipan ) from .clients import ( MiguClient, PyPiClient, SohuClient, QQIdClient, QunarClient, FishCClient, LagouClient, IfengClient, @@ -13,5 +13,5 @@ from .clients import ( MieShopClient, QQMusicClient, MpweixinClient, Cloud189Client, XimalayaClient, eSurfingClient, Music163Client, BiliBiliClient, JingdongClient, BaiduPanClient, ZgconlineClient, W3CSchoolClient, BaiduTiebaClient, Icourse163Client, JianguoyunClient, XiaomiHealthClient, StackoverflowClient, - DazhongdianpingClient, TencentVideoClient, BaiduClient + DazhongdianpingClient, TencentVideoClient, BaiduClient, AlipanClient ) \ No newline at end of file diff --git a/DecryptLogin/modules/clients/__init__.py b/DecryptLogin/modules/clients/__init__.py index 0ff11f3..7c7fee8 100644 --- a/DecryptLogin/modules/clients/__init__.py +++ b/DecryptLogin/modules/clients/__init__.py @@ -12,6 +12,7 @@ from .zhihu import ZhihuClient from .QQQun import QQQunClient from .weibo import WeiboClient from .douyu import DouyuClient +from .alipan import AlipanClient from .youdao import YoudaoClient from .renren import RenRenClient from .taobao import TaobaoClient diff --git a/DecryptLogin/modules/clients/alipan.py b/DecryptLogin/modules/clients/alipan.py new file mode 100644 index 0000000..b9194a4 --- /dev/null +++ b/DecryptLogin/modules/clients/alipan.py @@ -0,0 +1,26 @@ +''' +Function: + 阿里云客户端 +Author: + Charles +微信公众号: + Charles的皮卡丘 +更新日期: + 2022-07-19 +''' +import re +import requests +from .baseclient import BaseClient + + +'''阿里云客户端''' +class AlipanClient(BaseClient): + def __init__(self, reload_history=True, **kwargs): + super(AlipanClient, self).__init__(website_name='douyu', reload_history=reload_history, **kwargs) + '''检查会话是否已经过期, 过期返回True''' + def checksessionstatus(self, session, infos_return): + url = 'https://api.aliyundrive.com/token/refresh' + response = requests.post(url, json={'refresh_token': infos_return['refresh_token']}) + if response.status_code == 200: + return False + return True \ No newline at end of file diff --git a/DecryptLogin/modules/clients/baseclient.py b/DecryptLogin/modules/clients/baseclient.py index 21aea02..3b7d607 100644 --- a/DecryptLogin/modules/clients/baseclient.py +++ b/DecryptLogin/modules/clients/baseclient.py @@ -26,7 +26,7 @@ class BaseClient(): 'douyu': douyu().login, 'migu': migu().login, 'qunar': qunar().login, 'mieshop': mieshop().login, 'mpweixin': mpweixin().login, 'baidutieba': baidutieba().login, 'dazhongdianping': dazhongdianping().login, 'jianguoyun': jianguoyun().login, 'cloud189': cloud189().login, 'qqmusic': qqmusic().login, 'ximalaya': ximalaya().login, 'icourse163': icourse163().login, - 'xiaomihealth': xiaomihealth().login, 'tencentvideo': tencentvideo().login + 'xiaomihealth': xiaomihealth().login, 'tencentvideo': tencentvideo().login, 'alipan': alipan().login } assert website_name in self.supported_apis self.rootdir = os.path.split(os.path.abspath(__file__))[0] @@ -73,7 +73,8 @@ class BaseClient(): infos_return, session = history_infos[username] # 检查是否已经过期 try: - if self.checksessionstatus(session, infos_return): return None, None, True + if self.checksessionstatus(session, infos_return): + return None, None, True except: return None, None, True # 返回可用的数据 diff --git a/DecryptLogin/modules/core/__init__.py b/DecryptLogin/modules/core/__init__.py index 06b4c72..8fd87d6 100644 --- a/DecryptLogin/modules/core/__init__.py +++ b/DecryptLogin/modules/core/__init__.py @@ -12,6 +12,7 @@ from .douyu import douyu from .zhihu import zhihu from .ifeng import ifeng from .QQQun import QQQun +from .alipan import alipan from .renren import renren from .youdao import youdao from .douban import douban @@ -49,5 +50,5 @@ __all__ = [ 'toutiao', 'taobao', 'jingdong', 'ifeng', 'sohu', 'zgconline', 'lagou', 'twitter', 'eSurfing', 'renren', 'w3cschool', 'fishc', 'youdao', 'baidupan', 'stackoverflow', 'codalab', 'pypi', 'douyu', 'migu', 'qunar', 'mieshop', 'mpweixin', 'baidutieba', 'dazhongdianping', 'jianguoyun', 'cloud189', 'qqmusic', - 'ximalaya', 'icourse163', 'xiaomihealth', 'tencentvideo' + 'ximalaya', 'icourse163', 'xiaomihealth', 'tencentvideo', 'alipan' ] \ No newline at end of file diff --git a/DecryptLogin/modules/core/alipan.py b/DecryptLogin/modules/core/alipan.py new file mode 100644 index 0000000..233d50c --- /dev/null +++ b/DecryptLogin/modules/core/alipan.py @@ -0,0 +1,144 @@ +''' +Function: + 阿里云盘模拟登录 +Author: + Charles +微信公众号: + Charles的皮卡丘 +更新日期: + 2022-07-19 +''' +import os +import re +import time +import json +import qrcode +import base64 +import requests +from ..utils import removeImage, saveImage, showImage + + +'''PC端登录阿里云盘''' +class alipanPC(): + is_callable = False + def __init__(self, **kwargs): + for key, value in kwargs.items(): setattr(self, key, value) + self.info = 'login in alipan in pc mode' + + +'''移动端登录阿里云盘''' +class alipanMobile(): + is_callable = False + def __init__(self, **kwargs): + for key, value in kwargs.items(): setattr(self, key, value) + self.info = 'login in alipan in mobile mode' + + +'''扫码登录阿里云盘''' +class alipanScanqr(): + is_callable = True + def __init__(self, **kwargs): + for key, value in kwargs.items(): setattr(self, key, value) + self.info = 'login in alipan in scanqr mode' + self.cur_path = os.getcwd() + self.session = requests.Session() + self.__initialize() + '''登录函数''' + def login(self, username='', password='', crack_captcha_func=None, **kwargs): + # 设置代理 + self.session.proxies.update(kwargs.get('proxies', {})) + # 获取登录二维码 + self.session.get('https://auth.aliyundrive.com/v2/oauth/authorize?client_id=25dzX3vbYqktVxyX&redirect_uri=https%3A%2F%2Fwww.aliyundrive.com%2Fsign%2Fcallback&response_type=code&login_type=custom&state=%7B%22origin%22%3A%22https%3A%2F%2Fwww.aliyundrive.com%22%7D') + response = self.session.get('https://passport.aliyundrive.com/newlogin/qrcode/generate.do?appName=aliyun_drive&fromSite=52&appName=aliyun_drive&appEntrance=web&_csrf_token=8iPG8rL8zndjoUQhrQnko5&umidToken=27f197668ac305a0a521e32152af7bafdb0ebc6c&isMobile=false&lang=zh_CN&returnUrl=&hsiz=1d3d27ee188453669e48ee140ea0d8e1&fromSite=52&bizParams=&_bx-v=2.0.31') + data = response.json()['content']['data'] + ck, t, code_content = data['ck'], data['t'], data['codeContent'] + # 保存并显示登录二维码 + qr = qrcode.QRCode( + version=2, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=1, + ) + qr.add_data(code_content) + qr.make(fit=True) + img = qr.make_image() + img.save(os.path.join(self.cur_path, 'qrcode.jpg')) + showImage(os.path.join(self.cur_path, 'qrcode.jpg')) + # 检测二维码状态 + while True: + response = self.session.post(self.qrcode_query_url, data={'ck': ck, 't': t}) + data = response.json()['content']['data'] + login_status = data['qrCodeStatus'] + if login_status in ['NEW', 'SCANED']: + continue + elif login_status in ['CONFIRMED']: + break + elif login_status in ['EXPIRED']: + raise RuntimeError('Fail to login, qrcode has expired') + else: + raise RuntimeError(login_status) + time.sleep(1) + # token登录 + removeImage(os.path.join(self.cur_path, 'qrcode.jpg')) + pds_login_result = json.loads(base64.b64decode(data['bizExt']).decode('gbk'))['pds_login_result'] + access_token = pds_login_result['accessToken'] + headers = { + 'Referer': 'https://auth.aliyundrive.com/v2/oauth/authorize?client_id=25dzX3vbYqktVxyX&redirect_uri=https%3A%2F%2Fwww.aliyundrive.com%2Fsign%2Fcallback&response_type=code&login_type=custom&state=%7B%22origin%22%3A%22https%3A%2F%2Fwww.aliyundrive.com%22%7D' + } + response = self.session.post(self.token_login_url, json={'token': access_token}, headers=headers) + code = re.findall(r'code=(.*?)\&', response.json()['goto'])[0] + response = self.session.post(self.token_get_url, json={'code': code}) + refresh_token = response.json()['refresh_token'] + response = requests.post(self.refresh_url, json={'refresh_token': refresh_token}) + response_json = response.json() + username = response_json['user_name'] + token, token_type, refresh_token, drive_id = response_json['access_token'], response_json['token_type'], response_json['refresh_token'], response_json['default_drive_id'] + self.session.headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36', + 'authorization': f'{token_type} {token}', + } + # 登录成功 + print('[INFO]: Account -> %s, login successfully' % username) + infos_return = {'username': username} + infos_return.update(response_json) + return infos_return, self.session + '''初始化''' + def __initialize(self): + self.qrcode_query_url = 'https://passport.aliyundrive.com/newlogin/qrcode/query.do?appName=aliyun_drive&fromSite=52&_bx-v=2.0.31' + self.token_login_url = 'https://auth.aliyundrive.com/v2/oauth/token_login' + self.token_get_url = 'https://api.aliyundrive.com/token/get' + self.refresh_url = 'https://api.aliyundrive.com/token/refresh' + + +''' +Function: + 阿里云盘模拟登录 +Detail: + -login: + Input: + --username: 用户名 + --password: 密码 + --mode: mobile/pc/scanqr + --crack_captcha_func: 若提供验证码接口, 则利用该接口来实现验证码的自动识别 + --proxies: 为requests.Session()设置代理 + Return: + --infos_return: 用户名等信息 + --session: 登录后的requests.Session() +''' +class alipan(): + def __init__(self, **kwargs): + self.info = 'login in alipan' + self.supported_modes = { + 'pc': alipanPC(**kwargs), + 'mobile': alipanMobile(**kwargs), + 'scanqr': alipanScanqr(**kwargs), + } + '''登录函数''' + def login(self, username='', password='', mode='scanqr', crack_captcha_func=None, **kwargs): + assert mode in self.supported_modes, 'unsupport mode %s in alipan.login' % mode + selected_api = self.supported_modes[mode] + if not selected_api.is_callable: raise NotImplementedError('not be implemented for mode %s in alipan.login' % mode) + args = { + 'username': username, + 'password': password, + 'crack_captcha_func': crack_captcha_func, + } + args.update(kwargs) + return selected_api.login(**args) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 81a2a90..12557ca 100644 --- a/LICENSE +++ b/LICENSE @@ -200,4 +200,5 @@ Copyright 2022-2030 CharlesPikachu. All rights reserved. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. + \ No newline at end of file diff --git a/README.md b/README.md index dec55a6..9f6f031 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ run "pip install git+https://github.com/CharlesPikachu/DecryptLogin.git@master" | xiaomihealth | ✗ | ✓ | ✗ | 小米运动 | | tencentvideo | ✗ | ✗ | ✓ | 腾讯视频 | | baidu | ✗ | ✗ | ✓ | 百度 | +| alipan | ✗ | ✗ | ✓ | 阿里云盘 | ### Quick Start diff --git a/docs/cn/RECOMMEND.md b/docs/cn/RECOMMEND.md index f6ac33d..2eb3ed5 100644 --- a/docs/cn/RECOMMEND.md +++ b/docs/cn/RECOMMEND.md @@ -35,3 +35,5 @@ - [图片下载器](https://github.com/CharlesPikachu/imagedl) - [从零开始实现一个深度学习框架](https://github.com/CharlesPikachu/pytoydl) + +- [小说下载器](https://github.com/CharlesPikachu/noveldl) \ No newline at end of file diff --git a/docs/cn/SUPPORTLIST.md b/docs/cn/SUPPORTLIST.md index a56e858..b5c3dc4 100644 --- a/docs/cn/SUPPORTLIST.md +++ b/docs/cn/SUPPORTLIST.md @@ -43,4 +43,5 @@ | [中国大学MOOC](https://www.icourse163.org/) | ✗ | ✓ | ✗ | | [小米运动](https://www.huami.com/) | ✗ | ✓ | ✗ | | [腾讯视频](https://v.qq.com/) | ✗ | ✗ | ✓ | -| [百度](https://baidu.com/) | ✗ | ✗ | ✓ | \ No newline at end of file +| [百度](https://baidu.com/) | ✗ | ✗ | ✓ | +| [阿里云盘](https://www.aliyundrive.com/) | ✗ | ✗ | ✓ | \ No newline at end of file diff --git a/docs/cn/requirements.txt b/docs/cn/requirements.txt index bbb1cb7..842ac88 100644 --- a/docs/cn/requirements.txt +++ b/docs/cn/requirements.txt @@ -1,4 +1,4 @@ recommonmark -sphinx -sphinx_markdown_tables +sphinx==4.5.0 +sphinx_markdown_tables==0.0.12 sphinx_rtd_theme \ No newline at end of file diff --git a/docs/en/RECOMMEND.md b/docs/en/RECOMMEND.md index d97a845..0906984 100644 --- a/docs/en/RECOMMEND.md +++ b/docs/en/RECOMMEND.md @@ -35,3 +35,5 @@ - [Imagedl](https://github.com/CharlesPikachu/imagedl): Search and download images from specific websites. - [Pytoydl](https://github.com/CharlesPikachu/pytoydl): A toy deep learning framework built upon numpy. + +- [NovelDL](https://github.com/CharlesPikachu/noveldl): Search and download novels from some specific websites. \ No newline at end of file diff --git a/docs/en/SUPPORTLIST.md b/docs/en/SUPPORTLIST.md index 11ec410..7160af5 100644 --- a/docs/en/SUPPORTLIST.md +++ b/docs/en/SUPPORTLIST.md @@ -43,4 +43,5 @@ | [icourse163](https://www.icourse163.org/) | ✗ | ✓ | ✗ | | [xiaomihealth](https://www.huami.com/) | ✗ | ✓ | ✗ | | [tencentvideo](https://v.qq.com/) | ✗ | ✗ | ✓ | -| [baidu](https://baidu.com/) | ✗ | ✗ | ✓ | \ No newline at end of file +| [baidu](https://baidu.com/) | ✗ | ✗ | ✓ | +| [alipan](https://www.aliyundrive.com/) | ✗ | ✗ | ✓ | \ No newline at end of file diff --git a/docs/en/requirements.txt b/docs/en/requirements.txt index bbb1cb7..842ac88 100644 --- a/docs/en/requirements.txt +++ b/docs/en/requirements.txt @@ -1,4 +1,4 @@ recommonmark -sphinx -sphinx_markdown_tables +sphinx==4.5.0 +sphinx_markdown_tables==0.0.12 sphinx_rtd_theme \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 014ebc7..5d4f5cf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -rsa >= 4.0 +rsa >= 4.0 qrcode >= 6.1 pillow >= 6.0.0 PyExecJS >= 1.5.1 requests >= 2.22.0 pycryptodome >= 3.8.1 requests_toolbelt >= 0.9.1 -gmssl >= 3.2.1 +gmssl >= 3.2.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 1d83883..825e17d 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ Author: GitHub: https://github.com/CharlesPikachu 更新日期: - 2022-02-08 + 2022-07-19 ''' import DecryptLogin from setuptools import setup, find_packages @@ -37,7 +37,7 @@ setup( author_email=DecryptLogin.__email__, license=DecryptLogin.__license__, include_package_data=True, - install_requires=list(open('requirements.txt', 'r').readlines()), + install_requires=[lab.strip('\n') for lab in list(open('requirements.txt', 'r').readlines())], zip_safe=True, packages=find_packages() ) \ No newline at end of file