最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用Python實(shí)現(xiàn)一個(gè)帶進(jìn)度條的URL批量下載工具(含GUI界面)

 更新時(shí)間:2025年07月03日 10:49:50   作者:XMYX-0  
本文將帶你一步一步實(shí)現(xiàn)一個(gè)支持 GUI 操作的批量 URL 下載工具,支持從 Excel 文件中讀取鏈接,自動(dòng)保存、記錄失敗鏈接,并帶有下載進(jìn)度條,非常適合運(yùn)營(yíng)、測(cè)試、爬蟲等批量下載需求,需要的朋友可以參考下

效果

請(qǐng)?zhí)砑訄D片描述

功能亮點(diǎn)

  • 支持從 .xlsx 文件讀取 URL 列表
  • 批量下載,支持失敗重試日志
  • 支持自定義保存目錄和子文件夾
  • 帶有下載進(jìn)度條和實(shí)時(shí)狀態(tài)提示
  • 全 GUI 操作,無(wú)需命令行
  • 支持文件名自動(dòng)提取,無(wú)需手動(dòng)命名

用到的依賴庫(kù)

以下是該項(xiàng)目中用到的第三方庫(kù):

pip install requests pandas openpyxl

openpyxl 是 pandas.read_excel 在讀取 .xlsx 文件時(shí)默認(rèn)依賴的后端。

項(xiàng)目結(jié)構(gòu)拆解與說(shuō)明

提取工具邏輯:如何從 URL 獲取文件名

from urllib.parse import urlparse

def extract_filename_from_url(url):
    path = urlparse(url).path
    filename = os.path.basename(path)
    return filename if filename else str(uuid.uuid4())
  • 使用 urlparse 提取路徑,再用 os.path.basename 獲取文件名;
  • 若鏈接無(wú)文件名(比如以 / 結(jié)尾),則使用 UUID 作為備選。

下載邏輯:requests 下載 + 失敗捕獲

def download_file(url, folder_path):
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        filename = extract_filename_from_url(url)
        save_path = os.path.join(folder_path, filename)
        with open(save_path, 'wb') as f:
            f.write(response.content)
        return True
    except:
        return False
  • 使用 requests.get() 獲取內(nèi)容;
  • 若出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤或 404,則返回 False,并記錄。

下載控制與進(jìn)度條更新

def start_download_with_progress(...):
    ...
    def process_next(index):
        ...
        # 下載成功/失敗計(jì)數(shù)
        # 寫入失敗日志
        # 更新進(jìn)度條 + 狀態(tài)文字
        # after(100, ...) 避免阻塞 GUI
  • 使用 progress_bar.after() 模擬異步,防止主線程卡死;
  • 實(shí)時(shí)更新進(jìn)度條和狀態(tài)標(biāo)簽;
  • 下載失敗寫入 download_fail.log,便于事后處理。

GUI 界面設(shè)計(jì)與交互邏輯

from tkinter import ...
  • 使用 Tkinter 實(shí)現(xiàn)圖形界面;
  • 包括:文件選擇按鈕、路徑輸入、保存子目錄輸入、進(jìn)度條、狀態(tài)文字、下載按鈕等;
  • 綁定 Entry<KeyRelease> 事件實(shí)現(xiàn)路徑預(yù)覽實(shí)時(shí)更新;
  • 使用 ttk.Progressbar 實(shí)現(xiàn)可視化進(jìn)度條。

界面示例(啟動(dòng)后):

在這里插入圖片描述

使用說(shuō)明

  1. 準(zhǔn)備一個(gè) .xlsx 文件,第一列為 URL 列,第一行可為表頭;
  2. 啟動(dòng)程序,點(diǎn)擊“選擇 Excel 文件”按鈕;
  3. 設(shè)置保存目錄與子文件夾名稱;
  4. 點(diǎn)擊“開始下載”,等待進(jìn)度條完成;
  5. 下載失敗的 URL 會(huì)記錄在 download_fail.log 文件中。

實(shí)用建議

  • 遇到下載失敗,可以手動(dòng)查看 download_fail.log 并嘗試重試;

源碼

import os
import uuid
import requests
import pandas as pd
from datetime import datetime
from urllib.parse import urlparse
from tkinter import Tk, Label, Button, filedialog, messagebox, Entry, StringVar, Frame
from tkinter import ttk

# 獲取當(dāng)前時(shí)間默認(rèn)文件夾名
def get_default_folder_name():
    return datetime.now().strftime('%Y%m%d%H%M')

# 提取 URL 文件名
def extract_filename_from_url(url):
    path = urlparse(url).path
    filename = os.path.basename(path)
    return filename if filename else str(uuid.uuid4())

# 單個(gè)下載邏輯
def download_file(url, folder_path):
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        filename = extract_filename_from_url(url)
        save_path = os.path.join(folder_path, filename)
        with open(save_path, 'wb') as f:
            f.write(response.content)
        return True
    except:
        return False

# 下載并更新 UI 進(jìn)度
def start_download_with_progress(urls, save_path, fail_log_path, progress_bar, status_label, start_button):
    total = len(urls)
    success = 0
    fail = 0

    def process_next(index):
        nonlocal success, fail

        if index >= total:
            status_label.config(text=f"? 下載完成,成功 {success} 個(gè),失敗 {fail} 個(gè)")
            start_button.config(state='normal')
            return

        url = urls[index]
        ok = download_file(url, save_path)
        if ok:
            success += 1
        else:
            fail += 1
            with open(fail_log_path, 'a', encoding='utf-8') as f:
                f.write(url + '\n')

        percent = int(((index + 1) / total) * 100)
        progress_bar['value'] = percent
        status_label.config(text=f"進(jìn)度:{percent}%  | 成功:{success}  失?。簕fail}")
        progress_bar.update()

        # 延遲調(diào)用下一項(xiàng),避免 UI 卡死
        progress_bar.after(100, lambda: process_next(index + 1))

    process_next(0)

# 下載啟動(dòng)邏輯
def start_download(selected_file, folder_name_var, base_path_var, full_path_label_var,
                   progress_bar, status_label, start_button):
    if not selected_file:
        messagebox.showwarning("警告", "請(qǐng)先選擇 Excel 文件")
        return

    folder_name = folder_name_var.get().strip() or get_default_folder_name()
    base_path = base_path_var.get().strip() or os.getcwd()
    save_path = os.path.join(base_path, folder_name)
    os.makedirs(save_path, exist_ok=True)
    full_path_label_var.set(f"保存路徑:{save_path}")

    try:
        df = pd.read_excel(selected_file, usecols=[0])
        urls = df.iloc[:, 0].astype(str).str.strip()
        urls = urls[urls != '']  # 過濾空字符串
        urls = urls.tolist()

        if not urls:
            messagebox.showinfo("提示", "未檢測(cè)到有效 URL")
            return

        # 清空失敗記錄
        failed_log_path = os.path.join(save_path, 'download_fail.log')
        with open(failed_log_path, 'w', encoding='utf-8') as f:
            pass

        progress_bar['maximum'] = 100
        progress_bar['value'] = 0
        progress_bar.pack(pady=10)
        status_label.pack()
        start_button.config(state='disabled')

        start_download_with_progress(urls, save_path, failed_log_path,
                                     progress_bar, status_label, start_button)

    except Exception as e:
        messagebox.showerror("錯(cuò)誤", f"下載過程中發(fā)生錯(cuò)誤:{e}")

# 文件選擇
def choose_file(selected_file_var, file_label):
    file_path = filedialog.askopenfilename(filetypes=[("Excel 文件", "*.xlsx")])
    if file_path:
        selected_file_var.set(file_path)
        file_label.config(text=f"已選擇文件:{os.path.basename(file_path)}")

# 保存路徑選擇
def select_directory(base_path_var, folder_name_var, full_path_label_var):
    selected = filedialog.askdirectory()
    if selected:
        base_path_var.set(selected)
        update_full_path_label(folder_name_var, base_path_var, full_path_label_var)

# 路徑標(biāo)簽更新
def update_full_path_label(folder_name_var, base_path_var, full_path_label_var):
    folder_name = folder_name_var.get().strip() or get_default_folder_name()
    base_path = base_path_var.get().strip() or os.getcwd()
    full_path_label_var.set(f"保存路徑:{os.path.join(base_path, folder_name)}")

# 主界面
def create_gui():
    root = Tk()
    root.title("URL 批量下載工具 作者:XMYX-0")
    root.geometry("620x460")

    selected_file_var = StringVar()
    folder_name_var = StringVar(value=get_default_folder_name())
    base_path_var = StringVar(value=os.getcwd())
    full_path_label_var = StringVar()

    # UI 元素
    Label(root, text="1. 選擇包含 URL 的 Excel 文件(.xlsx)", font=("微軟雅黑", 11)).pack(pady=10)
    file_label = Label(root, text="尚未選擇文件", font=("微軟雅黑", 10), fg="gray")
    file_label.pack()
    Button(root, text="選擇 Excel 文件", font=("微軟雅黑", 10),
           command=lambda: choose_file(selected_file_var, file_label)).pack(pady=5)

    Label(root, text="2. 設(shè)置保存目錄", font=("微軟雅黑", 11)).pack(pady=10)
    Label(root, text="保存子目錄名稱:", font=("微軟雅黑", 10)).pack()
    folder_entry = Entry(root, textvariable=folder_name_var, font=("微軟雅黑", 10), width=35)
    folder_entry.pack()

    path_frame = Frame(root)
    path_frame.pack(pady=10)
    Label(path_frame, text="保存路徑:", font=("微軟雅黑", 10)).grid(row=0, column=0, padx=5)
    path_entry = Entry(path_frame, textvariable=base_path_var, font=("微軟雅黑", 10), width=35)
    path_entry.grid(row=0, column=1)
    Button(path_frame, text="瀏覽", command=lambda: select_directory(base_path_var, folder_name_var, full_path_label_var)).grid(row=0, column=2, padx=5)

    update_full_path_label(folder_name_var, base_path_var, full_path_label_var)
    Label(root, textvariable=full_path_label_var, font=("微軟雅黑", 9), fg="gray").pack()

    progress_bar = ttk.Progressbar(root, length=400)
    status_label = Label(root, text="", font=("微軟雅黑", 10))

    start_button = Button(root, text="? 開始下載", font=("微軟雅黑", 12), bg="#4CAF50", fg="white",
                          command=lambda: start_download(
                              selected_file_var.get(),
                              folder_name_var,
                              base_path_var,
                              full_path_label_var,
                              progress_bar,
                              status_label,
                              start_button))
    start_button.pack(pady=20)

    folder_entry.bind("<KeyRelease>", lambda e: update_full_path_label(folder_name_var, base_path_var, full_path_label_var))
    path_entry.bind("<KeyRelease>", lambda e: update_full_path_label(folder_name_var, base_path_var, full_path_label_var))

    Label(root, text="注意:Excel 的第一行為標(biāo)題,從第二行開始讀取 URL", font=("微軟雅黑", 9), fg="gray").pack(pady=10)

    root.mainloop()

if __name__ == "__main__":
    create_gui()

以上就是利用Python實(shí)現(xiàn)一個(gè)帶進(jìn)度條的URL批量下載工具的詳細(xì)內(nèi)容,更多關(guān)于Python URL批量下載工具的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python3壓縮和解壓文件案例總結(jié)

    python3壓縮和解壓文件案例總結(jié)

    壓縮和解壓縮是日常常用的操作,不管是windows上圖形界面的操作,還是linux上用命令來(lái)進(jìn)行壓縮解壓縮,總的而言都還是比較方便的,本文通過案例代碼講解了python3壓縮和解壓文件的方法,
    2023-02-02
  • Python實(shí)現(xiàn)合成多張圖片到PDF格式

    Python實(shí)現(xiàn)合成多張圖片到PDF格式

    在日常生活中,經(jīng)常會(huì)遇到需要提交身份證正反面證明資料的情況,而且這些網(wǎng)站大部分只接受pdf格式,這時(shí)候我們就需要把身份證正反面兩張圖片合成為一個(gè)pdf文件。本文將為大家提供用Python實(shí)現(xiàn)這一要求的方法,需要的可以參考一下
    2022-02-02
  • 如何使用PyTorch實(shí)現(xiàn)自由的數(shù)據(jù)讀取

    如何使用PyTorch實(shí)現(xiàn)自由的數(shù)據(jù)讀取

    這篇文章主要給大家介紹了關(guān)于如何使用PyTorch實(shí)現(xiàn)自由的數(shù)據(jù)讀取的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • python之pygame模塊實(shí)現(xiàn)飛機(jī)大戰(zhàn)完整代碼

    python之pygame模塊實(shí)現(xiàn)飛機(jī)大戰(zhàn)完整代碼

    這篇文章主要為大家詳細(xì)介紹了python之pygame模塊實(shí)現(xiàn)飛機(jī)大戰(zhàn)完整代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • python中常用排序操作sort方法和sorted函數(shù)的使用超詳細(xì)講解(內(nèi)置模板代碼!)

    python中常用排序操作sort方法和sorted函數(shù)的使用超詳細(xì)講解(內(nèi)置模板代碼!)

    這篇文章主要介紹了Python中的排序方法,包括sort()方法和sorted()函數(shù)的使用,sort()方法用于列表,對(duì)原列表進(jìn)行排序,文章還提供了一些排序案例模板代碼,以解決實(shí)際問題,需要的朋友可以參考下
    2025-02-02
  • python中的二叉樹排序用法及說(shuō)明

    python中的二叉樹排序用法及說(shuō)明

    這篇文章主要介紹了python中的二叉樹排序用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-03-03
  • python基礎(chǔ)教程之類class定義使用方法

    python基礎(chǔ)教程之類class定義使用方法

    Python中的類(Class)是一個(gè)抽象的概念,比函數(shù)還要抽象,這也就是Python的核心概念,面對(duì)對(duì)象的編程方法(OOP),其它如:Java、C++等都是面對(duì)對(duì)象的編程語(yǔ)言
    2014-02-02
  • python小技巧之批量抓取美女圖片

    python小技巧之批量抓取美女圖片

    學(xué)了python以后,知道python的抓取功能其實(shí)是非常強(qiáng)大的,當(dāng)然不能浪費(fèi),呵呵。我平時(shí)很喜歡美女圖,呵呵,程序員很苦悶的,看看美女,養(yǎng)養(yǎng)眼,增加點(diǎn)樂趣。好,那就用python寫一個(gè)美女圖自動(dòng)抓取程序吧~~
    2014-06-06
  • python SOCKET編程基礎(chǔ)入門

    python SOCKET編程基礎(chǔ)入門

    這篇文章主要介紹了python SOCKET編程基礎(chǔ)入門的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • python復(fù)制列表時(shí)[:]和[::]之間有什么區(qū)別

    python復(fù)制列表時(shí)[:]和[::]之間有什么區(qū)別

    這篇文章主要給大家介紹了關(guān)于python復(fù)制列表時(shí)[:]和[::]之間有什么區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-10-10

最新評(píng)論

德昌县| 疏勒县| 吉安市| 中宁县| 苍溪县| 旅游| 万年县| 衡山县| 兴文县| 深水埗区| 山阳县| 武安市| 绥江县| 梅州市| 盐源县| 佛冈县| 林甸县| 彩票| 青海省| 凤山市| 湖南省| 无为县| 安泽县| 通海县| 苏尼特右旗| 榆林市| 田阳县| 通州区| 招远市| 靖边县| 锡林浩特市| 德清县| 南阳市| 广平县| 淮安市| 秦安县| 鱼台县| 伊宁市| 司法| 扬州市| 保山市|