style(tiktok): 整理代码格式

This commit is contained in:
imgyh 2023-04-21 16:53:37 +08:00
parent 48fcf902be
commit 064ae7dc63
14 changed files with 1849 additions and 1816 deletions

View File

@ -83,6 +83,7 @@ class TikTok(object):
userVideoUrls.append(videoRealUrl) userVideoUrls.append(videoRealUrl)
return userVideoUrls return userVideoUrls
tk = TikTok() tk = TikTok()
# tk.oneVideoInfo() # tk.oneVideoInfo()
tk.userVideoInfo() tk.userVideoInfo()

View File

@ -48,10 +48,10 @@ class TikTok(object):
self.utils = Utils() self.utils = Utils()
self.result = Result() self.result = Result()
self.headers = { self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'referer': 'https://www.douyin.com/', 'referer': 'https://www.douyin.com/',
'accept-encoding': None, 'accept-encoding': None,
'Cookie': f"msToken={self.utils.generate_random_str(107)}; ttwid={self.utils.getttwid()}; odin_tt=324fb4ea4a89c0c05827e18a1ed9cf9bf8a17f7705fcc793fec935b637867e2a5a9b8168c885554d029919117a18ba69; passport_csrf_token=f61602fc63757ae0e4fd9d6bdcee4810;" 'Cookie': f"msToken={self.utils.generate_random_str(107)}; ttwid={self.utils.getttwid()}; odin_tt=324fb4ea4a89c0c05827e18a1ed9cf9bf8a17f7705fcc793fec935b637867e2a5a9b8168c885554d029919117a18ba69; passport_csrf_token=f61602fc63757ae0e4fd9d6bdcee4810;"
} }
# 用于设置重复请求某个接口的最大时间 # 用于设置重复请求某个接口的最大时间
self.timeout = 10 self.timeout = 10
@ -71,7 +71,6 @@ class TikTok(object):
# self.done_event = Event() # self.done_event = Event()
# signal.signal(signal.SIGINT, self.handle_sigint) # signal.signal(signal.SIGINT, self.handle_sigint)
# 从分享链接中提取网址 # 从分享链接中提取网址
def getShareLink(self, string): def getShareLink(self, string):
# findall() 查找匹配正则表达式的字符串 # findall() 查找匹配正则表达式的字符串
@ -145,7 +144,6 @@ class TikTok(object):
return key_type, key return key_type, key
def getAwemeInfoApi(self, aweme_id): def getAwemeInfoApi(self, aweme_id):
if aweme_id is None: if aweme_id is None:
return None return None
@ -205,7 +203,7 @@ class TikTok(object):
if end - start > self.timeout: if end - start > self.timeout:
# raise RuntimeError("重复请求该接口" + str(self.timeout) + "s, 仍然未获取到数据") # raise RuntimeError("重复请求该接口" + str(self.timeout) + "s, 仍然未获取到数据")
print("[ 提示 ]:重复请求该接口" + str(self.timeout) + "s, 仍然未获取到数据") print("[ 提示 ]:重复请求该接口" + str(self.timeout) + "s, 仍然未获取到数据")
return {},{} return {}, {}
# print("[ 警告 ]:接口未返回数据, 正在重新请求!\r") # print("[ 警告 ]:接口未返回数据, 正在重新请求!\r")
# 清空self.awemeDict # 清空self.awemeDict
@ -225,7 +223,6 @@ class TikTok(object):
return self.result.awemeDict, datadict return self.result.awemeDict, datadict
def getUserInfoApi(self, sec_uid, mode="post", count=35, max_cursor=0): def getUserInfoApi(self, sec_uid, mode="post", count=35, max_cursor=0):
if sec_uid is None: if sec_uid is None:
return None return None
@ -346,10 +343,10 @@ class TikTok(object):
awemeList.append(copy.deepcopy(self.result.awemeDict)) awemeList.append(copy.deepcopy(self.result.awemeDict))
if numflag: if numflag:
number-=1 number -= 1
if number==0: if number == 0:
break break
if numflag and number==0: if numflag and number == 0:
print("\r\n[ 提示 ]: [主页] 下指定数量作品数据获取完成...\r\n") print("\r\n[ 提示 ]: [主页] 下指定数量作品数据获取完成...\r\n")
break break
@ -399,7 +396,8 @@ class TikTok(object):
self.result.liveDict["cover"] = live_json['data']['data'][0]['cover']['url_list'][0] self.result.liveDict["cover"] = live_json['data']['data'][0]['cover']['url_list'][0]
# 头像 # 头像
self.result.liveDict["avatar"] = live_json['data']['data'][0]['owner']['avatar_thumb']['url_list'][0].replace("100x100", "1080x1080") self.result.liveDict["avatar"] = live_json['data']['data'][0]['owner']['avatar_thumb']['url_list'][0].replace(
"100x100", "1080x1080")
# 观看人数 # 观看人数
self.result.liveDict["user_count"] = live_json['data']['data'][0]['user_count_str'] self.result.liveDict["user_count"] = live_json['data']['data'][0]['user_count_str']
@ -419,19 +417,20 @@ class TikTok(object):
try: try:
# 分区 # 分区
self.result.liveDict["partition"] = live_json['data']['partition_road_map']['partition']['title'] self.result.liveDict["partition"] = live_json['data']['partition_road_map']['partition']['title']
self.result.liveDict["sub_partition"] = live_json['data']['partition_road_map']['sub_partition']['partition'][ self.result.liveDict["sub_partition"] = \
live_json['data']['partition_road_map']['sub_partition']['partition'][
'title'] 'title']
except Exception as e: except Exception as e:
self.result.liveDict["partition"] = '' self.result.liveDict["partition"] = ''
self.result.liveDict["sub_partition"] = '' self.result.liveDict["sub_partition"] = ''
flv = [] flv = []
for i, f in enumerate(self.result.liveDict["flv_pull_url"].keys()): for i, f in enumerate(self.result.liveDict["flv_pull_url"].keys()):
flv.append(f) flv.append(f)
self.result.liveDict["flv_pull_url0"] = self.result.liveDict["flv_pull_url"][flv[0]].replace("http://", "https://") self.result.liveDict["flv_pull_url0"] = self.result.liveDict["flv_pull_url"][flv[0]].replace("http://",
"https://")
return self.result.liveDict, live_json return self.result.liveDict, live_json
@ -477,7 +476,8 @@ class TikTok(object):
self.result.liveDict["cover"] = live_json['data']['data'][0]['cover']['url_list'][0] self.result.liveDict["cover"] = live_json['data']['data'][0]['cover']['url_list'][0]
# 头像 # 头像
self.result.liveDict["avatar"] = live_json['data']['data'][0]['owner']['avatar_thumb']['url_list'][0].replace("100x100", "1080x1080") self.result.liveDict["avatar"] = live_json['data']['data'][0]['owner']['avatar_thumb']['url_list'][0].replace(
"100x100", "1080x1080")
# 观看人数 # 观看人数
self.result.liveDict["user_count"] = live_json['data']['data'][0]['user_count_str'] self.result.liveDict["user_count"] = live_json['data']['data'][0]['user_count_str']
@ -497,7 +497,8 @@ class TikTok(object):
try: try:
# 分区 # 分区
self.result.liveDict["partition"] = live_json['data']['partition_road_map']['partition']['title'] self.result.liveDict["partition"] = live_json['data']['partition_road_map']['partition']['title']
self.result.liveDict["sub_partition"] = live_json['data']['partition_road_map']['sub_partition']['partition'][ self.result.liveDict["sub_partition"] = \
live_json['data']['partition_road_map']['sub_partition']['partition'][
'title'] 'title']
except Exception as e: except Exception as e:
self.result.liveDict["partition"] = '' self.result.liveDict["partition"] = ''
@ -516,7 +517,8 @@ class TikTok(object):
rate = int(input('[ 🎬 ]输入数字选择推流清晰度:')) rate = int(input('[ 🎬 ]输入数字选择推流清晰度:'))
self.result.liveDict["flv_pull_url0"] = self.result.liveDict["flv_pull_url"][flv[rate]].replace("http://", "https://") self.result.liveDict["flv_pull_url0"] = self.result.liveDict["flv_pull_url"][flv[rate]].replace("http://",
"https://")
# 显示清晰度列表 # 显示清晰度列表
print('[ %s ]:%s' % (flv[rate], self.result.liveDict["flv_pull_url"][flv[rate]])) print('[ %s ]:%s' % (flv[rate], self.result.liveDict["flv_pull_url"][flv[rate]]))
@ -544,7 +546,6 @@ class TikTok(object):
if end - start > self.timeout: if end - start > self.timeout:
return None return None
for aweme in datadict["aweme_list"]: for aweme in datadict["aweme_list"]:
# 清空self.awemeDict # 清空self.awemeDict
@ -672,13 +673,12 @@ class TikTok(object):
return None return None
for mix in datadict["mix_infos"]: for mix in datadict["mix_infos"]:
mixIdNameDict={} mixIdNameDict = {}
mixIdNameDict["https://www.douyin.com/collection/" + mix["mix_id"]] = mix["mix_name"] mixIdNameDict["https://www.douyin.com/collection/" + mix["mix_id"]] = mix["mix_name"]
mixIdlist.append(mixIdNameDict) mixIdlist.append(mixIdNameDict)
return mixIdlist, datadict, datadict["cursor"], datadict["has_more"] return mixIdlist, datadict, datadict["cursor"], datadict["has_more"]
def getUserAllMixInfo(self, sec_uid, count=35, number=0): def getUserAllMixInfo(self, sec_uid, count=35, number=0):
print('[ 提示 ]:正在请求的用户 id = %s\r\n' % sec_uid) print('[ 提示 ]:正在请求的用户 id = %s\r\n' % sec_uid)
if sec_uid is None: if sec_uid is None:
@ -762,7 +762,6 @@ class TikTok(object):
if end - start > self.timeout: if end - start > self.timeout:
return None return None
for aweme in datadict["aweme_list"]: for aweme in datadict["aweme_list"]:
# 清空self.awemeDict # 清空self.awemeDict
self.result.clearDict(self.result.awemeDict) self.result.clearDict(self.result.awemeDict)
@ -924,7 +923,7 @@ class TikTok(object):
try: try:
# 使用作品 创建时间+描述 当文件夹 # 使用作品 创建时间+描述 当文件夹
file_name = awemeDict["create_time"] + "_" + self.utils.replaceStr(awemeDict["desc"]) file_name = awemeDict["create_time"] + "_" + self.utils.replaceStr(awemeDict["desc"])
aweme_path = os.path.join(savePath, file_name) aweme_path = os.path.join(savePath, file_name)
if not os.path.exists(aweme_path): if not os.path.exists(aweme_path):
os.mkdir(aweme_path) os.mkdir(aweme_path)
@ -937,7 +936,7 @@ class TikTok(object):
f.write(json.dumps(awemeDict, ensure_ascii=False, indent=2)) f.write(json.dumps(awemeDict, ensure_ascii=False, indent=2))
f.close() f.close()
except Exception as e: except Exception as e:
print("[ 错误 ]:保存 result.json 失败... 作品名: " + file_name +"\r\n") print("[ 错误 ]:保存 result.json 失败... 作品名: " + file_name + "\r\n")
desc = file_name[:30] desc = file_name[:30]
# 下载 视频 # 下载 视频
@ -958,7 +957,7 @@ class TikTok(object):
self.alltask.append( self.alltask.append(
self.pool.submit(self.progressBarDownload, url, video_path, "[ 视频 ]:" + desc)) self.pool.submit(self.progressBarDownload, url, video_path, "[ 视频 ]:" + desc))
except Exception as e: except Exception as e:
print("[ 警告 ]:视频下载失败,请重试... 作品名: " + file_name +"\r\n") print("[ 警告 ]:视频下载失败,请重试... 作品名: " + file_name + "\r\n")
# 下载 图集 # 下载 图集
if awemeDict["awemeType"] == 1: if awemeDict["awemeType"] == 1:
@ -978,7 +977,7 @@ class TikTok(object):
self.alltask.append( self.alltask.append(
self.pool.submit(self.progressBarDownload, url, image_path, "[ 图集 ]:" + desc)) self.pool.submit(self.progressBarDownload, url, image_path, "[ 图集 ]:" + desc))
except Exception as e: except Exception as e:
print("[ 警告 ]:图片下载失败,请重试... 作品名: " + file_name +"\r\n") print("[ 警告 ]:图片下载失败,请重试... 作品名: " + file_name + "\r\n")
# 下载 音乐 # 下载 音乐
if music: if music:
@ -999,7 +998,7 @@ class TikTok(object):
self.alltask.append( self.alltask.append(
self.pool.submit(self.progressBarDownload, url, music_path, "[ 原声 ]:" + desc)) self.pool.submit(self.progressBarDownload, url, music_path, "[ 原声 ]:" + desc))
except Exception as e: except Exception as e:
print("[ 警告 ]:音乐(原声)下载失败,请重试... 作品名: " + file_name +"\r\n") print("[ 警告 ]:音乐(原声)下载失败,请重试... 作品名: " + file_name + "\r\n")
# 下载 cover # 下载 cover
if cover and awemeDict["awemeType"] == 0: if cover and awemeDict["awemeType"] == 0:
@ -1019,7 +1018,7 @@ class TikTok(object):
self.alltask.append( self.alltask.append(
self.pool.submit(self.progressBarDownload, url, cover_path, "[ 封面 ]:" + desc)) self.pool.submit(self.progressBarDownload, url, cover_path, "[ 封面 ]:" + desc))
except Exception as e: except Exception as e:
print("[ 警告 ]:cover下载失败,请重试... 作品名: " + file_name +"\r\n") print("[ 警告 ]:cover下载失败,请重试... 作品名: " + file_name + "\r\n")
# 下载 avatar # 下载 avatar
if avatar: if avatar:
@ -1039,7 +1038,7 @@ class TikTok(object):
self.alltask.append( self.alltask.append(
self.pool.submit(self.progressBarDownload, url, avatar_path, "[ 头像 ]:" + desc)) self.pool.submit(self.progressBarDownload, url, avatar_path, "[ 头像 ]:" + desc))
except Exception as e: except Exception as e:
print("[ 警告 ]:avatar下载失败,请重试... 作品名: " + file_name +"\r\n") print("[ 警告 ]:avatar下载失败,请重试... 作品名: " + file_name + "\r\n")
except Exception as e: except Exception as e:
print("[ 错误 ]:下载作品时出错\r\n") print("[ 错误 ]:下载作品时出错\r\n")
@ -1093,8 +1092,8 @@ class TikTok(object):
# end = time.time() # 结束时间 # end = time.time() # 结束时间
# print('\n' + '[下载完成]:耗时: %d分钟%d秒\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间 # print('\n' + '[下载完成]:耗时: %d分钟%d秒\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间
def userDownload(self, awemeList: list, music=True, cover=True, avatar=True, resjson=True, savePath=os.getcwd(),
def userDownload(self, awemeList: list, music=True, cover=True, avatar=True, resjson=True, savePath=os.getcwd(), thread=5): thread=5):
if awemeList is None: if awemeList is None:
return return
if not os.path.exists(savePath): if not os.path.exists(savePath):
@ -1106,7 +1105,8 @@ class TikTok(object):
start = time.time() # 开始时间 start = time.time() # 开始时间
for aweme in awemeList: for aweme in awemeList:
self.awemeDownload(awemeDict=aweme, music=music, cover=cover, avatar=avatar, resjson=resjson, savePath=savePath) self.awemeDownload(awemeDict=aweme, music=music, cover=cover, avatar=avatar, resjson=resjson,
savePath=savePath)
# time.sleep(0.5) # time.sleep(0.5)
wait(self.alltask, return_when=ALL_COMPLETED) wait(self.alltask, return_when=ALL_COMPLETED)
@ -1116,7 +1116,8 @@ class TikTok(object):
self.isdwownload = True self.isdwownload = True
# 下载上一步失败的 # 下载上一步失败的
for aweme in awemeList: for aweme in awemeList:
self.awemeDownload(awemeDict=aweme, music=music, cover=cover, avatar=avatar, resjson=resjson, savePath=savePath) self.awemeDownload(awemeDict=aweme, music=music, cover=cover, avatar=avatar, resjson=resjson,
savePath=savePath)
# time.sleep(0.5) # time.sleep(0.5)
wait(self.alltask, return_when=ALL_COMPLETED) wait(self.alltask, return_when=ALL_COMPLETED)
@ -1126,5 +1127,6 @@ class TikTok(object):
end = time.time() # 结束时间 end = time.time() # 结束时间
print('\n' + '[下载完成]:耗时: %d分钟%d\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间 print('\n' + '[下载完成]:耗时: %d分钟%d\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间
if __name__ == "__main__": if __name__ == "__main__":
pass pass

View File

@ -42,6 +42,7 @@ configModel = {
} }
def argument(): def argument():
parser = argparse.ArgumentParser(description='抖音批量下载工具 使用帮助') parser = argparse.ArgumentParser(description='抖音批量下载工具 使用帮助')
parser.add_argument("--cmd", "-C", help="使用命令行(True)或者配置文件(False), 默认为False", parser.add_argument("--cmd", "-C", help="使用命令行(True)或者配置文件(False), 默认为False",
@ -50,7 +51,7 @@ def argument():
help="作品(视频或图集)、直播、合集、音乐集合、个人主页的分享链接或者电脑浏览器网址, 可以设置多个链接(删除文案, 保证只有URL, https://v.douyin.com/kcvMpuN/ 或者 https://www.douyin.com/开头的)", help="作品(视频或图集)、直播、合集、音乐集合、个人主页的分享链接或者电脑浏览器网址, 可以设置多个链接(删除文案, 保证只有URL, https://v.douyin.com/kcvMpuN/ 或者 https://www.douyin.com/开头的)",
type=str, required=False, default=[], action="append") type=str, required=False, default=[], action="append")
parser.add_argument("--path", "-p", help="下载保存位置, 默认当前文件位置", parser.add_argument("--path", "-p", help="下载保存位置, 默认当前文件位置",
type=str, required=False,default=os.getcwd()) type=str, required=False, default=os.getcwd())
parser.add_argument("--music", "-m", help="是否下载视频中的音乐(True/False), 默认为True", parser.add_argument("--music", "-m", help="是否下载视频中的音乐(True/False), 默认为True",
type=Utils().str2bool, required=False, default=True) type=Utils().str2bool, required=False, default=True)
parser.add_argument("--cover", "-c", help="是否下载视频的封面(True/False), 默认为True, 当下载视频时有效", parser.add_argument("--cover", "-c", help="是否下载视频的封面(True/False), 默认为True, 当下载视频时有效",
@ -82,12 +83,13 @@ def argument():
return args return args
def yamlConfig(): def yamlConfig():
curPath = os.path.dirname(os.path.realpath(sys.argv[0])) curPath = os.path.dirname(os.path.realpath(sys.argv[0]))
yamlPath = os.path.join(curPath, "config.yml") yamlPath = os.path.join(curPath, "config.yml")
f = open(yamlPath, 'r', encoding='utf-8') f = open(yamlPath, 'r', encoding='utf-8')
cfg = f.read() cfg = f.read()
configDict = yaml.load(stream=cfg,Loader=yaml.FullLoader) configDict = yaml.load(stream=cfg, Loader=yaml.FullLoader)
try: try:
if configDict["link"] != None: if configDict["link"] != None:
@ -159,7 +161,7 @@ def yamlConfig():
cookiekey = configDict["cookies"].keys() cookiekey = configDict["cookies"].keys()
cookieStr = "" cookieStr = ""
for i in cookiekey: for i in cookiekey:
cookieStr = cookieStr + i + "=" + configDict["cookies"][i] + "; " cookieStr = cookieStr + i + "=" + configDict["cookies"][i] + "; "
configModel["cookie"] = cookieStr configModel["cookie"] = cookieStr
except Exception as e: except Exception as e:
pass pass
@ -184,7 +186,7 @@ def main():
configModel["avatar"] = args.avatar configModel["avatar"] = args.avatar
configModel["json"] = args.json configModel["json"] = args.json
if args.mode == None or args.mode == []: if args.mode == None or args.mode == []:
args.mode=[] args.mode = []
args.mode.append("post") args.mode.append("post")
configModel["mode"] = list(set(args.mode)) configModel["mode"] = list(set(args.mode))
configModel["number"]["post"] = args.postnumber configModel["number"]["post"] = args.postnumber
@ -215,7 +217,7 @@ def main():
key_type, key = tk.getKey(url) key_type, key = tk.getKey(url)
if key_type == "user": if key_type == "user":
print("[ 提示 ]:正在请求用户主页下作品\r\n") print("[ 提示 ]:正在请求用户主页下作品\r\n")
userPath = os.path.join(configModel["path"], "user_"+key) userPath = os.path.join(configModel["path"], "user_" + key)
if not os.path.exists(userPath): if not os.path.exists(userPath):
os.mkdir(userPath) os.mkdir(userPath)
@ -242,13 +244,15 @@ def main():
modePath = os.path.join(userPath, mode) modePath = os.path.join(userPath, mode)
if not os.path.exists(modePath): if not os.path.exists(modePath):
os.mkdir(modePath) os.mkdir(modePath)
tk.userDownload(awemeList=datalist, music=configModel["music"], cover=configModel["cover"], tk.userDownload(awemeList=datalist, music=configModel["music"],
cover=configModel["cover"],
avatar=configModel["avatar"], resjson=configModel["json"], avatar=configModel["avatar"], resjson=configModel["json"],
savePath=os.path.join(modePath, mix_file_name), thread=configModel["thread"]) savePath=os.path.join(modePath, mix_file_name),
thread=configModel["thread"])
print(f'[ 提示 ]:合集 [{mixIdNameDict[mix_id]}] 中的作品下载完成\r\n') print(f'[ 提示 ]:合集 [{mixIdNameDict[mix_id]}] 中的作品下载完成\r\n')
elif key_type == "mix": elif key_type == "mix":
print("[ 提示 ]:正在请求单个合集下作品\r\n") print("[ 提示 ]:正在请求单个合集下作品\r\n")
datalist = tk.getMixInfo(key,35, configModel["number"]["mix"]) datalist = tk.getMixInfo(key, 35, configModel["number"]["mix"])
if datalist is not None and datalist != []: if datalist is not None and datalist != []:
mixPath = os.path.join(configModel["path"], "mix_" + key) mixPath = os.path.join(configModel["path"], "mix_" + key)
if not os.path.exists(mixPath): if not os.path.exists(mixPath):
@ -258,7 +262,7 @@ def main():
savePath=mixPath, thread=configModel["thread"]) savePath=mixPath, thread=configModel["thread"])
elif key_type == "music": elif key_type == "music":
print("[ 提示 ]:正在请求音乐(原声)下作品\r\n") print("[ 提示 ]:正在请求音乐(原声)下作品\r\n")
datalist = tk.getMusicInfo(key,35, configModel["number"]["music"]) datalist = tk.getMusicInfo(key, 35, configModel["number"]["music"])
if datalist is not None and datalist != []: if datalist is not None and datalist != []:
musicPath = os.path.join(configModel["path"], "music_" + key) musicPath = os.path.join(configModel["path"], "music_" + key)
if not os.path.exists(musicPath): if not os.path.exists(musicPath):
@ -281,19 +285,20 @@ def main():
elif key_type == "live": elif key_type == "live":
print("[ 提示 ]:正在进行直播解析\r\n") print("[ 提示 ]:正在进行直播解析\r\n")
live_json = tk.getLiveInfo(key) live_json = tk.getLiveInfo(key)
if configModel["json"]: if configModel["json"]:
livePath = os.path.join(configModel["path"], "live") livePath = os.path.join(configModel["path"], "live")
if not os.path.exists(livePath): if not os.path.exists(livePath):
os.mkdir(livePath) os.mkdir(livePath)
live_file_name = utils.replaceStr(key + live_json["nickname"]) live_file_name = utils.replaceStr(key + live_json["nickname"])
# 保存获取到json # 保存获取到json
print("[ 提示 ]:正在保存获取到的信息到result.json\r\n") print("[ 提示 ]:正在保存获取到的信息到result.json\r\n")
with open(os.path.join(livePath, live_file_name + ".json"), "w", encoding='utf-8') as f: with open(os.path.join(livePath, live_file_name + ".json"), "w", encoding='utf-8') as f:
f.write(json.dumps(live_json, ensure_ascii=False, indent=2)) f.write(json.dumps(live_json, ensure_ascii=False, indent=2))
f.close() f.close()
end = time.time() # 结束时间 end = time.time() # 结束时间
print('\n' + '[下载完成]:总耗时: %d分钟%d\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间 print('\n' + '[下载完成]:总耗时: %d分钟%d\n' % (int((end - start) / 60), ((end - start) % 60))) # 输出下载用时时间
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -16,6 +16,7 @@ Change Log :
import time import time
import copy import copy
class Result(object): class Result(object):
def __init__(self): def __init__(self):
# 作者信息 # 作者信息

View File

@ -15,6 +15,7 @@ Change Log :
import TikTokUtils import TikTokUtils
from TikTok import TikTok from TikTok import TikTok
def getAwemeInfo(): def getAwemeInfo():
share_link_video = "3.56 uSy:/ 复制打开抖音,看看【小透明的作品】没有女朋友就用我的吧哈哈哈哈 # 表情包锁屏 https://v.douyin.com/BugmVVD/" share_link_video = "3.56 uSy:/ 复制打开抖音,看看【小透明的作品】没有女朋友就用我的吧哈哈哈哈 # 表情包锁屏 https://v.douyin.com/BugmVVD/"
share_link_pic = "8.20 MJI:/ 复制打开抖音,看看【舍溪的图文作品】我又来放图集啦~还有你们要的小可爱大图也放啦~# ... https://v.douyin.com/BugrFTN/" share_link_pic = "8.20 MJI:/ 复制打开抖音,看看【舍溪的图文作品】我又来放图集啦~还有你们要的小可爱大图也放啦~# ... https://v.douyin.com/BugrFTN/"
@ -25,6 +26,7 @@ def getAwemeInfo():
datanew, dataraw = tk.getAwemeInfo(key) datanew, dataraw = tk.getAwemeInfo(key)
print(datanew) print(datanew)
def getUserInfo(): def getUserInfo():
share_link_post = "1- 长按复制此条消息打开抖音搜索查看TA的更多作品。 https://v.douyin.com/BupCppt/" share_link_post = "1- 长按复制此条消息打开抖音搜索查看TA的更多作品。 https://v.douyin.com/BupCppt/"
share_link_like = "2- 长按复制此条消息打开抖音搜索查看TA的更多作品。 https://v.douyin.com/BusJrfr/" share_link_like = "2- 长按复制此条消息打开抖音搜索查看TA的更多作品。 https://v.douyin.com/BusJrfr/"
@ -35,6 +37,7 @@ def getUserInfo():
awemeList = tk.getUserInfo(key, mode="like", count=35) awemeList = tk.getUserInfo(key, mode="like", count=35)
print(awemeList) print(awemeList)
def getLiveInfo(): def getLiveInfo():
live_link = "https://live.douyin.com/40768897856" live_link = "https://live.douyin.com/40768897856"
tk = TikTok() tk = TikTok()
@ -44,6 +47,7 @@ def getLiveInfo():
live_json = tk.getLiveInfo(key) live_json = tk.getLiveInfo(key)
print(live_json) print(live_json)
def getMixInfo(): def getMixInfo():
mix_link = 'https://v.douyin.com/B3J63Le/' mix_link = 'https://v.douyin.com/B3J63Le/'
tk = TikTok() tk = TikTok()
@ -53,6 +57,7 @@ def getMixInfo():
awemeList = tk.getMixInfo(key, count=35) awemeList = tk.getMixInfo(key, count=35)
print(len(awemeList)) print(len(awemeList))
def getUserAllMixInfo(): def getUserAllMixInfo():
user_all_mix_link = 'https://v.douyin.com/B38oovu/' user_all_mix_link = 'https://v.douyin.com/B38oovu/'
tk = TikTok() tk = TikTok()
@ -62,33 +67,37 @@ def getUserAllMixInfo():
mixIdNameDict = tk.getUserAllMixInfo(key, count=35) mixIdNameDict = tk.getUserAllMixInfo(key, count=35)
print(mixIdNameDict) print(mixIdNameDict)
def getMusicInfo(): def getMusicInfo():
music_link = 'https://v.douyin.com/S6YMNXs/' music_link = 'https://v.douyin.com/S6YMNXs/'
tk = TikTok() tk = TikTok()
url = tk.getShareLink(music_link) url = tk.getShareLink(music_link)
key_type, key = tk.getKey(url) key_type, key = tk.getKey(url)
awemeList = tk.getMusicInfo(key,count=35) awemeList = tk.getMusicInfo(key, count=35)
print(len(awemeList)) print(len(awemeList))
def test(): def test():
utils=TikTokUtils.Utils() utils = TikTokUtils.Utils()
user_all_mix_link = 'https://www.douyin.com/aweme/v1/web/aweme/favorite/?'+\ user_all_mix_link = 'https://www.douyin.com/aweme/v1/web/aweme/favorite/?' + \
utils.getXbogus(url='device_platform=webapp&aid=6383&sec_user_id=MS4wLjABAAAAjQn6ONfaGgUpk0Q1ep8dPiD3W4T_lxTJmemfy3MTJ64&max_cursor=1676441180000&count=10') utils.getXbogus(
url='device_platform=webapp&aid=6383&sec_user_id=MS4wLjABAAAAjQn6ONfaGgUpk0Q1ep8dPiD3W4T_lxTJmemfy3MTJ64&max_cursor=1676441180000&count=10')
headers = { headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
'referer': 'https://www.douyin.com/', 'referer': 'https://www.douyin.com/',
'accept-encoding': None, 'accept-encoding': None,
'Cookie': 'ttwid=1|oLudm-Hi5ikxQQhmAnv4Km4LjwwvLa4Qk_JGrKffuYU|1681878460|b0f581d97797bb67d2260bf92d65e8808b90713afc08bf5d8100f571fd70a275; passport_csrf_token=570d671dcd8d8598fcde4c3f7c99664d; passport_csrf_token_default=570d671dcd8d8598fcde4c3f7c99664d; s_v_web_id=verify_lgn70gzw_sAVtjJdD_Clyk_43UL_8M9L_6JiTtPC2TyU0; n_mh=vrLGYVtwqutbPLOGNTDUGahwaD9AyYjn4iVvAO2Xt0s; sso_uid_tt=92e014dfb6653bdc319ecc6a6ceea870; sso_uid_tt_ss=92e014dfb6653bdc319ecc6a6ceea870; toutiao_sso_user=d0bd8d5cc0f75420799903572941ce83; toutiao_sso_user_ss=d0bd8d5cc0f75420799903572941ce83; passport_auth_status=5c576b088f4a19448eb4efd7aaeb7c5e,; passport_auth_status_ss=5c576b088f4a19448eb4efd7aaeb7c5e,; uid_tt=564215aecc985785d033c9e4c9d00fc4; uid_tt_ss=564215aecc985785d033c9e4c9d00fc4; sid_tt=f14390d924c81856fde84b1cd534bf09; sessionid=f14390d924c81856fde84b1cd534bf09; sessionid_ss=f14390d924c81856fde84b1cd534bf09; odin_tt=0aa1c100d17bf3541dce9e8dd62c6353302b8abaaa0a5998d5c437313feb245d8f7b6391a69772e4afa7d3c718878837; passport_assist_user=CjwC3fi9JyApG4DN-HiFI6n5FcGAdzNDT29nR-nSDJYAVfqh2BYI77qdTN2GRfgagkYLRi1wxNp1akHBwGcaSAo8XDkNT-UWnkFmc_0eXMYCb8OIh4G_YnH8pylwwdfS-7PCTekX3trj0JyENUVWLWFxnKuG5HhSS4FB2CtxEJ7yrg0Yia_WVCIBA9bY7IU=; sid_ucp_sso_v1=1.0.0-KDc0NmY3NzA5ZWFhNzI2YzMyOWMxMDMwNjAwMDg3YzRjYzg3ZjlhODcKHQjG-7zT9QEQ5dv9oQYY7zEgDDCL_7nMBTgGQPQHGgJscSIgZDBiZDhkNWNjMGY3NTQyMDc5OTkwMzU3Mjk0MWNlODM; ssid_ucp_sso_v1=1.0.0-KDc0NmY3NzA5ZWFhNzI2YzMyOWMxMDMwNjAwMDg3YzRjYzg3ZjlhODcKHQjG-7zT9QEQ5dv9oQYY7zEgDDCL_7nMBTgGQPQHGgJscSIgZDBiZDhkNWNjMGY3NTQyMDc5OTkwMzU3Mjk0MWNlODM; publish_badge_show_info="0,0,0,1681878505305"; LOGIN_STATUS=1; store-region=cn-sc; store-region-src=uid; sid_guard=f14390d924c81856fde84b1cd534bf09|1681878504|5183998|Sun,+18-Jun-2023+04:28:22+GMT; sid_ucp_v1=1.0.0-KGY5OGQ3OTQ4YmVkYzczODgzYzM0MmJmOWYxMzhkMDliMTc5NGI3NjMKGQjG-7zT9QEQ6Nv9oQYY7zEgDDgGQPQHSAQaAmxmIiBmMTQzOTBkOTI0YzgxODU2ZmRlODRiMWNkNTM0YmYwOQ; ssid_ucp_v1=1.0.0-KGY5OGQ3OTQ4YmVkYzczODgzYzM0MmJmOWYxMzhkMDliMTc5NGI3NjMKGQjG-7zT9QEQ6Nv9oQYY7zEgDDgGQPQHSAQaAmxmIiBmMTQzOTBkOTI0YzgxODU2ZmRlODRiMWNkNTM0YmYwOQ; download_guide="3/20230419"; pwa2="3|0"; FOLLOW_NUMBER_YELLOW_POINT_INFO="MS4wLjABAAAA-jD2lukp--I21BF8VQsmYUqJDbj3FmU-kGQTHl2y1Cw/1681920000000/0/0/1681900423333"; __ac_nonce=0644234d60042cacebbb6; __ac_signature=_02B4Z6wo00f01eZN0dAAAIDAhUcRuQz7dNHmbdVAAB3TRUC7i8VqXQejR8jv-D8UggBx1MBLH564PE.cCZf00m7Cw640CNUvcc5jJfhgn8u5FhvVndykvwbQb.HEpSfGN-8eqql7GpuGZJ8f1d; strategyABtestKey="1682060514.261"; passport_fe_beating_status=true; csrf_session_id=405b0ec4f6338a5d893a5f14f6fd1a64; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtY2xpZW50LWNlcnQiOiItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNGRENDQWJxZ0F3SUJBZ0lVR1ljQ3FuQUh0UUJBZm5WWkYxQW84cUtjY2Zrd0NnWUlLb1pJemowRUF3SXdcbk1URUxNQWtHQTFVRUJoTUNRMDR4SWpBZ0JnTlZCQU1NR1hScFkydGxkRjluZFdGeVpGOWpZVjlsWTJSellWOHlcbk5UWXdIaGNOTWpNd016STNNRE15T0RBeldoY05Nek13TXpJM01URXlPREF6V2pBbk1Rc3dDUVlEVlFRR0V3SkRcblRqRVlNQllHQTFVRUF3d1BZbVJmZEdsamEyVjBYMmQxWVhKa01Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERcbkFRY0RRZ0FFNmZ1Z3d0MEJnZUh5akVub1FvNWtXUS9qc2daTTV1YXBiNTQ4KytTV0dRSjMwb2lSTHNtYlVFSUZcblFIYzh3UEthZzZmdXNPTm91WncxOEdNYm5vTStwNk9CdVRDQnRqQU9CZ05WSFE4QkFmOEVCQU1DQmFBd01RWURcblZSMGxCQ293S0FZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREF3WUlLd1lCQlFVSEF3UXdcbktRWURWUjBPQkNJRUlPV3Y3d01ZUGhoeUNPL2ZwenJGNDJNeEQ4ZGIzN0YyTDgxaW8zVTVlVFpaTUNzR0ExVWRcbkl3UWtNQ0tBSURLbForcU9aRWdTamN4T1RVQjdjeFNiUjIxVGVxVFJnTmQ1bEpkN0lrZURNQmtHQTFVZEVRUVNcbk1CQ0NEbmQzZHk1a2IzVjVhVzR1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lCbm9xRDBRbVdUSlNLOVNcbkFZRjJ6YkljYzBsZjFRMDVTUGxXMURDQ0FMVUpBaUVBazJFRWpKdkdFRnl0YzBWbXRoRTA5bFpGeFFkUmlGN21cbk9pdE5IZzBOZUJrPVxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIn0=; msToken=qSfWwAdwksuBS5wmQAvpzUsf2ovkFFKefOLSvZDKA1Z_FX7ith-wCknpVQB08kft4ISWp00GHeQBaPwV9tcWJq6xBC-mPnQKNjBVINeOQGvFtSdsfacWMtWpa8x1RJE=; FOLLOW_LIVE_POINT_INFO="MS4wLjABAAAA-jD2lukp--I21BF8VQsmYUqJDbj3FmU-kGQTHl2y1Cw/1682092800000/0/0/1682061497980"; msToken=jDwC5gjTRXV6hrFvGMG-AkOBXHGrt_Mp5NaltB1upOUm0aQnZ7sy7qlSEn2tQbGHShp2X7ayNMDQQlPekSTV9MkxBv56LR9zepTlYNOoqbH_RdjDvbl-MZDrmui3OEE=; tt_scid=hERl4ibL-B89BGXb9wUfsmVkQh-G2dvL2wI0QvEDYLooFsvwoz.q6J4ZA0WErn0Tb9fb; home_can_add_dy_2_desktop="1"' } 'Cookie': 'ttwid=1|oLudm-Hi5ikxQQhmAnv4Km4LjwwvLa4Qk_JGrKffuYU|1681878460|b0f581d97797bb67d2260bf92d65e8808b90713afc08bf5d8100f571fd70a275; passport_csrf_token=570d671dcd8d8598fcde4c3f7c99664d; passport_csrf_token_default=570d671dcd8d8598fcde4c3f7c99664d; s_v_web_id=verify_lgn70gzw_sAVtjJdD_Clyk_43UL_8M9L_6JiTtPC2TyU0; n_mh=vrLGYVtwqutbPLOGNTDUGahwaD9AyYjn4iVvAO2Xt0s; sso_uid_tt=92e014dfb6653bdc319ecc6a6ceea870; sso_uid_tt_ss=92e014dfb6653bdc319ecc6a6ceea870; toutiao_sso_user=d0bd8d5cc0f75420799903572941ce83; toutiao_sso_user_ss=d0bd8d5cc0f75420799903572941ce83; passport_auth_status=5c576b088f4a19448eb4efd7aaeb7c5e,; passport_auth_status_ss=5c576b088f4a19448eb4efd7aaeb7c5e,; uid_tt=564215aecc985785d033c9e4c9d00fc4; uid_tt_ss=564215aecc985785d033c9e4c9d00fc4; sid_tt=f14390d924c81856fde84b1cd534bf09; sessionid=f14390d924c81856fde84b1cd534bf09; sessionid_ss=f14390d924c81856fde84b1cd534bf09; odin_tt=0aa1c100d17bf3541dce9e8dd62c6353302b8abaaa0a5998d5c437313feb245d8f7b6391a69772e4afa7d3c718878837; passport_assist_user=CjwC3fi9JyApG4DN-HiFI6n5FcGAdzNDT29nR-nSDJYAVfqh2BYI77qdTN2GRfgagkYLRi1wxNp1akHBwGcaSAo8XDkNT-UWnkFmc_0eXMYCb8OIh4G_YnH8pylwwdfS-7PCTekX3trj0JyENUVWLWFxnKuG5HhSS4FB2CtxEJ7yrg0Yia_WVCIBA9bY7IU=; sid_ucp_sso_v1=1.0.0-KDc0NmY3NzA5ZWFhNzI2YzMyOWMxMDMwNjAwMDg3YzRjYzg3ZjlhODcKHQjG-7zT9QEQ5dv9oQYY7zEgDDCL_7nMBTgGQPQHGgJscSIgZDBiZDhkNWNjMGY3NTQyMDc5OTkwMzU3Mjk0MWNlODM; ssid_ucp_sso_v1=1.0.0-KDc0NmY3NzA5ZWFhNzI2YzMyOWMxMDMwNjAwMDg3YzRjYzg3ZjlhODcKHQjG-7zT9QEQ5dv9oQYY7zEgDDCL_7nMBTgGQPQHGgJscSIgZDBiZDhkNWNjMGY3NTQyMDc5OTkwMzU3Mjk0MWNlODM; publish_badge_show_info="0,0,0,1681878505305"; LOGIN_STATUS=1; store-region=cn-sc; store-region-src=uid; sid_guard=f14390d924c81856fde84b1cd534bf09|1681878504|5183998|Sun,+18-Jun-2023+04:28:22+GMT; sid_ucp_v1=1.0.0-KGY5OGQ3OTQ4YmVkYzczODgzYzM0MmJmOWYxMzhkMDliMTc5NGI3NjMKGQjG-7zT9QEQ6Nv9oQYY7zEgDDgGQPQHSAQaAmxmIiBmMTQzOTBkOTI0YzgxODU2ZmRlODRiMWNkNTM0YmYwOQ; ssid_ucp_v1=1.0.0-KGY5OGQ3OTQ4YmVkYzczODgzYzM0MmJmOWYxMzhkMDliMTc5NGI3NjMKGQjG-7zT9QEQ6Nv9oQYY7zEgDDgGQPQHSAQaAmxmIiBmMTQzOTBkOTI0YzgxODU2ZmRlODRiMWNkNTM0YmYwOQ; download_guide="3/20230419"; pwa2="3|0"; FOLLOW_NUMBER_YELLOW_POINT_INFO="MS4wLjABAAAA-jD2lukp--I21BF8VQsmYUqJDbj3FmU-kGQTHl2y1Cw/1681920000000/0/0/1681900423333"; __ac_nonce=0644234d60042cacebbb6; __ac_signature=_02B4Z6wo00f01eZN0dAAAIDAhUcRuQz7dNHmbdVAAB3TRUC7i8VqXQejR8jv-D8UggBx1MBLH564PE.cCZf00m7Cw640CNUvcc5jJfhgn8u5FhvVndykvwbQb.HEpSfGN-8eqql7GpuGZJ8f1d; strategyABtestKey="1682060514.261"; passport_fe_beating_status=true; csrf_session_id=405b0ec4f6338a5d893a5f14f6fd1a64; bd_ticket_guard_client_data=eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtY2xpZW50LWNlcnQiOiItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cbk1JSUNGRENDQWJxZ0F3SUJBZ0lVR1ljQ3FuQUh0UUJBZm5WWkYxQW84cUtjY2Zrd0NnWUlLb1pJemowRUF3SXdcbk1URUxNQWtHQTFVRUJoTUNRMDR4SWpBZ0JnTlZCQU1NR1hScFkydGxkRjluZFdGeVpGOWpZVjlsWTJSellWOHlcbk5UWXdIaGNOTWpNd016STNNRE15T0RBeldoY05Nek13TXpJM01URXlPREF6V2pBbk1Rc3dDUVlEVlFRR0V3SkRcblRqRVlNQllHQTFVRUF3d1BZbVJmZEdsamEyVjBYMmQxWVhKa01Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERcbkFRY0RRZ0FFNmZ1Z3d0MEJnZUh5akVub1FvNWtXUS9qc2daTTV1YXBiNTQ4KytTV0dRSjMwb2lSTHNtYlVFSUZcblFIYzh3UEthZzZmdXNPTm91WncxOEdNYm5vTStwNk9CdVRDQnRqQU9CZ05WSFE4QkFmOEVCQU1DQmFBd01RWURcblZSMGxCQ293S0FZSUt3WUJCUVVIQXdFR0NDc0dBUVVGQndNQ0JnZ3JCZ0VGQlFjREF3WUlLd1lCQlFVSEF3UXdcbktRWURWUjBPQkNJRUlPV3Y3d01ZUGhoeUNPL2ZwenJGNDJNeEQ4ZGIzN0YyTDgxaW8zVTVlVFpaTUNzR0ExVWRcbkl3UWtNQ0tBSURLbForcU9aRWdTamN4T1RVQjdjeFNiUjIxVGVxVFJnTmQ1bEpkN0lrZURNQmtHQTFVZEVRUVNcbk1CQ0NEbmQzZHk1a2IzVjVhVzR1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGdBTUVVQ0lCbm9xRDBRbVdUSlNLOVNcbkFZRjJ6YkljYzBsZjFRMDVTUGxXMURDQ0FMVUpBaUVBazJFRWpKdkdFRnl0YzBWbXRoRTA5bFpGeFFkUmlGN21cbk9pdE5IZzBOZUJrPVxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxuIn0=; msToken=qSfWwAdwksuBS5wmQAvpzUsf2ovkFFKefOLSvZDKA1Z_FX7ith-wCknpVQB08kft4ISWp00GHeQBaPwV9tcWJq6xBC-mPnQKNjBVINeOQGvFtSdsfacWMtWpa8x1RJE=; FOLLOW_LIVE_POINT_INFO="MS4wLjABAAAA-jD2lukp--I21BF8VQsmYUqJDbj3FmU-kGQTHl2y1Cw/1682092800000/0/0/1682061497980"; msToken=jDwC5gjTRXV6hrFvGMG-AkOBXHGrt_Mp5NaltB1upOUm0aQnZ7sy7qlSEn2tQbGHShp2X7ayNMDQQlPekSTV9MkxBv56LR9zepTlYNOoqbH_RdjDvbl-MZDrmui3OEE=; tt_scid=hERl4ibL-B89BGXb9wUfsmVkQh-G2dvL2wI0QvEDYLooFsvwoz.q6J4ZA0WErn0Tb9fb; home_can_add_dy_2_desktop="1"'}
import requests import requests
res = requests.get(user_all_mix_link,headers=headers).text res = requests.get(user_all_mix_link, headers=headers).text
import json import json
datadict = json.loads(res) datadict = json.loads(res)
print(datadict["aweme_list"][0]["video"]["bit_rate"]) print(datadict["aweme_list"][0]["video"]["bit_rate"])
print(len(datadict["aweme_list"][0]["video"]["bit_rate"])) print(len(datadict["aweme_list"][0]["video"]["bit_rate"]))
if __name__ == "__main__": if __name__ == "__main__":
# test() # test()
# getMusicInfo() # getMusicInfo()
@ -98,4 +107,3 @@ if __name__ == "__main__":
# getUserInfo() # getUserInfo()
# getLiveInfo() # getLiveInfo()
pass pass

View File

@ -85,5 +85,6 @@ class Urls(object):
####################################################################################### #######################################################################################
if __name__ == '__main__': if __name__ == '__main__':
Urls() Urls()

View File

@ -22,6 +22,7 @@ import sys
import json import json
from TikTokUrls import Urls from TikTokUrls import Urls
class Utils(object): class Utils(object):
def __init__(self): def __init__(self):
pass pass
@ -52,7 +53,7 @@ class Utils(object):
# 去除前后空格 # 去除前后空格
return result return result
def resource_path(self,relative_path): def resource_path(self, relative_path):
if getattr(sys, 'frozen', False): # 是否Bundle Resource if getattr(sys, 'frozen', False): # 是否Bundle Resource
base_path = sys._MEIPASS base_path = sys._MEIPASS
else: else:
@ -62,9 +63,10 @@ class Utils(object):
def getXbogus(self, url, headers=None): def getXbogus(self, url, headers=None):
# getXbogus算法开源地址https://github.com/B1gM8c/tiktok # getXbogus算法开源地址https://github.com/B1gM8c/tiktok
user_agent = headers.get( user_agent = headers.get(
'User-Agent') if headers else "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" 'User-Agent') if headers else "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
try: try:
xbogus = execjs.compile(open(self.resource_path(os.path.join("X-Bogus.js"))).read()).call('sign', url, user_agent) xbogus = execjs.compile(open(self.resource_path(os.path.join("X-Bogus.js"))).read()).call('sign', url,
user_agent)
params = url + "&X-Bogus=" + xbogus params = url + "&X-Bogus=" + xbogus
except Exception as e: except Exception as e:
# print('[ 错误 ]:X-Bogus算法异常或者本地没有JS环境') # print('[ 错误 ]:X-Bogus算法异常或者本地没有JS环境')
@ -79,8 +81,6 @@ class Utils(object):
return return
return params return params
def str2bool(self, v): def str2bool(self, v):
if isinstance(v, bool): if isinstance(v, bool):
return v return v
@ -97,7 +97,7 @@ class Utils(object):
data = '{"region":"cn","aid":1768,"needFid":false,"service":"www.ixigua.com","migrate_info":{"ticket":"","source":"node"},"cbUrlProtocol":"https","union":true}' data = '{"region":"cn","aid":1768,"needFid":false,"service":"www.ixigua.com","migrate_info":{"ticket":"","source":"node"},"cbUrlProtocol":"https","union":true}'
res = requests.post(url=url, data=data) res = requests.post(url=url, data=data)
for i,j in res.cookies.items(): for i, j in res.cookies.items():
return j return j

View File

@ -33,7 +33,8 @@ def work(share_link, max_cursor, mode, cookie):
has_more = None has_more = None
if key_type == "user": if key_type == "user":
if mode == 'post' or mode == 'like': if mode == 'post' or mode == 'like':
datalist, rawdatalist, cursor, has_more = tk.getUserInfoApi(sec_uid=key, mode=mode, count=35, max_cursor=max_cursor) datalist, rawdatalist, cursor, has_more = tk.getUserInfoApi(sec_uid=key, mode=mode, count=35,
max_cursor=max_cursor)
elif mode == 'mix': elif mode == 'mix':
datalist, rawdatalist, cursor, has_more = tk.getUserAllMixInfoApi(sec_uid=key, count=35, cursor=max_cursor) datalist, rawdatalist, cursor, has_more = tk.getUserAllMixInfoApi(sec_uid=key, count=35, cursor=max_cursor)
elif key_type == "mix": elif key_type == "mix":
@ -45,7 +46,7 @@ def work(share_link, max_cursor, mode, cookie):
elif key_type == "live": elif key_type == "live":
datalist, rawdatalist = tk.getLiveInfoApi(web_rid=key) datalist, rawdatalist = tk.getLiveInfoApi(web_rid=key)
datadict={} datadict = {}
if datalist is not None and datalist != []: if datalist is not None and datalist != []:
datadict["data"] = datalist datadict["data"] = datalist
@ -57,6 +58,7 @@ def work(share_link, max_cursor, mode, cookie):
datadict["status_code"] = 500 datadict["status_code"] = 500
return datadict return datadict
def deal(mode=None): def deal(mode=None):
usefuldict = {} usefuldict = {}
if request.headers.get("content_type") == "application/json": if request.headers.get("content_type") == "application/json":
@ -83,10 +85,12 @@ def deal(mode=None):
usefuldict["status_code"] = 500 usefuldict["status_code"] = 500
return jsonify(usefuldict) return jsonify(usefuldict)
app = Flask(__name__) app = Flask(__name__)
# 设置编码 # 设置编码
app.config['JSON_AS_ASCII'] = False app.config['JSON_AS_ASCII'] = False
def argument(): def argument():
parser = argparse.ArgumentParser(description='抖音去水印工具 使用帮助') parser = argparse.ArgumentParser(description='抖音去水印工具 使用帮助')
parser.add_argument("--port", "-p", help="Web端口", parser.add_argument("--port", "-p", help="Web端口",
@ -95,34 +99,42 @@ def argument():
return args return args
@app.route("/douyin/music", methods=["POST"]) @app.route("/douyin/music", methods=["POST"])
def douyinMusic(): def douyinMusic():
return deal() return deal()
@app.route("/douyin/mix", methods=["POST"]) @app.route("/douyin/mix", methods=["POST"])
def douyinMix(): def douyinMix():
return deal() return deal()
@app.route("/douyin/user/mix", methods=["POST"]) @app.route("/douyin/user/mix", methods=["POST"])
def douyinUserMix(): def douyinUserMix():
return deal(mode="mix") return deal(mode="mix")
@app.route("/douyin/user/like", methods=["POST"]) @app.route("/douyin/user/like", methods=["POST"])
def douyinUserLike(): def douyinUserLike():
return deal(mode="like") return deal(mode="like")
@app.route("/douyin/user/post", methods=["POST"]) @app.route("/douyin/user/post", methods=["POST"])
def douyinUserPost(): def douyinUserPost():
return deal(mode="post") return deal(mode="post")
@app.route("/douyin/aweme", methods=["POST"]) @app.route("/douyin/aweme", methods=["POST"])
def douyinAweme(): def douyinAweme():
return deal() return deal()
@app.route("/douyin/live", methods=["POST"]) @app.route("/douyin/live", methods=["POST"])
def douyinLive(): def douyinLive():
return deal() return deal()
@app.route("/douyin", methods=["POST"]) @app.route("/douyin", methods=["POST"])
def douyin(): def douyin():
return deal() return deal()

View File

@ -153,7 +153,7 @@ button:hover {
} }
/*--//wrapper--*/ /*--//wrapper--*/
.error-61-mian { .error-61-mian {
background: url(https://testingcf.jsdelivr.net/gh/imgyh/tiktok/static/img/banner.jpg) no-repeat bottom; background: url(https://testingcf.jsdelivr.net/gh/imgyh/tiktok/static/img/banner.jpg) no-repeat bottom;
background-size: cover; background-size: cover;
-webkit-background-size: cover; -webkit-background-size: cover;
@ -167,7 +167,7 @@ button:hover {
align-items: center; align-items: center;
} }
.error-61-mian:before { .error-61-mian:before {
content: ""; content: "";
background: rgba(66, 21, 2, 0.45); background: rgba(66, 21, 2, 0.45);
position: absolute; position: absolute;
@ -178,19 +178,19 @@ button:hover {
z-index: -1; z-index: -1;
} }
.errors-16-top { .errors-16-top {
max-width: 600px; max-width: 600px;
margin: 0 auto; margin: 0 auto;
text-align: center text-align: center
} }
.errors-16-mid { .errors-16-mid {
max-width: 600px; max-width: 600px;
margin: 0 auto; margin: 0 auto;
text-align: center text-align: center
} }
.error-61-mian h3 { .error-61-mian h3 {
font-size: 223px; font-size: 223px;
line-height: 200px; line-height: 200px;
color: #fff; color: #fff;
@ -199,21 +199,21 @@ button:hover {
text-shadow: 0 1px 2px rgba(0, 0, 0, .6); text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
} }
.error-61-mian p { .error-61-mian p {
font-size: 18px; font-size: 18px;
line-height: 30px; line-height: 30px;
color: #fff; color: #fff;
letter-spacing: 1px; letter-spacing: 1px;
} }
.error-page-form { .error-page-form {
border: 2px solid #fff; border: 2px solid #fff;
border-radius: 25px; border-radius: 25px;
padding: 5px; padding: 5px;
margin: 20px 0; margin: 20px 0;
} }
.error-page-form input { .error-page-form input {
color: #fff; color: #fff;
font-size: 18px; font-size: 18px;
border: none; border: none;
@ -247,7 +247,7 @@ button:hover {
background: transparent; background: transparent;
} }
.error-page-form button { .error-page-form button {
color: var(--theme-green); color: var(--theme-green);
background: #fff; background: #fff;
border: none; border: none;
@ -260,13 +260,13 @@ button:hover {
border-radius: 25px; border-radius: 25px;
} }
.error-page-form button:hover { .error-page-form button:hover {
color: #fff; color: #fff;
background: #0099CC; /*#394247*/ background: #0099CC; /*#394247*/
} }
.social-coming-icons a { .social-coming-icons a {
background: transparent; background: transparent;
border-radius: 50%; border-radius: 50%;
width: 34px; width: 34px;
@ -278,13 +278,13 @@ button:hover {
color: #fff; color: #fff;
} }
.social-coming-icons a span { .social-coming-icons a span {
font-size: 18px; font-size: 18px;
line-height: 30px; line-height: 30px;
} }
.social-coming-icons a:hover { .social-coming-icons a:hover {
color: #0099CC; /*#394247*/ color: #0099CC; /*#394247*/
border: 2px solid #0099CC; /*#394247*/ border: 2px solid #0099CC; /*#394247*/
transition: 0.5s ease; transition: 0.5s ease;
@ -294,30 +294,30 @@ button:hover {
-moz-transition: 0.5s ease; -moz-transition: 0.5s ease;
} }
.copy-right { .copy-right {
margin: 0 auto; margin: 0 auto;
text-align: center text-align: center
} }
.copy-right p { .copy-right p {
font-size: 18px; font-size: 18px;
line-height: 29px; line-height: 29px;
color: #f9f9f9; color: #f9f9f9;
} }
.copy-right a { .copy-right a {
color: #00c4b6; color: #00c4b6;
} }
@media (max-width: 1280px) { @media (max-width: 1280px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 180px; font-size: 180px;
line-height: 170px; line-height: 170px;
} }
} }
@media (max-width: 1280px) { @media (max-width: 1280px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 125px; font-size: 125px;
line-height: 120px; line-height: 120px;
color: #fff; color: #fff;
@ -327,21 +327,21 @@ button:hover {
} }
@media (max-width: 990px) { @media (max-width: 990px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 125px; font-size: 125px;
line-height: 110px; line-height: 110px;
} }
} }
@media (max-width: 667px) { @media (max-width: 667px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 115px; font-size: 115px;
line-height: 110px; line-height: 110px;
} }
} }
@media (max-width: 600px) { @media (max-width: 600px) {
.error-61-mian { .error-61-mian {
background: url(https://testingcf.jsdelivr.net/gh/imgyh/tiktok/static/img/banner.jpg) no-repeat right; background: url(https://testingcf.jsdelivr.net/gh/imgyh/tiktok/static/img/banner.jpg) no-repeat right;
background-size: cover; background-size: cover;
-webkit-background-size: cover; -webkit-background-size: cover;
@ -352,14 +352,14 @@ button:hover {
} }
@media (max-width: 440px) { @media (max-width: 440px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 105px; font-size: 105px;
line-height: 100px; line-height: 100px;
} }
} }
@media (max-width: 384px) { @media (max-width: 384px) {
.error-61-mian h3 { .error-61-mian h3 {
font-size: 95px; font-size: 95px;
line-height: 90px; line-height: 90px;
} }
@ -615,7 +615,7 @@ button:hover {
position: absolute; position: absolute;
right: 50px; right: 50px;
top: 50px; top: 50px;
z-index: 10 ; z-index: 10;
cursor: pointer; cursor: pointer;
} }

View File

@ -19,10 +19,12 @@
</script> </script>
<!-- //Meta tag Keywords --> <!-- //Meta tag Keywords -->
<!-- /Favicons --> <!-- /Favicons -->
<link href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/img/favicon.ico" rel="shortcut icon" type="image/x-icon"> <link href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/img/favicon.ico" rel="shortcut icon"
type="image/x-icon">
<!-- //Favicons --> <!-- //Favicons -->
<!--/Style-CSS --> <!--/Style-CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/css/style.css" type="text/css" media="all"/> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/css/style.css" type="text/css"
media="all"/>
<!--//Style-CSS --> <!--//Style-CSS -->
<!-- font-awesome-icons --> <!-- font-awesome-icons -->
<link href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/css/font-awesome.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/css/font-awesome.css" rel="stylesheet">
@ -45,16 +47,17 @@
<p style="color:#00c4b6;font-size:32px;">抖音去水印工具</p> <p style="color:#00c4b6;font-size:32px;">抖音去水印工具</p>
<br> <br>
<p>支持视频/图集/直播解析,粘贴视频/图集/直播分享链接时无需删除文案,但如果链接正确但解析失败请删掉文案后重试 https://v.douyin.com/kcvMpuN/</p> <p>支持视频/图集/直播解析,粘贴视频/图集/直播分享链接时无需删除文案,但如果链接正确但解析失败请删掉文案后重试 https://v.douyin.com/kcvMpuN/</p>
{# <p>2.支持直播解析,需要网页版直播链接 https://live.douyin.com/343806013144</p>#} {# <p>2.支持直播解析,需要网页版直播链接 https://live.douyin.com/343806013144</p>#}
<p>关于抖音批量下载与去水印工具的更多实现细节请点击: <a href="https://www.imgyh.com/archives/41.html" target="_blank" style="color:#00c4b6;">抖音批量下载与去水印工具</a></p> <p>关于抖音批量下载与去水印工具的更多实现细节请点击: <a href="https://www.imgyh.com/archives/41.html" target="_blank"
style="color:#00c4b6;">抖音批量下载与去水印工具</a></p>
<form id="form1" onsubmit="return false" action="#" method="post" class="d-flex error-page-form"> <form id="form1" onsubmit="return false" action="#" method="post" class="d-flex error-page-form">
{# 以前需要手动选择 图片 或者 视频 现在加了自动判断#} {# 以前需要手动选择 图片 或者 视频 现在加了自动判断#}
{# <div class="select">#} {# <div class="select">#}
{# <select name="awemeType" required="required">#} {# <select name="awemeType" required="required">#}
{# <option value="0" selected="selected">视频</option>#} {# <option value="0" selected="selected">视频</option>#}
{# <option value="1">图集</option>#} {# <option value="1">图集</option>#}
{# </select>#} {# </select>#}
{# </div>#} {# </div>#}
<input type="text" placeholder="粘贴视频/图集/直播分享地址" name="share_link" required="required"> <input type="text" placeholder="粘贴视频/图集/直播分享地址" name="share_link" required="required">
<button type="reset" onclick="SendAjax()">解析</button> <button type="reset" onclick="SendAjax()">解析</button>
@ -156,10 +159,10 @@
<div style="display: none"> <div style="display: none">
<ul id="images"> <ul id="images">
{# <li><img src="picture-1.jpg" alt="Picture 1"></li>#} {# <li><img src="picture-1.jpg" alt="Picture 1"></li>#}
{# <li><img src="picture-2.jpg" alt="Picture 2"></li>#} {# <li><img src="picture-2.jpg" alt="Picture 2"></li>#}
{# <li><img src="picture-3.jpg" alt="Picture 3"></li>#} {# <li><img src="picture-3.jpg" alt="Picture 3"></li>#}
</ul> </ul>
</div> </div>
<script src="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/js/jquery-1.8.2.min.js" type="text/javascript"></script> <script src="https://cdn.jsdelivr.net/gh/imgyh/tiktok/static/js/jquery-1.8.2.min.js" type="text/javascript"></script>