主要包含逻辑
- 支持进度条展示
- 支持断点续传
- 支持检测文件是否已经存在
- 支持检测老版本问题存在并做删除处理
代码实现
import os
import requests
# import wget
import fnmatch
from tqdm import tqdm
import time
import re
def get_cookie():
"""
从明道云拉取cookie信息
"""
apiurl = 'https://cooperation.XXX.com:443/api/v2/open/worksheet/getFilterRows'
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39"}
body = {
"appKey": "f7b8e6816d39a931",
"sign": "ODlkNTVhNDdjZDhjNmYwODhjYjExZTU4NGFmODFkZDQzZjRlNGMzMzJlODdhNzhmNTVjYmQ4ZTA1MzAzNzc3Mw==",
"worksheetId": "hxggzjxx",
"viewId": "634509562b5b0f8d7a182f39",
"pageSize": 5000,
"pageIndex": 1,
"filters": [
{
"controlId": "leibie",
"dataType": 2,
"spliceType": 1,
"filterType": 2,
"values": ["应用商店审核平台"]}]
}
res_data = requests.post(apiurl, json=body, headers=headers).json()['data']['rows']
for i in res_data:
if i['leibie'] == '应用商店审核平台' and i['jianmingcheng'] == 'cookie':
cookie = i['quzhi']
elif i['leibie'] == '应用商店审核平台' and i['jianmingcheng'] == 'Authorization':
Authorization = i['quzhi']
headers = {"Authorization": Authorization,
"Connection": "keep-alive",
"Cookie": cookie,
"Host": "appstore.XXX.com",
"Referer": "https://appstore.XXX.com/cms/",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39"
}
return headers
headers = get_cookie()
def getv23app_info():
"""
获取V23上上架的应用
"""
url = f'https://appstore.XXX.com/prod-api/store-admin-app/getAppList?pageNum=1&pageSize=4000&pkgInstallMode=1&app_name=&searchAppIds=&app_status=101&store_version=11&app_arch=4&appid=®ion=&app_mode=1&package_mode=&supWayland=0&appFrom='
res = requests.get(url, headers=headers).json()['rows']
res = sorted(res, key=lambda x: x['urge_upt_times'], reverse=True)
return res
def download_file_with_progress(url, output_path):
"""
下载并提供进度展示功能,支持断点续传
"""
local_size = 0
if os.path.exists(output_path):
local_size = os.path.getsize(output_path)
headers = {"Range": f"bytes={local_size}-"}
response = requests.get(url, headers=headers, stream=True)
total_size = int(response.headers.get('content-length', 0)) + local_size
block_size = 1024 # 1 Kibibyte
progress_bar = tqdm(total=total_size, initial=local_size, unit='iB', unit_scale=True)
with open(output_path, 'ab') as file:
for data in response.iter_content(block_size):
progress_bar.update(len(data))
file.write(data)
progress_bar.close()
if total_size != 0 and progress_bar.n != total_size:
print("ERROR: Something went wrong")
def download_app(appinfo):
"""
Check for apps that meet the community test criteria and get download links and app names
"""
app_name = appinfo['app_name']
appid = appinfo['appid']
appinfoid = appinfo['app_info_id']
appinfo_url = f'https://appstore.XXX.com/prod-api/store-admin-app/getAppDetail/{appinfoid}'
ressrc = requests.get(appinfo_url, headers=headers).json()['datas']
res = ressrc['appPackages']
for j in res:
if j['pkgArch'] in ['X86', 'x86', '全架构'] and '社区版V23' in j[
'supSysStr']: # Here is the filtered Community Edition app
download_url = f'https://home-store-img.XXX.com/{j["fileSaveKey"]}'
pkgVersion = j['pkgVersion']
download_name = f'{appid}_{app_name}_{pkgVersion}.deb'
download_name = re.sub(r'[:]', ".",download_name) # Some apps have colons in their version numbers, which need to be handled
# Check if the file already exists
if os.path.exists(download_name):
# Get file size on server
head_response = requests.head(download_url)
total_size = int(head_response.headers.get('content-length', 0))
# Get local file size
local_size = os.path.getsize(download_name)
if local_size == total_size:
print(f'{download_name} 已存在且完整,跳过下载。')
continue
else:
time.sleep(1)
local_size_now = os.path.getsize(download_name)
if local_size_now != local_size:
print(f'{download_name} 有其他程序在下载……')
continue
print(f'{download_name} 已存在但不完整,准备断点续传……')
else:
print(f'准备下载 {download_name} 应用')
download_file_with_progress(download_url, download_name)
print(f'{download_name} 应用下载完成!')
def main():
appinfo = getv23app_info()
for i in appinfo:
download_app(i)
if __name__ == '__main__':
main()