【源码+打包】【更新】抖音视频下载之指定作者批量下载

编辑:佚名 日期:2024-08-26 05:16 / 人气:

本帖最后由 kiopc 于 2023-5-23 19:27 编辑

用之前打包的exe文件去下载视频的时候,发现不能下载了,于是找到源码重新修改了一下.

原帖地址:https://www.52pojie.cn/thread-1668793-1-1.html

感谢@neteast

使用方法:




只用后面的框起来的id


把框起来的id复制到软件的【作者id】,点:【获取信息】,此时右边会显示多少条作品,然后点【开始下载】就行了


打包好的exe文件暂停下载,有反馈说重复下载的问题,修复后再提供下载,感谢反馈的童鞋


另外不支持直播录制!!!

源码:
[Python] 纯文本查看 复制代码
# -*- encoding:utf-8 -*-
"""
File   :   downVedio.py
Time    :   2023-05-17 14:00
Software:   IntelliJ IDEA
"""
import os
import re
import subprocess
import threading
import time
import tkinter as tk
import tkinter.font as tkFont
import warnings
from datetime import datetime

import requests

LOG_LINE_NUM=0


class App:
    def __init__(self, root):
        self.test=False
        self.initUi(root)
        self.initData()
        self.testData()

    def testData(self):
        if (self.test):
            self.GLineEdit_332.insert(0, '2p5EEc9')  # 2sWmMkb
            self.GButton_333['state']='active'

    def initData(self):

        self.nickname='未找到该ID用户或者暂未发布作品'
        self.status_download=True
        self.tag='odd'
        self.session=requests.Session()
        self.session.headers.update({
            'User-Agent': "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C28 Safari/419.3"})
        self.starurl=None
        self.baseurl='https://v.douyin.com/'
        self.baseinfo='https://www.iesdouyin.com/web/api/v2/user/info/?'
        self.userinfourl=None

    def initUi(self, root):
        # setting title
        root.title("DYDownloader neteast@52pojie")
        # setting window size
        width=897
        height=533
        screenwidth=root.winfo_screenwidth()
        screenheight=root.winfo_screenheight()
        alignstr='%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        root.geometry(alignstr)
        root.resizable(width=False, height=False)

        ft=tkFont.Font(family='宋体', size=10)
        GLabel_515=tk.Label(root)
        GLabel_515["font"]=ft
        GLabel_515["justify"]="center"
        GLabel_515["text"]="作者ID"
        GLabel_515.place(x=20, y=10, width=47, height=30)

        self.GLineEdit_508=tk.Entry(root)
        self.GLineEdit_508["borderwidth"]="1px"
        self.GLineEdit_508["justify"]="center"
        self.GLineEdit_508["text"]="path"
        self.GLineEdit_508['state']='readonly'
        self.GLineEdit_508.place(x=90, y=50, width=610, height=30)

        self.GLineEdit_332=tk.Entry(root)
        self.GLineEdit_332["borderwidth"]="1px"
        self.GLineEdit_332["justify"]="center"
        self.GLineEdit_332["text"]="url"
        self.GLineEdit_332.place(x=90, y=10, width=231, height=30)

        self.GButton_333=tk.Button(root)
        self.GButton_333["justify"]="center"
        self.GButton_333["text"]="开始下载"
        self.GButton_333.place(x=710, y=50, width=90, height=30)
        self.GButton_333['state']='disable'
        self.GButton_333["command"]=self.GButton_333_command

        ft2=tkFont.Font(family='宋体', size=12)
        self.GLineEdit_428=tk.Text(root)
        self.GLineEdit_428["borderwidth"]="1px"
        self.GLineEdit_428["font"]=ft2
        self.GLineEdit_428.place(x=10, y=90, width=881, height=427)

        self.GButton_676=tk.Button(root)
        self.GButton_676["font"]=ft
        self.GButton_676["justify"]="center"
        self.GButton_676["text"]="停止下载"
        self.GButton_676['state']='disable'
        self.GButton_676.place(x=810, y=50, width=74, height=30)
        self.GButton_676["command"]=self.GButton_676_command

        GButton_701=tk.Button(root)
        GButton_701["font"]=ft
        GButton_701["justify"]="center"
        GButton_701["text"]="获取信息"
        GButton_701.place(x=330, y=10, width=70, height=30)
        GButton_701["command"]=self.GButton_701_command

        GLabel_100=tk.Label(root)
        GLabel_100["font"]=ft
        GLabel_100["justify"]="center"
        GLabel_100["text"]="昵称"
        GLabel_100.place(x=410, y=10, width=43, height=30)

        GLabel_1=tk.Label(root)
        GLabel_1["font"]=ft
        GLabel_1["justify"]="center"
        GLabel_1["text"]="条作品"
        GLabel_1.place(x=790, y=10, width=76, height=30)

        self.GLineEdit_690=tk.Entry(root)
        self.GLineEdit_690["borderwidth"]="1px"
        self.GLineEdit_690["font"]=ft
        self.GLineEdit_690["justify"]="center"
        self.GLineEdit_690["text"]="条作品"
        self.GLineEdit_690['state']='readonly'
        self.GLineEdit_690.place(x=710, y=10, width=90, height=30)

        self.GLineEdit_281=tk.Entry(root)
        self.GLineEdit_281["borderwidth"]="1px"
        self.GLineEdit_281["font"]=ft
        self.GLineEdit_281["fg"]="#333333"
        self.GLineEdit_281["justify"]="center"
        self.GLineEdit_281["text"]="昵称"
        self.GLineEdit_281['state']='readonly'
        self.GLineEdit_281.place(x=460, y=10, width=240, height=31)

        GButton_55=tk.Button(root)
        GButton_55["bg"]="#efefef"
        GButton_55["font"]=ft
        GButton_55["fg"]="#000000"
        GButton_55["justify"]="center"
        GButton_55["text"]="保存路径"
        GButton_55["relief"]="groove"
        GButton_55.place(x=10, y=50, width=70, height=30)
        GButton_55["command"]=self.GButton_55_command

    def GButton_55_command(self):  # 打开文件夹
        path=self.GLineEdit_508.get()
        if path:
            self.open_fp(path)

    def GButton_701_command(self):  # 获取信息
        authorId=self.GLineEdit_332.get()
        self.status_download=True
        if authorId:
            self.starurl=self.baseurl + authorId

            self._log(f'{"-" * 20}开始查询,请稍等{"-" * 20}')
            obj1=threading.Thread(target=self.analysis, args=({False}))
            obj1.setDaemon(True)
            obj1.start()
        else:
            self._log("请输入作者ID")

    def GButton_676_command(self):  # 停止下载
        self.status_download=False
        self.GButton_676['state']='disable'

    def GButton_333_command(self):  # 开始下载
        self.status_download=True
        authorId=self.GLineEdit_332.get()
        if authorId:
            self.starurl=self.baseurl + authorId
            self._log(f'{"-" * 20}准备下载,请稍等{"-" * 20}')
            self.GButton_333['state']='disable'
            self.GButton_676['state']='active'
            self.pcursor=''
            obj1=threading.Thread(target=self.analysis, args=({True}))
            obj1.setDaemon(True)
            obj1.start()
        else:
            self._log("请输入作者ID")

    def analysis(self, flag):
        req=self._requests('get', self.starurl, decode_level=3)
        sp=req.url.split('?')
        if len(sp)==2:
            param=sp[1]
        else:
            self._log(f'{"-" * 20}获取数据失败,请检查主播ID是否正确{"-" * 20}')
            return
        self.userinfourl=self.baseinfo + param
        userinfo=self._requests('get', self.userinfourl, decode_level=2)
        self.nickname=userinfo['user_info']['nickname']
        aweme_count=userinfo['user_info']['aweme_count']
        if not flag:
            self._log(f'{"-" * 20}查询完成!{"-" * 20}')
            filepath=os.getcwd() + '\\' + 'dydownloads' + '\\' + self.nickname
            self.GLineEdit_690['state']='normal'
            self.GLineEdit_281['state']='normal'
            self.GLineEdit_508['state']='normal'
            self.GLineEdit_508.delete(0, 'end')
            self.GLineEdit_281.delete(0, 'end')
            self.GLineEdit_690.delete(0, 'end')
            self.GLineEdit_690.insert(0, f'{aweme_count}')
            self.GLineEdit_281.insert(0, f'{self.nickname}')
            self.GLineEdit_508.insert(0, f'{filepath}')
            self.GLineEdit_690['state']='readonly'
            self.GLineEdit_281['state']='readonly'
            self.GLineEdit_508['state']='readonly'
            self.GButton_333['state']='active'
        else:
            self._log(f'{"-" * 20}开始下载{"-" * 20}')
            max_cursor=0
            video_has_more=True
            icount=0;
            while video_has_more and self.status_download:
                json_url=f'https://www.iesdouyin.com/web/api/v2/aweme/post/?{param}&' \
                           f'count=21&max_cursor={max_cursor}'
                req=self._requests('get', json_url, decode_level=2)
                video_has_more=req['has_more']
                max_cursor=req['max_cursor']
                video_list=req['aweme_list']
                # req['aweme_list']中返回的是一个列表,其中元素是json数组,需要再次对这个数组进行解析,提取到正确的video_url
                for video in video_list:
                    if not self.status_download:
                        self._log(f'{"-" * 20}已停止下载video!{"-" * 20}')
                        break
                    icount +=1
                    self.download_video(video, icount)
            self._log(f'{"-" * 20}全部{aweme_count}个视频已下载完成{icount}个!{"-" * 20}')

    def download_video(self, video, num=0):
        try:
            filepath=os.getcwd() + '/' + 'dydownloads' + '/' + self.nickname
            caption=video['desc']  # title
            vid=video['video']['play_addr']['uri'] # video link
            caption=re.sub('[ \/:*?"<>|
	]', '', caption)
            likeCount=video['statistics']['digg_count']
            comment_count=video['statistics']['comment_count']
            caption=caption[:40] if len(caption) > 40 else caption
            self._log(f'{num:0>3d}{caption} {comment_count}评论 {likeCount}人点赞')
            caption=caption[:28] if len(caption) > 28 else caption
            if caption:
                download_url=f'https://aweme.snssdk.com/aweme/v1/play/?video_id={vid}&ratio=1080p'
                video_data=self._requests('get', download_url, decode_level=3).content
                self.save_video(os.path.normpath(filepath),
                                f'{num:0>3d}_' + caption + '_' + vid + '.mp4', video_data,
                                download_url)
        except Exception as e:
            print(e)
            self._log(f'获取数据失败,请检查主播ID是否正确,也可能cookies已过期!')

    def save_video(self, path, filename, video_data, url):
        if not os.path.exists(path):
            os.makedirs(path)
        with open(os.path.normpath(os.path.join(path, filename)), 'wb') as f:
            f.write(video_data)
            now_time=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            self._log(f'  状态:[下载完成]')

    def open_fp(self, fp):
        """
        打开文件或文件夹
        :param fp: 需要打开的文件或文件夹路径
        """
        import platform
        systemType: str=platform.platform()  # 获取系统类型
        if 'mac' in systemType:  # 判断以下当前系统类型
            fp: str=fp.replace("\\", "/")  # mac系统下,遇到`\\`让路径打不开,不清楚为什么哈,觉得没必要的话自己可以删掉啦,18行那条也是
            subprocess.call(["open", fp])
        else:
            fp: str=fp.replace("/", "\\")  # win系统下,有时`/`让路径打不开
            try:
                os.startfile(fp)
            except:
                self._log(f'{"-" * 20}文件还未下载{"-" * 20}')

    def _requests(self, method, url, decode_level=1, retry=0, timeout=15, **kwargs):
        if method in ["get", "post"]:
            for _ in range(retry + 1):
                try:
                    warnings.filterwarnings('ignore')
                    response=getattr(self.session, method)(url, timeout=timeout, verify=False, **kwargs)
                    return response.text if decode_level==1 else response.json() if decode_level==2 else response
                except Exception as e:
                    self._log(e)

        return None

    def _log(self, logmsg):
        global LOG_LINE_NUM
        current_time=self.get_current_time()
        logmsg_in=str(current_time) + " " + str(logmsg) + "
"  # 换行
        self.GLineEdit_428.tag_config("even", background='#e0e0e0')
        self.GLineEdit_428.tag_config("odd", background='#ffffff')
        self.tag='odd' if self.tag=='even' else 'even'
        if LOG_LINE_NUM <=22:

            self.GLineEdit_428.insert('end', logmsg_in, self.tag)
            LOG_LINE_NUM=LOG_LINE_NUM + 1
        else:
            self.GLineEdit_428.delete(1.0, 2.0)
            self.GLineEdit_428.insert('end', logmsg_in, self.tag)

    def get_current_time(self):
        current_time=time.strftime('%H:%M:%S', time.localtime(time.time()))
        return current_time


if __name__=="__main__":
    root=tk.Tk()
    app=App(root)
    root.mainloop()




现在致电 13988889999 OR 查看更多联系方式 →

Top 回顶部

平台注册入口