From 0ea992dd72e95ab6ddad09005801aa56a40fb693 Mon Sep 17 00:00:00 2001 From: RobotJohns <37685728+RobotJohns@users.noreply.github.com> Date: Tue, 7 Dec 2021 16:47:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0=20=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1). 修改 路径为 './' 兼容 mac 2). 存储视频信息 描述,点赞,评论,以便 后期的数据二次加工 3). 优化以 视频描述作为 文件名称的时候 对于长文件名称以及 '\r\n' 非法进行处理 4). 添加GC --- DbTool.py | 104 ++++++++++++++ TikTokMulti.py | 379 +++++++++++++++++++++++++++++-------------------- 2 files changed, 329 insertions(+), 154 deletions(-) create mode 100644 DbTool.py diff --git a/DbTool.py b/DbTool.py new file mode 100644 index 0000000..b1de72d --- /dev/null +++ b/DbTool.py @@ -0,0 +1,104 @@ +import os +import sqlite3 + +import re +dbfile = '' +dbTable = '' + +# fileName = '' +# des = '' +# like = '' +# share = '' +# comment = '' +# time = '' + + +def createDB(path): + global dbfile + tableName = 'data.db' + + if not os.path.exists(path): + os.mkdir(path) + db_is_new = not os.path.exists(path+tableName) + if db_is_new: + print('Need to create schema') + else: + print('Database exists, assume schema does, too.') + conn = sqlite3.connect(path+tableName) + dbfile = path+tableName + + conn.close() + + +def createTable(tableName): + global dbfile + global dbTable + + dbTable = tableName + conn = sqlite3.connect(dbfile) + sql = '''create table if not exists {0}( + _id integer primary key autoincrement, + fileName char(360) unique, + des char(360), + like integer, + share integer, + comment integer, + time char(32));'''.format(tableName) + + conn.execute(sql) + print("Table created successfully") + conn.close() + + +def insertDate(videoinfo, videodes, videotime): + # global fileName + # global des + # global like + # global share + # global comment + # global time + # print("fileName:"+fileName) + # print("videoinfo:"+videoinfo) + # print("des:"+des) + # print("time:"+time) + + global dbfile + global dbTable + + fileName = videotime + re.sub(r'[\\/:*?"<>|\r\n]+', "_", videodes) + + # like = videoinfo['digg_count'] + # share = videoinfo['share_count'] + # comment = videoinfo['comment_count'] + # time = videotime + conn = sqlite3.connect(dbfile) + #print('-------------------------->{0}'.format(videoinfo['digg_count'])) + + try: + + selectSql = '''select _id from {0} where fileName = '{1}';'''.format( + dbTable, fileName) + #print('---selectSql:{0}'.format(selectSql)) + + resoult = conn.execute(selectSql) + #print('---数据长度{0}'.format(len(resoult.fetchall()))) + + #不存在类似数据 再插入 + if len(resoult.fetchall()) == 0: + #print('---数据长度{0}'.format(len(resoult.fetchall()))) + insertSql = '''insert into {0} ('fileName','des','like','share','comment','time') values ('{1}','{2}','{3}','{4}','{5}','{6}');'''.format( + dbTable, fileName, videodes, videoinfo['digg_count'], videoinfo['share_count'], videoinfo['comment_count'], videotime) + + #print(insertSql) + conn.execute(insertSql) + conn.commit() + #print("Table insert successfully") + conn.close() + else: + conn.close() + + except Exception as error: + # print('插入数据错误:'+error) + print('插入数据错误:{0}'.format(error)) + conn.close() + pass diff --git a/TikTokMulti.py b/TikTokMulti.py index 76afd51..a8fb7e6 100644 --- a/TikTokMulti.py +++ b/TikTokMulti.py @@ -9,23 +9,32 @@ @Mail :johnserfseed@gmail.com ''' -import requests,json,os,time,configparser,re,sys +import requests +import json +import os +import time +import configparser +import re +import sys import TikTokDownload +import DbTool +import gc + class TikTok(): - #初始化 + # 初始化 def __init__(self): self.headers = { 'user-agent': 'Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36 Edg/87.0.664.66' - } - - #抓获所有视频 + } + + # 抓获所有视频 self.Isend = False self.out_Print() - #绘制布局 + # 绘制布局 print("#" * 120) - print( - """ + print( + """ TikTokDownload V1.2.3 使用说明: 1、运行软件前先打开目录下 conf.ini 文件按照要求进行配置 @@ -39,7 +48,7 @@ def __init__(self): print("#" * 120) print('\r') - #检测配置文件 + # 检测配置文件 if os.path.isfile("conf.ini") == True: pass else: @@ -54,310 +63,372 @@ def __init__(self): self.cf.add_section("count") self.cf.set("count", "count", "35") self.cf.add_section("save") - self.cf.set("save", "url", ".\\Download\\") + self.cf.set("save", "url", "./Download/") self.cf.add_section("mode") self.cf.set("mode", "mode", "post") - with open("conf.ini","a+") as f: + with open("conf.ini", "a+") as f: self.cf.write(f) print('----生成成功----\r') except: input('----生成失败,正在为您下载配置文件----\r') - r =requests.get('https://gitee.com/johnserfseed/TikTokDownload/raw/main/conf.ini') + r = requests.get( + 'https://gitee.com/johnserfseed/TikTokDownload/raw/main/conf.ini') with open("conf.ini", "a+") as conf: conf.write(r.content) sys.exit() - #实例化读取配置文件 + # 实例化读取配置文件 self.cf = configparser.ConfigParser() - #用utf-8防止出错 + # 用utf-8防止出错 self.cf.read("conf.ini", encoding="utf-8") - #读取保存路径 - self.save = self.cf.get("save","url") + # 读取保存路径 + self.save = self.cf.get("save", "url") + + # 读取下载视频个数 + self.count = int(self.cf.get("count", "count")) - #读取下载视频个数 - self.count = int(self.cf.get("count","count")) - - #读取下载是否下载音频 - self.musicarg = self.cf.get("music","musicarg") + # 读取下载是否下载音频 + self.musicarg = self.cf.get("music", "musicarg") - #读取用户主页地址 + # 读取用户主页地址 self.uid = input('批量下载直接回车,单一视频下载直接粘贴视频链接:') if self.uid == '': - self.uid = self.cf.get("url","uid") + self.uid = self.cf.get("url", "uid") else: pass - #读取下载模式 - self.mode = self.cf.get("mode","mode") + # 读取下载模式 + self.mode = self.cf.get("mode", "mode") - #保存用户名 + # 保存用户名 self.nickname = "" self.like_counts = 0 print('----读取配置完成----\r') + + DbTool.createDB(self.save) + self.judge_link() def out_Print(self): print(r''' - ████████╗██╗██╗ ██╗████████╗ ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗ ██╗███╗ ██╗██╗ ██████╗ █████╗ ██████╗ + ████████╗██╗██╗ ██╗████████╗ ██████╗ ██╗ ██╗██████╗ ██████╗ ██╗ ██╗███╗ ██╗██╗ ██████╗ █████╗ ██████╗ ╚══██╔══╝██║██║ ██╔╝╚══██╔══╝██╔═══██╗██║ ██╔╝██╔══██╗██╔═══██╗██║ ██║████╗ ██║██║ ██╔═══██╗██╔══██╗██╔══██╗ ██║ ██║█████╔╝ ██║ ██║ ██║█████╔╝ ██║ ██║██║ ██║██║ █╗ ██║██╔██╗ ██║██║ ██║ ██║███████║██║ ██║ ██║ ██║██╔═██╗ ██║ ██║ ██║██╔═██╗ ██║ ██║██║ ██║██║███╗██║██║╚██╗██║██║ ██║ ██║██╔══██║██║ ██║ ██║ ██║██║ ██╗ ██║ ╚██████╔╝██║ ██╗██████╔╝╚██████╔╝╚███╔███╔╝██║ ╚████║███████╗╚██████╔╝██║ ██║██████╔╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝''') - #匹配粘贴的url地址 - def Find(self,string): + # 匹配粘贴的url地址 + def Find(self, string): # findall() 查找匹配正则表达式的字符串 - url = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', string) + url = re.findall( + 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', string) return url - #判断个人主页api链接 + # 判断个人主页api链接 def judge_link(self): - #获取解码后原地址 - r = requests.get(url = self.Find(self.uid)[0]) + # 获取解码后原地址 + r = requests.get(url=self.Find(self.uid)[0]) multi_url = 'https://www.douyin.com/user/' - #multi_url = 'https://www.iesdouyin.com/share/user/' #旧 + # multi_url = 'https://www.iesdouyin.com/share/user/' #旧 - #判断输入的是不是用户主页 + # 判断输入的是不是用户主页 if r.url[:28] == multi_url: print('----为您下载多个视频----\r') - #获取用户sec_uid - #key = re.findall('&sec_uid=(.*?)&',str(r.url))[0] - key = re.findall('/user/(.*?)\?',str(r.url))[0] + # 获取用户sec_uid + # key = re.findall('&sec_uid=(.*?)&',str(r.url))[0] + key = re.findall('/user/(.*?)\?', str(r.url))[0] if not key: - key = r.url[28:83] + key = r.url[28:83] print('----'+'用户的sec_id='+key+'----\r') else: print('----为您下载单个视频----\r') print(r.url) - urlarg,musicarg = TikTokDownload.main() - TikTokDownload.video_download(urlarg,musicarg) + urlarg, musicarg = TikTokDownload.main() + + TikTokDownload.video_download(urlarg, musicarg) return - #第一次访问页码 + # 第一次访问页码 max_cursor = 0 - #构造第一次访问链接 - api_post_url = 'https://www.iesdouyin.com/web/api/v2/aweme/%s/?sec_uid=%s&count=%s&max_cursor=%s&aid=1128&_signature=PDHVOQAAXMfFyj02QEpGaDwx1S&dytk=' % (self.mode,key,str(self.count),max_cursor) - response = requests.get(url = api_post_url,headers = self.headers) + # 构造第一次访问链接 + api_post_url = 'https://www.iesdouyin.com/web/api/v2/aweme/%s/?sec_uid=%s&count=%s&max_cursor=%s&aid=1128&_signature=PDHVOQAAXMfFyj02QEpGaDwx1S&dytk=' % ( + self.mode, key, str(self.count), max_cursor) + response = requests.get(url=api_post_url, headers=self.headers) html = json.loads(response.content.decode()) self.nickname = html['aweme_list'][0]['author']['nickname'] - if not os.path.exists(self.save + self.mode + "\\" + self.nickname): - os.makedirs(self.save + self.mode + "\\" + self.nickname) + if not os.path.exists(self.save + self.mode + "/" + self.nickname): + os.makedirs(self.save + self.mode + "/" + self.nickname) - self.get_data(api_post_url,max_cursor) - return api_post_url,max_cursor,key + DbTool.createTable(self.nickname) - #获取第一次api数据 - def get_data(self,api_post_url,max_cursor): - #尝试次数 + self.get_data(api_post_url, max_cursor) + return api_post_url, max_cursor, key + + # 获取第一次api数据 + def get_data(self, api_post_url, max_cursor): + # 尝试次数 index = 0 - #存储api数据 + # 存储api数据 result = [] while result == []: index += 1 print('----正在进行第 %d 次尝试----\r' % index) time.sleep(0.3) - response = requests.get(url = api_post_url,headers = self.headers) + response = requests.get(url=api_post_url, headers=self.headers) html = json.loads(response.content.decode()) - with open('r.json','wb')as f: + with open('r.json', 'wb')as f: f.write(response.content) if self.Isend == False: - #下一页值 + # 下一页值 print('[ 用户 ]:'+str(self.nickname)+'\r') max_cursor = html['max_cursor'] result = html['aweme_list'] print('----抓获数据成功----\r') - #处理第一页视频信息 - self.video_info(result,max_cursor) + # 处理第一页视频信息 + self.video_info(result, max_cursor) else: max_cursor = html['max_cursor'] self.next_data(max_cursor) - #self.Isend = True + # self.Isend = True print('----此页无数据,为您跳过----\r') - return result,max_cursor + return result, max_cursor + + # 下一页 + def next_data(self, max_cursor): + gc.collect - #下一页 - def next_data(self,max_cursor): - #获取解码后原地址 - r = requests.get(url = self.Find(self.uid)[0]) + # 获取解码后原地址 + r = requests.get(url=self.Find(self.uid)[0]) - #获取用户sec_uid - key = re.findall('/user/(.*?)\?',str(r.url))[0] + # 获取用户sec_uid + key = re.findall('/user/(.*?)\?', str(r.url))[0] if not key: - key = r.url[28:83] + key = r.url[28:83] - #构造下一次访问链接 - api_naxt_post_url = 'https://www.iesdouyin.com/web/api/v2/aweme/%s/?sec_uid=%s&count=%s&max_cursor=%s&aid=1128&_signature=RuMN1wAAJu7w0.6HdIeO2EbjDc&dytk=' % (self.mode,key,str(self.count),max_cursor) + # 构造下一次访问链接 + api_naxt_post_url = 'https://www.iesdouyin.com/web/api/v2/aweme/%s/?sec_uid=%s&count=%s&max_cursor=%s&aid=1128&_signature=RuMN1wAAJu7w0.6HdIeO2EbjDc&dytk=' % ( + self.mode, key, str(self.count), max_cursor) index = 0 result = [] while self.Isend == False: - #回到首页,则结束 + # 回到首页,则结束 if max_cursor == 0: self.Isend = True return index += 1 - print('----正在对',max_cursor,'页进行第 %d 次尝试----\r' % index) + print('----正在对', max_cursor, '页进行第 %d 次尝试----\r' % index) time.sleep(0.3) - response = requests.get(url = api_naxt_post_url,headers=self.headers) + response = requests.get( + url=api_naxt_post_url, headers=self.headers) html = json.loads(response.content.decode()) if self.Isend == False: - #下一页值 + # 下一页值 max_cursor = html['max_cursor'] result = html['aweme_list'] - print('----',max_cursor,'页抓获数据成功----\r') - #处理下一页视频信息 - self.video_info(result,max_cursor) + print('----', max_cursor, '页抓获数据成功----\r') + # 处理下一页视频信息 + self.video_info(result, max_cursor) else: self.Isend == True - print('----',max_cursor,'页抓获数据失败----\r') - #sys.exit() + print('----', max_cursor, '页抓获数据失败----\r') + # sys.exit() - #处理视频信息 - def video_info(self,result,max_cursor): - #作者信息 + # 处理视频信息 + def video_info(self, result, max_cursor): + # 作者信息 author_list = [] - #无水印视频链接 + # 无水印视频链接 video_list = [] - #作品id + # 作品id aweme_id = [] - #作者id + # 作者id nickname = [] - - #封面大图 - #dynamic_cover = [] + # 视频信息 点赞数 评论数 分享数 + videoinfo = [] + # 封面大图 + # dynamic_cover = [] for i2 in range(self.count): try: author_list.append(str(result[i2]['desc'])) - video_list.append(str(result[i2]['video']['play_addr']['url_list'][0])) + video_list.append( + str(result[i2]['video']['play_addr']['url_list'][0])) aweme_id.append(str(result[i2]['aweme_id'])) nickname.append(str(result[i2]['author']['nickname'])) - #dynamic_cover.append(str(result[i2]['video']['dynamic_cover']['url_list'][0])) + videoinfo.append(str(result[i2]['statistics'])) + # dynamic_cover.append(str(result[i2]['video']['dynamic_cover']['url_list'][0])) except Exception as error: - #print(error) + # print(error) pass - self.videos_download(author_list,video_list,aweme_id,nickname,max_cursor) - return self,author_list,video_list,aweme_id,nickname,max_cursor - - #检测视频是否已经下载过 - def check_info(self,nickname): + # self.videos_download(author_list,video_list,aweme_id,nickname,videoinfo,max_cursor) + # return self,author_list,video_list,aweme_id,nickname,videoinfo,max_cursor + self.videos_download(author_list, video_list, + aweme_id, nickname, videoinfo, max_cursor) + return self, author_list, video_list, aweme_id, nickname, videoinfo, max_cursor + + # 检测视频是否已经下载过 + def check_info(self, nickname): if nickname == []: return else: - v_info = os.listdir((self.save + self.mode + "\\" + nickname)) + v_info = os.listdir((self.save + self.mode + "/" + nickname)) return v_info - #音视频下载 - def videos_download(self,author_list,video_list,aweme_id,nickname,max_cursor): - #创建并检测下载目录是否存在 + # 音视频下载 + def videos_download(self, author_list, video_list, aweme_id, nickname, videoinfo, max_cursor): + # 创建并检测下载目录是否存在 try: - os.makedirs(self.save + self.mode + "\\" + nickname[0]) + os.makedirs(self.save + self.mode + "/" + nickname[0]) except: pass - v_info = self.check_info(self.nickname) + v_info = self.check_info(self.nickname) for i in range(self.count): - #点赞视频排序 + if len(videoinfo) == 0 or i > len(videoinfo)-1: + break + + # 点赞视频排序 self.like_counts += 1 - #获取单部视频接口信息 + # 获取单部视频接口信息 try: - jx_url = f'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={aweme_id[i]}' #官方接口 - js = json.loads(requests.get(url = jx_url,headers=self.headers).text) - creat_time = time.strftime("%Y-%m-%d %H.%M.%S", time.localtime(js['item_list'][0]['create_time'])) + # 官方接口 + jx_url = f'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={aweme_id[i]}' + js = json.loads(requests.get( + url=jx_url, headers=self.headers).text) + creat_time = time.strftime( + "%Y-%m-%d %H.%M.%S", time.localtime(js['item_list'][0]['create_time'])) except Exception as error: - #print(error) + print("网络请求出错 跳过当前视频:{0}".format(error)) pass - #每次判断视频是否已经下载过 + if not creat_time: + break + + # 移除文件名称 /r/n + author_list[i] = ''.join(author_list[i].splitlines()) + + DbTool.insertDate(eval(videoinfo[i]), author_list[i], creat_time) + + if len(author_list[i]) > 182: + print("-----> 文件名称太长 进行截取:{0},{1},长度:{2}".format( + videoinfo[i], author_list[i], len(author_list[i]))) + author_list[i] = author_list[i][0:180] + print( + "-----> 截取后的文字:{0},长度:{1}".format(author_list[i], len(author_list[i]))) + + # 每次判断视频是否已经下载过 try: if creat_time + author_list[i] + '.mp4' in v_info: - print('[ 提示 ]:'+author_list[i]+'[文件已存在,为您跳过]',end = "") #开始下载,显示下载文件大小 + print('[ 提示 ]:'+author_list[i] + + '[文件已存在,为您跳过]', end="") # 开始下载,显示下载文件大小 for i in range(20): - print(">",end = '',flush = True) + print(">", end='', flush=True) time.sleep(0.01) print('\r') continue except: - #防止下标越界 + # 防止下标越界 pass - - #尝试下载音频 + + # 尝试下载音频 try: - if self.musicarg == "yes": #保留音频 - music_url = str(js['item_list'][0]['music']['play_url']['url_list'][0]) + if self.musicarg == "yes": # 保留音频 + music_url = str(js['item_list'][0]['music'] + ['play_url']['url_list'][0]) music_title = str(js['item_list'][0]['music']['author']) - music=requests.get(music_url) #保存音频 - start = time.time() #下载开始时间 - size = 0 #初始化已下载大小 - chunk_size = 1024 #每次下载的数据大小 - content_size = int(music.headers['content-length']) # 下载文件总大小 - if music.status_code == 200: #判断是否响应成功 - print('[ 音频 ]:'+ creat_time + author_list[i]+'[文件 大小]:{size:.2f} MB'.format(size = content_size / chunk_size /1024)) #开始下载,显示下载文件大小 - + music = requests.get(music_url) # 保存音频 + start = time.time() # 下载开始时间 + size = 0 # 初始化已下载大小 + chunk_size = 1024 # 每次下载的数据大小 + content_size = int( + music.headers['content-length']) # 下载文件总大小 + if music.status_code == 200: # 判断是否响应成功 + print('[ 音频 ]:' + creat_time + author_list[i]+'[文件 大小]:{size:.2f} MB'.format( + size=content_size / chunk_size / 1024)) # 开始下载,显示下载文件大小 + if self.mode == 'post': - m_url = self.save + self.mode + "\\" + nickname[i] + '\\' + creat_time + re.sub(r'[\\/:*?"<>|\r\n]+', "_", music_title) + '_' + author_list[i] + '.mp3' + m_url = self.save + self.mode + "/" + nickname[i] + '/' + creat_time + re.sub( + r'[\\/:*?"<>|\r\n]+', "_", music_title) + '_' + author_list[i] + '.mp3' else: - m_url = self.save + self.mode + "\\" + self.nickname + '\\' + str(self.like_counts)+ '、' + re.sub(r'[\\/:*?"<>|\r\n]+', "_", music_title) + '_' + author_list[i] + '.mp3' - - with open(m_url,'wb') as file: #显示进度条 - for data in music.iter_content(chunk_size = chunk_size): + m_url = self.save + self.mode + "/" + self.nickname + '/' + \ + str(self.like_counts) + '、' + re.sub( + r'[\\/:*?"<>|\r\n]+', "_", music_title) + '_' + author_list[i] + '.mp3' + + with open(m_url, 'wb') as file: # 显示进度条 + for data in music.iter_content(chunk_size=chunk_size): file.write(data) - size +=len(data) - print('\r'+'[下载进度]:%s%.2f%%' % ('>'*int(size*50/ content_size), float(size / content_size * 100)) ,end=' ') - end = time.time() #下载结束时间 - print('\n' + '[下载完成]:耗时: %.2f秒\n' % (end - start)) #输出下载用时时间 + size += len(data) + print('\r'+'[下载进度]:%s%.2f%%' % ( + '>'*int(size*50 / content_size), float(size / content_size * 100)), end=' ') + end = time.time() # 下载结束时间 + print('\n' + '[下载完成]:耗时: %.2f秒\n' % + (end - start)) # 输出下载用时时间 except: input('下载音频出错!\r') - #尝试下载视频 + # 尝试下载视频 try: - video = requests.get(video_list[i]) #保存视频 - start = time.time() #下载开始时间 - size = 0 #初始化已下载大小 - chunk_size = 1024 #每次下载的数据大小 - content_size = int(video.headers['content-length']) # 下载文件总大小 + video = requests.get(video_list[i]) # 保存视频 + start = time.time() # 下载开始时间 + size = 0 # 初始化已下载大小 + chunk_size = 1024 # 每次下载的数据大小 + content_size = int(video.headers['content-length']) # 下载文件总大小 try: - if video.status_code == 200: #判断是否响应成功 - print('[ 视频 ]:'+ creat_time + author_list[i]+'[文件 大小]:{size:.2f} MB'.format(size = content_size / chunk_size /1024)) #开始下载,显示下载文件大小 - + if video.status_code == 200: # 判断是否响应成功 + print('[ 视频 ]:' + creat_time + author_list[i]+'[文件 大小]:{size:.2f} MB'.format( + size=content_size / chunk_size / 1024)) # 开始下载,显示下载文件大小 + if self.mode == 'post': - v_url = self.save + self.mode + "\\" + nickname[i] + '\\' + creat_time +re.sub(r'[\\/:*?"<>|\r\n]+', "_", author_list[i]) + '.mp4' + v_url = self.save + self.mode + "/" + \ + nickname[i] + '/' + creat_time + \ + re.sub(r'[\\/:*?"<>|\r\n]+', "_", + author_list[i]) + '.mp4' else: - v_url = self.save + self.mode + "\\" + self.nickname + '\\' + str(self.like_counts)+ '、' + re.sub(r'[\\/:*?"<>|\r\n]+', "_", author_list[i]) + '.mp4' - - with open(v_url,'wb') as file: #显示进度条 - for data in video.iter_content(chunk_size = chunk_size): + v_url = self.save + self.mode + "/" + self.nickname + '/' + \ + str(self.like_counts) + '、' + \ + re.sub(r'[\\/:*?"<>|\r\n]+', "_", + author_list[i]) + '.mp4' + + with open(v_url, 'wb') as file: # 显示进度条 + for data in video.iter_content(chunk_size=chunk_size): file.write(data) - size +=len(data) - print('\r'+'[下载进度]:%s%.2f%%' % ('>'*int(size*50/ content_size), float(size / content_size * 100)) ,end=' ') - end = time.time() #下载结束时间 - print('\n' + '[下载完成]:耗时: %.2f秒\n' % (end - start)) #输出下载用时时间 + size += len(data) + print('\r'+'[下载进度]:%s%.2f%%' % ( + '>'*int(size*50 / content_size), float(size / content_size * 100)), end=' ') + end = time.time() # 下载结束时间 + print('\n' + '[下载完成]:耗时: %.2f秒\n' % + (end - start)) # 输出下载用时时间 except Exception as error: print(error) input('下载视频出错!\r') + pass + continue except Exception as error: - #print(error) + # print(error) print('该页视频资源没有'+str(self.count)+'个,已为您跳过\r') break - #获取下一页信息 + + # 获取下一页信息 self.next_data(max_cursor) -#主模块执行 + +# 主模块执行 if __name__ == "__main__": RTK = TikTok() input('[ 完成 ]:已完成批量下载,输入任意键后退出:') - sys.exit() \ No newline at end of file + sys.exit() From ef9b23a13183782527edbf6cb1e84ca477ae9189 Mon Sep 17 00:00:00 2001 From: RobotJohns <37685728+RobotJohns@users.noreply.github.com> Date: Tue, 7 Dec 2021 16:52:26 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=20=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 路径 兼容 ,mac --- conf.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.ini b/conf.ini index a46d395..93dd2ec 100644 --- a/conf.ini +++ b/conf.ini @@ -12,7 +12,7 @@ count = 35 [save] #保存位置 你喜欢的名字 -url = .\Download\ +url = ./Download/ [mode] #下载模式选择 like为点赞 post为发布