style: 统一代码格式并改进异常处理

- 将多行字符串调整为符合PEP 8的格式
- 统一使用显式的异常捕获(except Exception)
- 改进线程的daemon设置方式
- 移除未使用的异常变量和导入
- 修复文件末尾的换行符问题
This commit is contained in:
2026-02-10 16:57:31 +08:00
parent 92619edcdb
commit bccffc006a
11 changed files with 71 additions and 36 deletions
Binary file not shown.
Binary file not shown.
+10 -10
View File
@@ -1,6 +1,7 @@
import requests import requests
import time import time
def download_file(url, filepath, referer=None, log_callback=None): def download_file(url, filepath, referer=None, log_callback=None):
""" """
[Data Layer] 文件下载执行器 [Data Layer] 文件下载执行器
@@ -9,7 +10,11 @@ def download_file(url, filepath, referer=None, log_callback=None):
try: try:
# 根据不同平台可能需要调整 Headers # 根据不同平台可能需要调整 Headers
headers = { headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
),
} }
# 优先使用传入的 referer # 优先使用传入的 referer
@@ -17,20 +22,14 @@ def download_file(url, filepath, referer=None, log_callback=None):
headers["Referer"] = referer headers["Referer"] = referer
else: else:
# 简单的 Referer 区分 (保留旧逻辑作为后备) # 简单的 Referer 区分 (保留旧逻辑作为后备)
if ( if "bilibili.com" in url or "hdslb.com" in url or "bilivideo.com" in url:
"bilibili.com" in url
or "hdslb.com" in url
or "bilivideo.com" in url
):
headers["Referer"] = "https://www.bilibili.com/" headers["Referer"] = "https://www.bilibili.com/"
else: else:
headers["Referer"] = "https://www.douyin.com/" headers["Referer"] = "https://www.douyin.com/"
for i in range(3): for i in range(3):
try: try:
response = requests.get( response = requests.get(url, headers=headers, stream=True, timeout=20)
url, headers=headers, stream=True, timeout=20
)
if response.status_code == 200: if response.status_code == 200:
with open(filepath, "wb") as f: with open(filepath, "wb") as f:
for chunk in response.iter_content(chunk_size=1024 * 1024): for chunk in response.iter_content(chunk_size=1024 * 1024):
@@ -41,7 +40,8 @@ def download_file(url, filepath, referer=None, log_callback=None):
if i == 2: if i == 2:
if log_callback: if log_callback:
log_callback( log_callback(
f"下载请求失败: Status {response.status_code} | URL: {url[:30]}..." f"下载请求失败: Status {response.status_code} "
f"| URL: {url[:30]}..."
) )
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
if i == 2: if i == 2:
Binary file not shown.
Binary file not shown.
+13 -5
View File
@@ -5,13 +5,17 @@ import json
import requests import requests
import concurrent.futures import concurrent.futures
from datetime import datetime from datetime import datetime
from tkinter import messagebox
from DrissionPage import ChromiumPage, ChromiumOptions from DrissionPage import ChromiumPage, ChromiumOptions
from src.downloader import download_file from src.downloader import download_file
def run_bilibili_task( def run_bilibili_task(
target_url, target_count, save_root, browser_path, log_callback, finish_callback target_url,
target_count,
save_root,
browser_path,
log_callback,
finish_callback=None,
): ):
""" """
[Control Layer] B站核心业务流程 [Control Layer] B站核心业务流程
@@ -85,7 +89,7 @@ def run_bilibili_task(
next_btn.click() next_btn.click()
no_new_data_count = 0 no_new_data_count = 0
time.sleep(2) time.sleep(2)
except: except Exception:
pass pass
else: else:
no_new_data_count = 0 no_new_data_count = 0
@@ -146,7 +150,7 @@ def run_bilibili_task(
if dp: if dp:
try: try:
dp.close() dp.close()
except: except Exception:
pass pass
finally: finally:
# 这里需要一种机制通知UI线程结束,或者由UI层处理 # 这里需要一种机制通知UI线程结束,或者由UI层处理
@@ -218,7 +222,11 @@ def get_bilibili_play_url(bvid):
""" """
url = f"https://www.bilibili.com/video/{bvid}" url = f"https://www.bilibili.com/video/{bvid}"
headers = { headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36"
),
"Referer": "https://www.bilibili.com/", "Referer": "https://www.bilibili.com/",
} }
try: try:
+28 -10
View File
@@ -5,7 +5,15 @@ from datetime import datetime
from DrissionPage import ChromiumPage, ChromiumOptions from DrissionPage import ChromiumPage, ChromiumOptions
from src.downloader import download_file from src.downloader import download_file
def run_douyin_task(target_url, target_count, save_root, browser_path, log_callback, finish_callback):
def run_douyin_task(
target_url,
target_count,
save_root,
browser_path,
log_callback,
finish_callback,
):
""" """
[Control Layer] 抖音核心业务流程 [Control Layer] 抖音核心业务流程
1. 启动浏览器 1. 启动浏览器
@@ -53,7 +61,7 @@ def run_douyin_task(target_url, target_count, save_root, browser_path, log_callb
): ):
collected_works.append(aweme) collected_works.append(aweme)
found_new = True found_new = True
except: except Exception:
pass pass
log_callback(f"已获取作品信息: {len(collected_works)}/{target_count}") log_callback(f"已获取作品信息: {len(collected_works)}/{target_count}")
@@ -99,7 +107,11 @@ def run_douyin_task(target_url, target_count, save_root, browser_path, log_callb
file_name_base = f"{date_str}({count_idx})" file_name_base = f"{date_str}({count_idx})"
download_tasks.append( download_tasks.append(
{"work": work, "index": index, "file_name_base": file_name_base} {
"work": work,
"index": index,
"file_name_base": file_name_base,
}
) )
# 使用线程池执行下载 # 使用线程池执行下载
@@ -115,7 +127,7 @@ def run_douyin_task(target_url, target_count, save_root, browser_path, log_callb
len(works_to_process), len(works_to_process),
save_root, save_root,
task["file_name_base"], task["file_name_base"],
log_callback log_callback,
) )
) )
@@ -133,12 +145,15 @@ def run_douyin_task(target_url, target_count, save_root, browser_path, log_callb
if dp: if dp:
try: try:
dp.close() dp.close()
except: except Exception:
pass pass
finally: finally:
pass pass
def process_douyin_work(work, index, total_count, save_root, file_name_base, log_callback):
def process_douyin_work(
work, index, total_count, save_root, file_name_base, log_callback
):
""" """
[Data Layer] 单个任务处理逻辑 (Worker) [Data Layer] 单个任务处理逻辑 (Worker)
判断作品类型(视频/图文),生成路径并调用下载器 判断作品类型(视频/图文),生成路径并调用下载器
@@ -148,9 +163,11 @@ def process_douyin_work(work, index, total_count, save_root, file_name_base, log
if "images" in work and work["images"]: if "images" in work and work["images"]:
is_video = False is_video = False
log_callback( msg = (
f"[{index + 1}/{total_count}] {file_name_base} | {'视频' if is_video else '图文'} | 下载中..." f"[{index + 1}/{total_count}] {file_name_base} | "
f"{'视频' if is_video else '图文'} | 下载中..."
) )
log_callback(msg)
if is_video: if is_video:
video_url = work["video"]["play_addr"]["url_list"][0] video_url = work["video"]["play_addr"]["url_list"][0]
@@ -158,7 +175,7 @@ def process_douyin_work(work, index, total_count, save_root, file_name_base, log
if not os.path.exists(file_path): if not os.path.exists(file_path):
if download_file(video_url, file_path, log_callback=log_callback): if download_file(video_url, file_path, log_callback=log_callback):
log_callback( log_callback(
f"[{index + 1}/{total_count}] {file_name_base} -> 下载完成" f"[{index + 1}/{total_count}] {file_name_base} " "-> 下载完成"
) )
else: else:
log_callback( log_callback(
@@ -166,7 +183,8 @@ def process_douyin_work(work, index, total_count, save_root, file_name_base, log
) )
else: else:
log_callback( log_callback(
f"[{index + 1}/{total_count}] {file_name_base} -> 文件已存在,跳过" f"[{index + 1}/{total_count}] {file_name_base} "
"-> 文件已存在,跳过"
) )
else: else:
img_folder = os.path.join(save_root, file_name_base) img_folder = os.path.join(save_root, file_name_base)
Binary file not shown.
+9 -3
View File
@@ -123,12 +123,18 @@ class DouyinDownloaderApp:
frame_platform.pack(padx=10, pady=5, fill="x") frame_platform.pack(padx=10, pady=5, fill="x")
rb_douyin = tk.Radiobutton( rb_douyin = tk.Radiobutton(
frame_platform, text="抖音", variable=self.platform_var, value="douyin" frame_platform,
text="抖音",
variable=self.platform_var,
value="douyin",
) )
rb_douyin.pack(side="left", padx=10) rb_douyin.pack(side="left", padx=10)
rb_bilibili = tk.Radiobutton( rb_bilibili = tk.Radiobutton(
frame_platform, text="B站", variable=self.platform_var, value="bilibili" frame_platform,
text="B站",
variable=self.platform_var,
value="bilibili",
) )
rb_bilibili.pack(side="left", padx=10) rb_bilibili.pack(side="left", padx=10)
@@ -223,8 +229,8 @@ class DouyinDownloaderApp:
thread = threading.Thread( thread = threading.Thread(
target=self.run_task, target=self.run_task,
args=(url, int(count_str), save_path, browser_path, platform), args=(url, int(count_str), save_path, browser_path, platform),
daemon=True,
) )
thread.daemon = True
thread.start() thread.start()
def run_task(self, target_url, target_count, save_root, browser_path, platform): def run_task(self, target_url, target_count, save_root, browser_path, platform):
+6 -3
View File
@@ -2,10 +2,13 @@ import tkinter as tk
from src.ui.app import DouyinDownloaderApp from src.ui.app import DouyinDownloaderApp
# 运行脚本 (使用 my_env 环境): # 运行脚本 (使用 my_env 环境):
# D:\ProgramData\anaconda3\envs\my_env\python.exe "D:\Code\doing_exercises\programs\Video Downloader\video_downloader.py" # D:\ProgramData\anaconda3\envs\my_env\python.exe video_downloader.py
# #
# 打包成 exe (使用 my_env 环境): # 打包成 exe (使用 my_env 环境):
# D:\ProgramData\anaconda3\envs\my_env\python.exe -m nuitka --standalone --mingw64 --show-memory --show-progress --output-dir=build_nuitka --enable-plugin=tk-inter --include-data-dir=ico=ico --windows-icon-from-ico=ico\video_downloader.ico --main=video_downloader.py # D:\ProgramData\anaconda3\envs\my_env\python.exe -m nuitka --standalone ^
# --mingw64 --show-memory --show-progress --output-dir=build_nuitka ^
# --enable-plugin=tk-inter --include-data-dir=ico=ico ^
# --windows-icon-from-ico=ico\video_downloader.ico --main=video_downloader.py
# 主函数入口 # 主函数入口
if __name__ == "__main__": if __name__ == "__main__":
@@ -13,7 +16,7 @@ if __name__ == "__main__":
root = tk.Tk() root = tk.Tk()
app = DouyinDownloaderApp(root) app = DouyinDownloaderApp(root)
root.mainloop() root.mainloop()
except Exception as e: except Exception:
import traceback import traceback
with open("error_log.txt", "w") as f: with open("error_log.txt", "w") as f: