使用python下载抖音视频

##主功能函数

import os
import time
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.edge.options import Options

def generate_unique_filename(directory, base_name, extension):
    """
    根据基础文件名和扩展名生成唯一文件名。
    """
    counter = 1
    file_name = f"{base_name}{extension}"
    while os.path.exists(os.path.join(directory, file_name)):
        file_name = f"{base_name}{counter}{extension}"
        counter += 1
    return file_name

def Download(target_url):
    # 设置 Edge 浏览器服务
    service = Service(EdgeChromiumDriverManager().install())
    # 获取桌面路径
    desktop = os.path.join(os.path.expanduser("~"), "Desktop")
    base_name = "长离"
    image_extension = ".jpg"
    video_extension = ".mp4"

    options = Options()
    options.add_argument("--headless")  # 开启无头模式
    options.add_argument("--disable-gpu")  # 禁用 GPU(提高兼容性)

    try:
        print(f"提取到的链接: {target_url}")

        # 启动浏览器并导航到链接
        driver = webdriver.Edge(options=options, service=service)
        driver.get(target_url)

        # 等待页面加载完成
        time.sleep(5)

        try:
            # 先尝试查找 <img> 元素
            img_element = WebDriverWait(driver, 15).until(
                EC.presence_of_element_located((By.CLASS_NAME, 'bSslRkqL'))
            )

            # 获取 <img> 的 src 属性
            img_src = img_element.get_attribute('src')
            if img_src:
                if img_src.startswith('//'):
                    img_src = 'https:' + img_src
                print(f"图片链接: {img_src}")

                # 模拟浏览器请求头
                headers = {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
                    "Referer": target_url,
                }

                # 下载图片
                unique_image_name = generate_unique_filename(desktop, base_name, image_extension)
                image_path = os.path.join(desktop, unique_image_name)
                response = requests.get(img_src, headers=headers, stream=True)
                if response.status_code == 200:
                    with open(image_path, 'wb') as file:
                        for chunk in response.iter_content(chunk_size=1024):
                            file.write(chunk)
                    print(f"图片已保存到: {image_path}")
                else:
                    print(f"下载失败: {img_src} (状态码: {response.status_code})")
            else:
                print("未找到有效的 src 属性。")

        except Exception:
            print("未找到 <img> 元素,尝试查找 <video> 元素。")

            try:
                # 尝试查找 <video> 元素
                video_element = WebDriverWait(driver, 15).until(
                    EC.presence_of_element_located((By.TAG_NAME, 'video'))
                )

                # 获取 <video> 的 HTML
                video_html = video_element.get_attribute('outerHTML')

                # 使用 BeautifulSoup 解析 HTML
                soup = BeautifulSoup(video_html, 'html.parser')
                source_tags = soup.find_all('source')

                if source_tags:
                    src = source_tags[0].get('src')
                    if src:
                        if src.startswith('//'):
                            src = 'https:' + src
                        print(f"视频链接: {src}")

                        # 模拟浏览器请求头
                        headers = {
                            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
                            "Referer": target_url,
                        }

                        # 下载视频
                        unique_video_name = generate_unique_filename(desktop, base_name, video_extension)
                        video_path = os.path.join(desktop, unique_video_name)
                        response = requests.get(src, headers=headers, stream=True)
                        if response.status_code == 200:
                            with open(video_path, 'wb') as file:
                                for chunk in response.iter_content(chunk_size=1024):
                                    file.write(chunk)
                            print(f"视频已保存到: {video_path}")
                        else:
                            print(f"下载失败: {src} (状态码: {response.status_code})")
                    else:
                        print("未找到有效的 src 属性。")
                else:
                    print("未找到 <source> 标签。")

            except Exception:
                print("未找到 <video> 或 <img> 元素。")

    except Exception as e:
        print("发生错误:", e)
    finally:
        if 'driver' in locals():
            driver.quit()

##简单图形界面实现

import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk, ImageFont, ImageDraw  # 用于处理图片和字体
import pyperclip
from download import Download
import re
import sys
import os

# 窗口大小定义
WIDTH = 1366
HEIGHT = 768

# 创建窗口
root = tk.Tk()
root.title("抖音视频下载器")  # 修改窗口名称
root.geometry(f"{WIDTH}x{HEIGHT}")  # 使用WIDTH和HEIGHT设置窗口大小

# 加载自定义字体
font_path = os.path.join(os.getcwd(), "00.otf")  # 同目录下的字体文件
try:
    from tkinter.font import Font
    custom_font = Font(family="CustomFont", size=16)
except Exception as e:
    print(f"无法加载字体: {e}")
    custom_font = ("Arial", 16)  # 使用默认字体作为备选

# 创建 Canvas 用于显示背景
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, highlightthickness=0)
canvas.pack(fill="both", expand=True)

# 加载背景图片
try:
    original_image = Image.open("background.png")
    background_image = ImageTk.PhotoImage(original_image.resize((WIDTH, HEIGHT)))
    canvas_image = canvas.create_image(0, 0, anchor="nw", image=background_image)
except Exception as e:
    print(f"无法加载背景图片: {e}")
    root.quit()

# 动态调整背景图片大小
def resize_image(event):
    new_width = event.width
    new_height = event.height
    resized_image = original_image.resize((new_width, new_height))
    new_background = ImageTk.PhotoImage(resized_image)
    canvas.itemconfig(canvas_image, image=new_background)
    canvas.image = new_background  # 防止垃圾回收

root.bind("<Configure>", resize_image)

# 文本框相关
input_text = tk.StringVar()

def on_paste():
    input_text.set(input_text.get() + pyperclip.paste())

def on_button_click():
    # 先在日志中显示“处理中,请稍后”
    log_text.insert(tk.END, "处理中,请稍后...\n")
    log_text.see(tk.END)  # 自动滚动到末尾
    log_text.update_idletasks()  # 强制刷新界面以显示消息

    # 处理按钮点击事件
    text = input_text.get()
    match = re.search(r'https://\S+', text)
    if match:
        link = match.group()
        Download(link)  # 调用下载函数
    else:
        log_text.insert(tk.END, "未检测到有效链接。\n")
    input_text.set("")  # 清空输入框

# 输入框居中
input_entry = tk.Entry(root, textvariable=input_text, font=("Arial", 24), width=30)
input_entry.place(x=WIDTH // 2 - 250, y=HEIGHT // 2 - 20)

# 按钮中线对称
button_offset = 150  # 按钮距离输入框的水平距离

paste_button = tk.Button(root, text="粘贴", font=("Arial", 16), command=on_paste)
paste_button.place(x=WIDTH // 2 - button_offset - 100, y=HEIGHT // 2 + 50)

submit_button = tk.Button(root, text="解析", font=("Arial", 16), command=on_button_click)
submit_button.place(x=WIDTH // 2 + button_offset +50, y=HEIGHT // 2 + 50)

# 用于显示日志的 Text 小部件
log_text = tk.Text(root, font=("Arial", 14), fg="black", bg="white", height=6, width=120, highlightthickness=0)
log_text.place(relx=0.5, rely=1.0, anchor="s", y=-10)  # 底部对齐,距离底部 10 像素

# 重定向 print 输出到日志窗口
class TextRedirector:
    def __init__(self, widget):
        self.widget = widget

    def write(self, string):
        self.widget.insert(tk.END, string)
        self.widget.see(tk.END)  # 自动滚动到末尾

    def flush(self):
        pass  # 必须实现以兼容 `sys.stdout`

sys.stdout = TextRedirector(log_text)

# 运行主循环
root.mainloop()

注:不需要图形界面的可以只运行主功能函数,需要图形界面则两部分放于同一路径下,且需放上 00.otf (字体文件)、background.png(界面背景图片)。
输入示例:8.28 复制打开抖音,看看【𝘽𝙖𝙜𝙖酱的呦西的作品】鸣潮 | 【年度混剪】系列~ 耗时45时 仅此3分… https://v.douyin.com/iUhQHRNR/ 08/11 trR:/ E@u.Fh
(直接放入分享文案即可)

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐