0%

python操作百度云盘

从网上找了一些资料,全都是百度云盘分享的带密码的有800 多条 想怎么批量解决

找了几个软件 发现都不能使用了 最后在知乎找到一个python的代码
由于版本问题 保存分享的功能有点问题 改了下源码 记录下

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# coding="utf-8"

import requests
import re
import json
import time
import random
# 解决验证码问题,经过测试实际使用过程中不会出验证码,所以没装的话可以屏蔽掉
# import pytesseract
from PIL import Image
from io import BytesIO


'''
初次使用时,请先从浏览器的开发者工具中获取百度网盘的Cookie,并设置在init方法中进行配置,并调用verifyCookie方法测试Cookie的有效性
已实现的方法:
1.获取登录Cookie有效性;
2.获取网盘中指定目录的文件列表;
3.获取加密分享链接的提取码;
4.转存分享的资源;
5.重命名网盘中指定的文件;
6.删除网盘中的指定文件;
7.移动网盘中指定文件至指定目录;
8.创建分享链接;
'''
class BaiDuPan(object):
def __init__(self):
# 创建session并设置初始登录Cookie
self.session = requests.session()
self.session.cookies['BDUSS'] = ''
self.session.cookies['STOKEN'] = ''
self.headers = {
'Host': 'pan.baidu.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
}

'''
验证Cookie是否已登录
返回值errno代表的意思:
0 有效的Cookie;1 init方法中未配置登录Cookie;2 无效的Cookie
'''
def verifyCookie(self):
if(self.session.cookies['BDUSS'] == '' or self.session.cookies['STOKEN'] == ''):
return {'errno': 1, 'err_msg': '请在init方法中配置百度网盘登录Cookie'}
else:
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
home_page = response.content.decode("utf-8")
if('<title>百度网盘-全部文件</title>' in home_page):
#user_name = re.findall(r'\, \'(.+?)\'\)', home_page)[0]
user_name = 'me'
return {'errno': 0, 'err_msg': '有效的Cookie,用户名:%s' % user_name}
else:
return {'errno': 2, 'err_msg': '无效的Cookie!'}


'''
获取指定目录的文件列表,直接返回原始的json
'''
def getFileList(self, dir='/', order='time', desc=0, page=1, num=100):
'''
构造获取文件列表的URL:
https://pan.baidu.com/api/list?
bdstoken= 从首页中可以获取到
&dir=/ 需要获取的目录
&order=name 可能值:name,time,size
&desc=0 0表示正序,1表示倒序
&page= 第几页
&num=100 每页文件数量
&t=0.8685513844705777 推测为随机字符串
&startLogTime=1581862647373 时间戳
&logid=MTU4MTg2MjY0NzM3MzAuMzM2MTAzMzk5MTg3NzYyOQ== 固定值
&clienttype=0 固定值
&showempty=0 固定值
&web=1 固定值
&channel=chunlei 固定值
&app_id=250528 固定值
'''
# 访问首页获取bdstoken
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
bdstoken = re.findall(r'initPrefetch\(\'(.+?)\'\,', response.content.decode("utf-8"))[0]
t = random.random()
startLogTime = str(int(time.time()) * 1000)
url = 'https://pan.baidu.com/api/list?bdstoken=%s&dir=%s&order=%s&desc=%s&page=%s&num=%s&t=%s&startLogTime=%s\
&logid=MTU4MTg2MjY0NzM3MzAuMzM2MTAzMzk5MTg3NzYyOQ==&clienttype=0&showempty=0&web=1&channel=chunlei&app_id=250528'\
% (bdstoken, dir, order, desc, page, num, t, startLogTime)
headers = self.headers
headers['Referer'] = 'https://pan.baidu.com/disk/home?'
response = self.session.get(url, headers=headers)
return response.json()


'''
获取分享链接的提取码
返回值errno代表的意思:
0 提取码获取成功;1 提取码获取失败;
'''
@staticmethod
def getSharePwd(surl):
# 云盘精灵的接口
ypsuperkey_headers = {
'Host': 'ypsuperkey.meek.com.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
}
response = requests.get('https://ypsuperkey.meek.com.cn/api/v1/items/BDY-%s?client_version=2019.2' % surl, headers=ypsuperkey_headers)
pwd = response.json().get('access_code', '')
if(not pwd):
# 小鸟云盘搜索接口
aisou_headers = {
'Host': 'helper.aisouziyuan.com',
'Origin': 'https://pan.baidu.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
'Referer': 'https://pan.baidu.com/share/init?surl=%s' % surl,
}
form_data = {
'url': surl,
'wrong': 'false',
'type': 'baidu',
'v': '3.132',
}
response = requests.post('https://helper.aisouziyuan.com/Extensions/Api/ResourcesCode?v=3.132', headers=aisou_headers, data=form_data)
pwd = response.text
errno, err_msg = (0, '提取码获取成功') if pwd else (1, '提取码获取失败:%s' % response.text)
return {'errno': errno, 'err_msg': err_msg, 'pwd': pwd}


'''
识别 验证加密分享时的验证码
返回值errno代表的意思:
0 识别成功;1 识别失败;其他值 获取验证码失败;
'''
def vcodeOCR(self):
# 获取验证码
vcode_res = requests.get('https://pan.baidu.com/api/getcaptcha?prod=shareverify&web=1&channel=chunlei&web=1&app_id=250528&bdstoken=null&clienttype=0', headers=self.headers)
vcode_json = vcode_res.json()
if(vcode_json['errno'] == 0):
# 获取验证码图片
genimage = requests.get(vcode_json['vcode_img'], headers=self.headers)
# 非自动化脚本,可以改为人工识别,并且将人工识别的验证码保存,用于后续的CNN训练
vcode_image = BytesIO(genimage.content)
image = Image.open(vcode_image)
image.show()
vcode = input('请输入验证码:')
f = open('./vcodeImg/%s - %s.jpg' % (vcode, str(int(time.time()) * 1000)), 'wb')
f.write(genimage.content)
f.close()

'''
将验证码图片加载至内存中进行自动识别
由于验证码旋转和紧贴,所以导致pytesseract识别率非常底!
考虑基于CNN深度学习识别,筹备数据集需要一定的时间
临时解决方案是:识别失败进行重试,加大重试次数
'''
# vcode_image = BytesIO(genimage.content)
# image = Image.open(vcode_image)
# vcode = pytesseract.image_to_string(image)
errno, err_msg = (1, '识别失败') if(len(vcode) != 4) else (0, '识别成功')
vcode_str = vcode_json['vcode_str']
else:
errno = vcode_json['errno']
err_msg = '获取验证码失败'
vcode_str = ''
return {'errno': errno, 'err_msg': err_msg, 'vcode': vcode, 'vcode_str': vcode_str}


'''
验证加密分享
返回值errno代表的意思:
0 加密分享验证通过;1 验证码获取失败;2 提取码不正确;3 加密分享验证失败;4 重试几次后,验证码依旧不正确;
'''
def verifyShare(self, surl, bdstoken, pwd, referer):
'''
构造密码验证的URL:https://pan.baidu.com/share/verify?
surl=62yUYonIFdKGdAaueOkyaQ 从重定向后的URL中获取
&t=1572356417593 时间戳
&channel=chunlei 固定值
&web=1 固定值
&app_id=250528 固定值
&bdstoken=742aa0d6886423a5503bbc67afdb2a7d 从重定向后的页面中可以找到,有时候会为空,经过验证,不要此字段也可以
&logid=MTU0ODU4MzUxMTgwNjAuNDg5NDkyMzg5NzAyMzY1MQ== 不知道什么作用,暂时为空或者固定值都可以
&clienttype=0 固定值
'''
t = str(int(time.time()) * 1000)
url = 'https://pan.baidu.com/share/verify?surl=%s&t=%s&channel=chunlei&web=1&app_id=250528&bdstoken=%s\
&logid=MTU0ODU4MzUxMTgwNjAuNDg5NDkyMzg5NzAyMzY1MQ==&clienttype=0' % (surl, t, bdstoken)
form_data = {
'pwd': pwd,
'vcode': '',
'vcode_str': '',
}
# 设置重试机制
is_vcode = False
for n in range(1, 166):
# 自动获取并识别验证码,使用pytesseract自动识别时,可加大重试次数
if is_vcode:
ocr_result = self.vcodeOCR()
if(ocr_result['errno'] == 0):
form_data['vcode'] = ocr_result['vcode']
form_data['vcode_str'] = ocr_result['vcode_str']
elif(ocr_result['errno'] == 1):
continue
else:
return {'errno': 1, 'err_msg': '验证码获取失败:%d' % ocr_result['errno']}
headers = self.headers
headers['referer'] = referer
# verify_json['errno']:-9表示提取码不正确;-62表示需要验证码/验证码不正确(不输入验证码也是此返回值)
verify_res = self.session.post(url, headers=headers, data=form_data)
verify_json = verify_res.json()
if(verify_json['errno'] == 0):
return {'errno': 0, 'err_msg': '加密分享验证通过'}
elif(verify_json['errno'] == -9):
return {'errno': 2, 'err_msg': '提取码不正确'}
elif(verify_json['errno'] == -62):
is_vcode = True
else:
return {'errno': 3, 'err_msg': '加密分享验证失败:%d' % verify_json['errno']}
return {'errno': 4, 'err_msg': '重试多次后,验证码依旧不正确:%d' % (verify_json['errno'] if("verify_json" in locals()) else -1)}


'''
返回值errno代表的意思:
0 转存成功;1 无效的分享链接;2 分享文件已被删除;
3 分享文件已被取消;4 分享内容侵权,无法访问;5 找不到文件;6 分享文件已过期
7 获取提取码失败;8 获取加密cookie失败; 9 转存失败;
'''
def saveShare(self, url, pwd=None, path='/'):
share_res = self.session.get(url, headers=self.headers)
share_page = share_res.content.decode("utf-8")
'''
1.如果分享链接有密码,会被重定向至输入密码的页面;
2.如果分享链接不存在,会被重定向至404页面https://pan.baidu.com/error/404.html,但是状态码是200;
3.如果分享链接已被删除,页面会提示:啊哦,你来晚了,分享的文件已经被删除了,下次要早点哟。
4.如果分享链接已被取消,页面会提示:啊哦,你来晚了,分享的文件已经被取消了,下次要早点哟。
5.如果分享链接涉及侵权,页面会提示:此链接分享内容可能因为涉及侵权、色情、反动、低俗等信息,无法访问!
6.啊哦!链接错误没找到文件,请打开正确的分享链接!
7.啊哦,来晚了,该分享文件已过期
'''
if('error/404.html' in share_res.url):
return {"errno": 1, "err_msg": "无效的分享链接", "extra": "", "info": ""}
if('你来晚了,分享的文件已经被删除了,下次要早点哟' in share_page):
return {"errno": 2, "err_msg": "分享文件已被删除", "extra": "", "info": ""}
if('你来晚了,分享的文件已经被取消了,下次要早点哟' in share_page):
return {"errno": 3, "err_msg": "分享文件已被取消", "extra": "", "info": ""}
if('此链接分享内容可能因为涉及侵权、色情、反动、低俗等信息,无法访问' in share_page):
return {"errno": 4, "err_msg": "分享内容侵权,无法访问", "extra": "", "info": ""}
if('链接错误没找到文件,请打开正确的分享链接' in share_page):
return {"errno": 5, "err_msg": "链接错误没找到文件", "extra": "", "info": ""}
if('啊哦,来晚了,该分享文件已过期' in share_page):
return {"errno": 6, "err_msg": "分享文件已过期", "extra": "", "info": ""}

# 提取码校验的请求中有此参数
bdstoken = re.findall(r'bdstoken\":\"(.+?)\"', share_page)
bdstoken = bdstoken[0] if(bdstoken) else ''
# 如果加密分享,需要验证提取码,带上验证通过的Cookie再请求分享链接,即可获取分享文件
if('init' in share_res.url):
surl = re.findall(r'surl=(.+?)$', share_res.url)[0]
if(pwd == None):
pwd_result = self.getSharePwd(surl)
if(pwd_result['errno'] != 0):
return {"errno": 7, "err_msg": pwd_result['err_msg'], "extra": "", "info": ""}
else:
pwd = pwd_result['pwd']
referer = share_res.url
verify_result = self.verifyShare(surl, bdstoken, pwd, referer)
if(verify_result['errno'] != 0):
return {"errno": 8, "err_msg": verify_result['err_msg'], "extra": "", "info": ""}
else:
# 加密分享验证通过后,使用全局session刷新页面(全局session中带有解密的Cookie)
share_res = self.session.get(url, headers=self.headers)
share_page = share_res.content.decode("utf-8")
# 更新bdstoken,有时候会出现 AttributeError: 'NoneType' object has no attribute 'group',重试几次就好了
#share_data = json.loads(re.search("yunData.setData\(({.*})\)", share_page).group(1))
share_data = json.loads(re.search("locals.mset\(({.*})\)", share_page).group(1))
bdstoken = share_data['bdstoken']
shareid = share_data['shareid']
_from = share_data['share_uk']
'''
构造转存的URL,除了logid不知道有什么用,但是经过验证,固定值没问题,其他变化的值均可在验证通过的页面获取到
'''
save_url = 'https://pan.baidu.com/share/transfer?shareid=%s&from=%s&ondup=newcopy&async=1&channel=chunlei&web=1&app_id=250528&bdstoken=%s\
&logid=MTU3MjM1NjQzMzgyMTAuMjUwNzU2MTY4MTc0NzQ0MQ==&clienttype=0' % (shareid, _from, bdstoken)
#file_list = share_data['file_list']['list']
file_list = share_data['file_list']
form_data = {
# 这个参数一定要注意,不能使用['fs_id', 'fs_id'],谨记!
'fsidlist': '[' + ','.join([str(item['fs_id']) for item in file_list]) + ']',
'path': path,
}
headers = self.headers
headers['Origin'] = 'https://pan.baidu.com'
headers['referer'] = url
'''
用带登录Cookie的全局session请求转存
如果有同名文件,保存的时候会自动重命名:类似xxx(1)
暂时不支持超过文件数量的文件保存
'''
save_res = self.session.post(save_url, headers=headers, data=form_data)
save_json = save_res.json()
errno, err_msg, extra, info = (0, '转存成功', save_json['extra'], save_json['info']) if(save_json['errno'] == 0) else (9, '转存失败:%d' % save_json['errno'], '', '')
return {'errno': errno, 'err_msg': err_msg, "extra": extra, "info": info}


'''
重命名指定文件
0 重命名成功;1 重命名失败;
'''
def rename(self, path, newname):
'''
构造重命名的URL:https://pan.baidu.com/api/filemanager?
bdstoken= 从首页可以获取到
&opera=rename 固定值
&async=2 固定值
&onnest=fail 固定值
&channel=chunlei 固定在
&web=1 固定值
&app_id=250528 固定值
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng== 固定值
&clienttype=0 固定值
'''
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
bdstoken = re.findall(r'initPrefetch\(\'(.+?)\'\,', response.content.decode("utf-8"))[0]
url = 'https://pan.baidu.com/api/filemanager?bdstoken=%s&opera=rename&async=2&onnest=fail&channel=chunlei&web=1&app_id=250528\
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng==&clienttype=0' % bdstoken
form_data = {"filelist": "[{\"path\":\"%s\",\"newname\":\"%s\"}]" % (path, newname)}
response = self.session.post(url, headers=self.headers, data=form_data)
if(response.json()['errno'] == 0):
return {'errno': 0, 'err_msg': '重命名成功!'}
else:
return {'errno': 1, 'err_msg': '重命名失败!', 'info': response.json()}



'''
删除指定文件
0 删除成功;1 删除失败;
'''
def delete(self, path):
'''
构造重命名的URL:https://pan.baidu.com/api/filemanager?
bdstoken= 从首页可以获取到
&opera=delete 固定值
&async=2 固定值
&onnest=fail 固定值
&channel=chunlei 固定在
&web=1 固定值
&app_id=250528 固定值
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng== 固定值
&clienttype=0 固定值
'''
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
bdstoken = re.findall(r'initPrefetch\(\'(.+?)\'\,', response.content.decode("utf-8"))[0]
url = 'https://pan.baidu.com/api/filemanager?bdstoken=%s&opera=delete&async=2&onnest=fail&channel=chunlei&web=1&app_id=250528\
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng==&clienttype=0' % bdstoken
form_data = {"filelist": "[\"%s\"]" % path}
response = self.session.post(url, headers=self.headers, data=form_data)
if(response.json()['errno'] == 0):
return {'errno': 0, 'err_msg': '删除成功!'}
else:
return {'errno': 1, 'err_msg': '删除失败!', 'info': response.json()}



'''
移动文件至指定目录
0 删除成功;1 删除失败;
'''
def move(self, path, destination, newname=False):
'''
构造重命名的URL:https://pan.baidu.com/api/filemanager?
bdstoken= 从首页可以获取到
&opera=move 固定值
&async=2 固定值
&onnest=fail 固定值
&channel=chunlei 固定在
&web=1 固定值
&app_id=250528 固定值
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng== 固定值
&clienttype=0 固定值
'''
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
bdstoken = re.findall(r'initPrefetch\(\'(.+?)\'\,', response.content.decode("utf-8"))[0]
url = 'https://pan.baidu.com/api/filemanager?bdstoken=%s&opera=move&async=2&onnest=fail&channel=chunlei&web=1&app_id=250528\
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng==&clienttype=0' % bdstoken
if(not newname):
newname = path.split('/')[-1]
form_data = {"filelist": "[{\"path\":\"%s\",\"dest\":\"%s\",\"newname\":\"%s\"}]" % (path, destination, newname)}
response = self.session.post(url, headers=self.headers, data=form_data)
if(response.json()['errno'] == 0):
return {'errno': 0, 'err_msg': '移动成功!'}
else:
return {'errno': 1, 'err_msg': '移动失败!', 'info': response.json()}



'''
随机生成4位字符串
'''
@staticmethod
def generatePwd(n=4):
pwd= ""
for i in range(n):
temp = random.randrange(0,3)
if temp == 0:
ch = chr(random.randrange(ord('A'),ord('Z') + 1))
pwd += ch
elif temp == 1:
ch = chr(random.randrange(ord('a'),ord('z') + 1))
pwd += ch
else:
pwd = str((random.randrange(0,10)))
return pwd


'''
创建分享链接
fid_list为列表,例如:[1110768251780445]
0 创建成功;1 创建失败;
'''
def createShareLink(self, fid_list, period=0, pwd=False):
'''
构造重命名的URL:https://pan.baidu.com/share/set?
bdstoken= 从首页可以获取到
&channel=chunlei 固定在
&web=1 固定值
&app_id=250528 固定值
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng== 固定值
&clienttype=0 固定值
'''
response = self.session.get('https://pan.baidu.com/', headers=self.headers)
bdstoken = re.findall(r'initPrefetch\(\'(.+?)\'\,', response.content.decode("utf-8"))[0]
url = 'https://pan.baidu.com/share/set?bdstoken=%s&channel=chunlei&web=1&app_id=250528\
&logid=MTU4MTk0MzY0MTQwNzAuNDA0MzQxOTM0MzE2MzM4Ng==&clienttype=0' % bdstoken
if(not pwd):
pwd = self.generatePwd()
'''
schannel=4 不知道什么意思,固定为4
channel_list=[] 不知道什么意思,固定为[]
period=0 0表示永久,7表示7天
pwd=w4y5 分享链接的提取码,可自定义
fid_list=[1110768251780445] 分享文件的id列表,可调用getFileList方法获取文件列表,包含fs_id
'''
form_data = {
'schannel': 4,
'channel_list': '[]',
'period': period,
'pwd': pwd,
'fid_list': str(fid_list),
}
response = self.session.post(url, headers=self.headers, data=form_data)
if(response.json()['errno'] == 0):
return {'errno': 0, 'err_msg': '创建分享链接成功!', 'info': {'link': response.json()['link'], 'pwd': pwd}}
else:
return {'errno': 1, 'err_msg': '创建分享链接失败!', 'info': response.json()}

如何使用

需要先登录网页版的 获取cookie BDUSS,STOKEN 或者自己更改下 加个配置文件之类的 或者等笔者 有时间封装一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# coding="utf-8"
import sys
sys.path.append('/home/bxw/python')
from BaiDuPan import BaiDuPan
import time

def startSave():
bai_du_pan = BaiDuPan()
bai_du_pan.verifyCookie()
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), '开始执行保存至百度网盘')
try:
result = bai_du_pan.saveShare("https://pan.baidu.com/s/1MiXOm2pkWFBvQL3-qrocfw", "ybev", '/pdf')
print(result)
except Exception as e:
result = {'errno': -1}
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), '其他保存异常: ', e)
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), '全部执行完成!')


if __name__ == '__main__':
startSave()

保存分享的方法直接调用 saveShare
其他的方法还没测试,测试如果有问题后续更新