mirror of
https://github.com/Bao-qing/123pan.git
synced 2025-11-13 20:26:09 +08:00
添加文件夹递归下载
This commit is contained in:
parent
69ee866e35
commit
d1d6b53101
47
README.md
47
README.md
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
## 项目介绍
|
## 项目介绍
|
||||||
|
|
||||||
123Pan 下载工具是一个使用 Python 编写的脚本,通过模拟安卓客户端协议来绕过 123Pan 的下载流量限制。该工具可以帮助用户在 Windows 系统上方便地下载 123Pan 上的文件,并提供了多种操作功能,如列出文件、下载文件、上传文件、分享文件等。
|
123Pan 下载工具是一个使用 Python 编写的脚本,通过模拟安卓客户端协议来绕过 123Pan 的下载流量限制。该工具可以帮助用户在电脑上方便地下载 123云盘上的文件,并提供了多种操作功能,如列出文件、下载文件、上传文件、分享文件等。
|
||||||
|
|
||||||
|
**更新内容:** 添加文件夹递归下载,不受流量限制
|
||||||
|
|
||||||
## 功能特点
|
## 功能特点
|
||||||
|
|
||||||
|
|
@ -32,13 +34,9 @@
|
||||||
|
|
||||||
### 运行脚本
|
### 运行脚本
|
||||||
|
|
||||||
```
|
|
||||||
可以直接下载release的可执行文件运行或运行python脚本。
|
可以直接下载release的可执行文件运行或运行python脚本。
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
脚本运行:
|
脚本运行:
|
||||||
```
|
|
||||||
|
|
||||||
1. 克隆或下载本项目代码到本地。
|
1. 克隆或下载本项目代码到本地。
|
||||||
|
|
||||||
|
|
@ -52,29 +50,38 @@
|
||||||
python android.py
|
python android.py
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
使用web协议(不建议,已停止更新)
|
||||||
使用web协议
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python web.py
|
python web.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### 命令
|
### 命令
|
||||||
|
|
||||||
- **登录**:`log`
|
- **登录**:`log`
|
||||||
|
|
||||||
- **列出文件**:`ls`
|
- **列出文件**:`ls`
|
||||||
|
|
||||||
- **刷新目录**:`re`
|
- **刷新目录**:`re`
|
||||||
|
|
||||||
- **下载文件**:`download <文件编号>`
|
- **下载文件**:`download <文件编号>`
|
||||||
|
|
||||||
Android下可以直接下载文件夹
|
Android下可以直接下载文件夹
|
||||||
|
|
||||||
- **获取下载链接** `link <文件编号>`
|
- **获取下载链接** `link <文件编号>`
|
||||||
|
|
||||||
- **分享文件**:`share`
|
- **分享文件**:`share`
|
||||||
|
|
||||||
- **删除文件**:`delete <文件编号>`
|
- **删除文件**:`delete <文件编号>`
|
||||||
|
|
||||||
- **创建文件夹**:`mkdir <文件夹名称>`
|
- **创建文件夹**:`mkdir <文件夹名称>`
|
||||||
|
|
||||||
- **切换目录**:`cd <目录编号>` 或 `cd ..` 返回上一级目录
|
- **切换目录**:`cd <目录编号>` 或 `cd ..` 返回上一级目录
|
||||||
|
|
||||||
- **上传文件**:`upload`,然后输入文件路径
|
- **上传文件**:`upload`,然后输入文件路径
|
||||||
|
|
||||||
- **直接输入数字**:进入文件夹,或是下载文件
|
- **直接输入数字**:进入文件夹,或是下载文件
|
||||||
|
|
||||||
- **退出**:`exit`
|
- **退出**:`exit`
|
||||||
|
|
||||||
### 示例
|
### 示例
|
||||||
|
|
@ -110,16 +117,18 @@
|
||||||
|
|
||||||
下载文件夹(android):
|
下载文件夹(android):
|
||||||
|
|
||||||
|
打包下载依旧会受到流量限制,递归下载无限制,请尽量使用递归下载。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
>download 2
|
>download 13
|
||||||
test
|
test
|
||||||
将打包下载文件夹,输入1开始下载:1
|
输入1遍历下载,输入2打包下载:1
|
||||||
打包下载
|
文件 FLUID.dat 已存在,是否要覆盖?
|
||||||
文件 test.zip 已存在,是否要覆盖?
|
输入1覆盖,2跳过,3全部覆盖,4全部跳过:4
|
||||||
输入1覆盖,2取消:1
|
已跳过
|
||||||
test.zip 1.78K
|
文件 FLUID.cas已跳过
|
||||||
[██████████████████████████████████████████████████] 100%
|
文件 profili2.3.zip已跳过
|
||||||
ok
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
4. 获取下载链接
|
4. 获取下载链接
|
||||||
|
|
@ -173,4 +182,4 @@
|
||||||
|
|
||||||
- 请确保在使用过程中网络连接正常。
|
- 请确保在使用过程中网络连接正常。
|
||||||
- 由于使用了模拟安卓客户端协议,可能会有一定的风险,请谨慎使用。
|
- 由于使用了模拟安卓客户端协议,可能会有一定的风险,请谨慎使用。
|
||||||
- 本工具仅供学习和研究使用,请勿用于非法用途。
|
- 本工具仅供学习和研究使用,请勿用于非法用途,任何滥用行为造成的后果由使用者承担
|
||||||
|
|
|
||||||
117
android.py
117
android.py
|
|
@ -18,9 +18,13 @@ class Pan123:
|
||||||
authorization="",
|
authorization="",
|
||||||
input_pwd=True,
|
input_pwd=True,
|
||||||
):
|
):
|
||||||
|
self.download_mode = 1
|
||||||
self.cookies = None
|
self.cookies = None
|
||||||
self.recycle_list = None
|
self.recycle_list = None
|
||||||
self.list = None
|
self.list = None
|
||||||
|
self.file_list = []
|
||||||
|
self.dir_list = []
|
||||||
|
self.name_dict = {}
|
||||||
if readfile:
|
if readfile:
|
||||||
self.read_ini(user_name, pass_word, input_pwd, authorization)
|
self.read_ini(user_name, pass_word, input_pwd, authorization)
|
||||||
else:
|
else:
|
||||||
|
|
@ -53,7 +57,7 @@ class Pan123:
|
||||||
}
|
}
|
||||||
self.parent_file_id = 0 # 路径,文件夹的id,0为根目录
|
self.parent_file_id = 0 # 路径,文件夹的id,0为根目录
|
||||||
self.parent_file_list = [0]
|
self.parent_file_list = [0]
|
||||||
res_code_getdir = self.get_dir()
|
res_code_getdir = self.get_dir()[0]
|
||||||
if res_code_getdir != 0:
|
if res_code_getdir != 0:
|
||||||
self.login()
|
self.login()
|
||||||
self.get_dir()
|
self.get_dir()
|
||||||
|
|
@ -107,7 +111,10 @@ class Pan123:
|
||||||
f.write(json.dumps(save_list))
|
f.write(json.dumps(save_list))
|
||||||
print("账号已保存")
|
print("账号已保存")
|
||||||
|
|
||||||
def get_dir(self):
|
def get_dir(self,save=True):
|
||||||
|
return self.get_dir_by_id(self.parent_file_id,save)
|
||||||
|
|
||||||
|
def get_dir_by_id(self, file_id,save=True):
|
||||||
res_code_getdir = 0
|
res_code_getdir = 0
|
||||||
page = 1
|
page = 1
|
||||||
lists = []
|
lists = []
|
||||||
|
|
@ -125,7 +132,7 @@ class Pan123:
|
||||||
"next": 0,
|
"next": 0,
|
||||||
"orderBy": "file_id",
|
"orderBy": "file_id",
|
||||||
"orderDirection": "desc",
|
"orderDirection": "desc",
|
||||||
"parentFileId": str(self.parent_file_id),
|
"parentFileId": str(file_id),
|
||||||
"trashed": False,
|
"trashed": False,
|
||||||
"SearchData": "",
|
"SearchData": "",
|
||||||
"Page": str(page),
|
"Page": str(page),
|
||||||
|
|
@ -141,8 +148,8 @@ class Pan123:
|
||||||
text = a.json()
|
text = a.json()
|
||||||
res_code_getdir = text["code"]
|
res_code_getdir = text["code"]
|
||||||
if res_code_getdir != 0:
|
if res_code_getdir != 0:
|
||||||
#print(a.text)
|
# print(a.text)
|
||||||
#print(a.headers)
|
# print(a.headers)
|
||||||
print("code = 2 Error:" + str(res_code_getdir))
|
print("code = 2 Error:" + str(res_code_getdir))
|
||||||
return res_code_getdir
|
return res_code_getdir
|
||||||
lists_page = text["data"]["InfoList"]
|
lists_page = text["data"]["InfoList"]
|
||||||
|
|
@ -154,9 +161,9 @@ class Pan123:
|
||||||
for i in lists:
|
for i in lists:
|
||||||
i["FileNum"] = file_num
|
i["FileNum"] = file_num
|
||||||
file_num += 1
|
file_num += 1
|
||||||
|
if save:
|
||||||
self.list = lists
|
self.list = lists
|
||||||
return res_code_getdir
|
return res_code_getdir, lists
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
print("--------------------")
|
print("--------------------")
|
||||||
|
|
@ -187,9 +194,13 @@ class Pan123:
|
||||||
print("--------------------")
|
print("--------------------")
|
||||||
|
|
||||||
# fileNumber 从0开始,0为第一个文件,传入时需要减一 !!!
|
# fileNumber 从0开始,0为第一个文件,传入时需要减一 !!!
|
||||||
def link(self, file_number, showlink=True):
|
def link_by_number(self, file_number, showlink=True):
|
||||||
file_detail = self.list[file_number]
|
file_detail = self.list[file_number]
|
||||||
|
return self.link_by_fileDetail(file_detail, showlink)
|
||||||
|
|
||||||
|
def link_by_fileDetail(self, file_detail, showlink=True):
|
||||||
type_detail = file_detail["Type"]
|
type_detail = file_detail["Type"]
|
||||||
|
|
||||||
if type_detail == 1:
|
if type_detail == 1:
|
||||||
down_request_url = "https://www.123pan.com/a/api/file/batch_download_info"
|
down_request_url = "https://www.123pan.com/a/api/file/batch_download_info"
|
||||||
down_request_data = {"fileIdList": [{"fileId": int(file_detail["FileId"])}]}
|
down_request_data = {"fileIdList": [{"fileId": int(file_detail["FileId"])}]}
|
||||||
|
|
@ -231,25 +242,40 @@ class Pan123:
|
||||||
|
|
||||||
return redirect_url
|
return redirect_url
|
||||||
|
|
||||||
def download(self, file_number,download_path="download/"):
|
def download(self, file_number,download_path="download"):
|
||||||
file_detail = self.list[file_number]
|
file_detail = self.list[file_number]
|
||||||
if file_detail["Type"] == 1:
|
if file_detail["Type"] == 1:
|
||||||
print("打包下载")
|
print("开始下载")
|
||||||
file_name = file_detail["FileName"] + ".zip"
|
file_name = file_detail["FileName"] + ".zip"
|
||||||
else:
|
else:
|
||||||
file_name = file_detail["FileName"] # 文件名
|
file_name = file_detail["FileName"] # 文件名
|
||||||
down_load_url = self.link(file_number, showlink=False)
|
|
||||||
|
|
||||||
if os.path.exists(download_path+file_name):
|
down_load_url = self.link_by_number(file_number, showlink=False)
|
||||||
print("文件 " + file_name + " 已存在,是否要覆盖?")
|
self.download_from_url(down_load_url, file_name, download_path)
|
||||||
sure_download = input("输入1覆盖,2取消:")
|
|
||||||
if sure_download != "1":
|
|
||||||
|
def download_from_url(self, url, file_name, download_path="download"):
|
||||||
|
if os.path.exists(download_path+"/"+file_name):
|
||||||
|
if self.download_mode == 4:
|
||||||
|
print("文件 " + file_name +"已跳过")
|
||||||
return
|
return
|
||||||
|
print("文件 " + file_name + " 已存在,是否要覆盖?")
|
||||||
|
sure_download = input("输入1覆盖,2跳过,3全部覆盖,4全部跳过:")
|
||||||
|
if sure_download == "2":
|
||||||
|
return
|
||||||
|
elif sure_download == "3":
|
||||||
|
self.download_mode = 3
|
||||||
|
elif sure_download == "4":
|
||||||
|
self.download_mode = 4
|
||||||
|
print("已跳过")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
os.remove(download_path+"/"+file_name)
|
||||||
|
|
||||||
if not os.path.exists(download_path):
|
if not os.path.exists(download_path):
|
||||||
print("文件夹不存在,创建文件夹")
|
print("文件夹不存在,创建文件夹")
|
||||||
os.makedirs(download_path)
|
os.makedirs(download_path)
|
||||||
down = requests.get(down_load_url, stream=True, timeout=10)
|
down = requests.get(url, stream=True, timeout=10)
|
||||||
|
|
||||||
file_size = int(down.headers["Content-Length"]) # 文件大小
|
file_size = int(down.headers["Content-Length"]) # 文件大小
|
||||||
content_size = int(file_size) # 文件总大小
|
content_size = int(file_size) # 文件总大小
|
||||||
|
|
@ -262,7 +288,8 @@ class Pan123:
|
||||||
time1 = time.time()
|
time1 = time.time()
|
||||||
time_temp = time1
|
time_temp = time1
|
||||||
data_count_temp = 0
|
data_count_temp = 0
|
||||||
with open(download_path+file_name, "wb") as f:
|
# 以.123pan后缀下载,下载完成重命名,防止下载中断
|
||||||
|
with open(download_path+"/"+file_name+".123pan", "wb") as f:
|
||||||
for i in down.iter_content(1024):
|
for i in down.iter_content(1024):
|
||||||
f.write(i)
|
f.write(i)
|
||||||
done_block = int((data_count / content_size) * 50)
|
done_block = int((data_count / content_size) * 50)
|
||||||
|
|
@ -297,6 +324,47 @@ class Pan123:
|
||||||
print("\r [%s%s] %d%% %s" % (50 * "█", "", 100, ""), end="")
|
print("\r [%s%s] %d%% %s" % (50 * "█", "", 100, ""), end="")
|
||||||
print("\nok")
|
print("\nok")
|
||||||
|
|
||||||
|
os.rename(download_path+"/"+file_name+".123pan", download_path+"/"+file_name)
|
||||||
|
|
||||||
|
def get_all_things(self,id):
|
||||||
|
# print(id)
|
||||||
|
# print(self.dir_list)
|
||||||
|
self.dir_list.remove(id)
|
||||||
|
all_list = self.get_dir_by_id(id,save=False)[1]
|
||||||
|
|
||||||
|
for i in all_list:
|
||||||
|
if i["Type"] == 0:
|
||||||
|
self.file_list.append(i)
|
||||||
|
else:
|
||||||
|
self.dir_list.append(i["FileId"])
|
||||||
|
self.name_dict[i["FileId"]] = i["FileName"]
|
||||||
|
|
||||||
|
for i in self.dir_list:
|
||||||
|
self.get_all_things(i)
|
||||||
|
|
||||||
|
def download_dir(self,file_number,download_path_root="download"):
|
||||||
|
file_detail = self.list[file_number]
|
||||||
|
if file_detail["Type"] != 1:
|
||||||
|
print("不是文件夹")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.file_list = []
|
||||||
|
self.dir_list = [file_detail["FileId"]]
|
||||||
|
self.name_dict = {file_detail["FileId"]:file_detail["FileName"]}
|
||||||
|
self.get_all_things(file_detail["FileId"])
|
||||||
|
# print(self.file_list)
|
||||||
|
# print(self.dir_list)
|
||||||
|
# print(self.name_dict)
|
||||||
|
for i in self.file_list:
|
||||||
|
AbsPath = i["AbsPath"]
|
||||||
|
for key,value in self.name_dict.items():
|
||||||
|
AbsPath = AbsPath.replace(str(key),value)
|
||||||
|
download_path = download_path_root + AbsPath
|
||||||
|
download_path = download_path.replace("/"+str(i["FileId"]),"")
|
||||||
|
self.download_from_url(i["DownloadUrl"],i["FileName"],download_path)
|
||||||
|
|
||||||
|
self.download_mode = 1
|
||||||
|
|
||||||
def recycle(self):
|
def recycle(self):
|
||||||
recycle_id = 0
|
recycle_id = 0
|
||||||
url = (
|
url = (
|
||||||
|
|
@ -718,11 +786,12 @@ if __name__ == "__main__":
|
||||||
pan = Pan123(readfile=True, input_pwd=True)
|
pan = Pan123(readfile=True, input_pwd=True)
|
||||||
pan.show()
|
pan.show()
|
||||||
while True:
|
while True:
|
||||||
|
#pan.get_all_things()
|
||||||
command = input("\033[91m >\033[0m")
|
command = input("\033[91m >\033[0m")
|
||||||
if command == "ls":
|
if command == "ls":
|
||||||
pan.show()
|
pan.show()
|
||||||
if command == "re":
|
if command == "re":
|
||||||
code = pan.get_dir()
|
code = pan.get_dir()[0]
|
||||||
if code == 0:
|
if code == 0:
|
||||||
print("刷新目录成功")
|
print("刷新目录成功")
|
||||||
pan.show()
|
pan.show()
|
||||||
|
|
@ -752,11 +821,15 @@ if __name__ == "__main__":
|
||||||
continue
|
continue
|
||||||
if pan.list[int(command[9:]) - 1]["Type"] == 1:
|
if pan.list[int(command[9:]) - 1]["Type"] == 1:
|
||||||
print(pan.list[int(command[9:]) - 1]["FileName"])
|
print(pan.list[int(command[9:]) - 1]["FileName"])
|
||||||
print("将打包下载文件夹,输入1开始下载:", end="")
|
print("输入1遍历下载,输入2打包下载:", end="")
|
||||||
sure = input()
|
sure = input()
|
||||||
if sure != "1":
|
if sure == "2":
|
||||||
continue
|
|
||||||
pan.download(int(command[9:]) - 1)
|
pan.download(int(command[9:]) - 1)
|
||||||
|
elif sure == "1":
|
||||||
|
pan.download_dir(int(command[9:]) - 1)
|
||||||
|
else:
|
||||||
|
pan.download(int(command[9:]) - 1)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("输入错误")
|
print("输入错误")
|
||||||
elif command == "exit":
|
elif command == "exit":
|
||||||
|
|
@ -771,7 +844,7 @@ if __name__ == "__main__":
|
||||||
if int(command[5:]) > len(pan.list) or int(command[5:]) < 1:
|
if int(command[5:]) > len(pan.list) or int(command[5:]) < 1:
|
||||||
print("输入错误")
|
print("输入错误")
|
||||||
continue
|
continue
|
||||||
pan.link(int(command[5:]) - 1)
|
pan.link_by_number(int(command[5:]) - 1)
|
||||||
else:
|
else:
|
||||||
print("输入错误")
|
print("输入错误")
|
||||||
elif command == "upload":
|
elif command == "upload":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user