建議檔名: Python_環境健檢(改).py
✅ 新增 opencc
和 tqdm
的檢查與安裝
✅ 匯出報告時加註「EPUB 轉換推薦安裝」提醒
處理 EPUB 時需要 zipfile 套件,這是 Python 內建
不需安裝,用來解壓/重新封裝 EPUB
opencc-python-reimplemented
核心簡繁轉換工具,支持自訂詞典,精確度高
tqdm
處理大量檔案時,顯示進度條
執行時會先產生目前安裝版本報告,並連網搜尋有無新版可更新。
無論是否進行更新,都會產生最終結果報告。
檢查報告1:
🔧 Python 環境健檢(10-modules stable)
==================================================
檢查時間(本地 UTC+8):2025/09/14 13:32:11
✔ 已安裝:beautifulsoup4 (4.13.5) — HTML/XML 解析 — https://www.crummy.com/software/BeautifulSoup/bs4/
✔ 已安裝:soupsieve (2.8) — CSS 選擇器支援 — https://github.com/facelessuser/soupsieve
✔ 已安裝:pypandoc (1.15) — 文件轉換工具 — https://github.com/bebraw/pypandoc
✔ 已安裝:requests (2.32.5) — HTTP 請求 — https://docs.python-requests.org/
✔ 已安裝:lxml (6.0.1) — 高效 XML/HTML 解析 — https://lxml.de/
✔ 已安裝:openpyxl (3.1.5) — Excel xlsx 讀寫 — https://openpyxl.readthedocs.io/
✔ 已安裝:python-docx (1.2.0) — Word .docx 操作 — https://github.com/python-openxml/python-docx
✔ 已安裝:python-pptx (1.0.2) — PowerPoint .pptx 操作 — https://github.com/scanny/python-pptx
✔ 已安裝:opencc-python-reimplemented (1.1.9) — 簡繁轉換 — https://pypi.org/project/opencc-python-reimplemented/
✔ 已安裝:tqdm (4.67.1) — 進度條顯示 — https://pypi.org/project/tqdm/
🔧 Python 環境健檢(最終結果)
==================================================
檢查時間(本地 UTC+8):2025/09/14 13:32:20
✔ 已安裝:beautifulsoup4 (4.13.5) — HTML/XML 解析 — https://www.crummy.com/software/BeautifulSoup/bs4/
✔ 已安裝:soupsieve (2.8) — CSS 選擇器支援 — https://github.com/facelessuser/soupsieve
✔ 已安裝:pypandoc (1.15) — 文件轉換工具 — https://github.com/bebraw/pypandoc
✔ 已安裝:requests (2.32.5) — HTTP 請求 — https://docs.python-requests.org/
✔ 已安裝:lxml (6.0.1) — 高效 XML/HTML 解析 — https://lxml.de/
✔ 已安裝:openpyxl (3.1.5) — Excel xlsx 讀寫 — https://openpyxl.readthedocs.io/
✔ 已安裝:python-docx (1.2.0) — Word .docx 操作 — https://github.com/python-openxml/python-docx
✔ 已安裝:python-pptx (1.0.2) — PowerPoint .pptx 操作 — https://github.com/scanny/python-pptx
✔ 已安裝:opencc-python-reimplemented (1.1.9) — 簡繁轉換 — https://pypi.org/project/opencc-python-reimplemented/
✔ 已安裝:tqdm (4.67.1) — 進度條顯示 — https://pypi.org/project/tqdm/
程式碼:
(複製以下文字,貼入純文字檔中,存檔後將副檔名設定為 .py)
【可直接在檔案總管雙擊執行】
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Python 環境健檢(10-modules stable + debug)
會在啟動時列出要檢查的套件清單與數量、目前 Python 解譯器與程式檔案路徑,
以方便確認你執行的就是此檔案。
"""
import importlib
import subprocess
import sys
import os
import json
datetime import datetime, timezone, timedelta
# ---------- 要檢查的 10 個套件(pip 名稱 -> (import 名稱, description)) ----------
PACKAGES = {
"beautifulsoup4": ("bs4", "HTML/XML 解析 — https://www.crummy.com/software/BeautifulSoup/bs4/"),
"soupsieve": ("soupsieve", "CSS 選擇器支援 — https://github.com/facelessuser/soupsieve"),
"pypandoc": ("pypandoc", "文件轉換工具 — https://github.com/bebraw/pypandoc"),
"requests": ("requests", "HTTP 請求 — https://docs.python-requests.org/"),
"lxml": ("lxml", "高效 XML/HTML 解析 — https://lxml.de/"),
"openpyxl": ("openpyxl", "Excel xlsx 讀寫 — https://openpyxl.readthedocs.io/"),
"python-docx": ("docx", "Word .docx 操作 — https://github.com/python-openxml/python-docx"),
"python-pptx": ("pptx", "PowerPoint .pptx 操作 — https://github.com/scanny/python-pptx"),
"opencc-python-reimplemented": ("opencc", "簡繁轉換 — https://pypi.org/project/opencc-python-reimplemented/"),
"tqdm": ("tqdm", "進度條顯示 — https://pypi.org/project/tqdm/"),
}
# ------------------------------------------------------------------------------
PAGE_LINES = 18 # 分頁顯示行數
def now_local_str():
tz = timezone(timedelta(hours=8))
return datetime.now(tz).strftime("%Y/%m/%d %H:%M:%S")
def get_installed_version(import_name, pip_name):
try:
module = importlib.import_module(import_name)
version = getattr(module, "__version__", None)
if not version:
# 嘗試用 importlib.metadata 取得發行版版本
try:
if sys.version_info >= (3, 8):
importlib.metadata import version as dist_version
else:
importlib_metadata import version as dist_version
try:
version = dist_version(pip_name)
except Exception:
version = None
except Exception:
version = None
return version or "unknown"
except Exception:
return None
def page_print(lines):
idx = 0
total = len(lines)
while idx < total:
chunk = lines[idx: idx + PAGE_LINES]
for l in chunk:
print(l)
idx += PAGE_LINES
if idx < total:
resp = input("按 Enter 顯示下一頁,輸入 q 以中止:").strip().lower()
if resp == "q":
break
def pip_install(package_name):
cmd = [sys.executable, "-m", "pip", "install", package_name]
print(f"執行:{' '.join(cmd)}")
proc = subprocess.run(cmd)
return proc.returncode == 0
def pip_upgrade(package_name):
cmd = [sys.executable, "-m", "pip", "install", "--upgrade", package_name]
print(f"執行:{' '.join(cmd)}")
proc = subprocess.run(cmd)
return proc.returncode == 0
def get_outdated_list():
try:
cmd = [sys.executable, "-m", "pip", "list", "--outdated", "--format=json"]
proc = subprocess.run(cmd, capture_output=True, text=True)
if proc.returncode == 0:
try:
data = json.loads(proc.stdout)
return {item["name"].lower(): item for item in data}
except Exception:
return {}
else:
return {}
except Exception:
return {}
def main():
print("🔧 Python 環境健檢(10-modules stable + debug)")
print("="*50)
print(f"執行檔案:{os.path.abspath(__file__)}")
print(f"使用的 Python 解譯器:{sys.executable}")
print(f"檢查時間(本地 UTC+8):{now_local_str()}\n")
# 立刻列出要檢查的套件清單與數量(debug 用)
keys = list(PACKAGES.keys())
print(f"要檢查的套件數量:{len(keys)}")
print("套件清單(pip 名稱):")
for k in keys:
print(" -", k)
print()
report_lines = []
status = {}
for pip_name, (import_name, desc) in PACKAGES.items():
installed_version = get_installed_version(import_name, pip_name)
if installed_version is None:
report_lines.append(f"✘ 未安裝:{pip_name} — {desc}")
status[pip_name] = {"installed": False, "import_name": import_name, "version": None, "desc": desc}
else:
report_lines.append(f"✔ 已安裝:{pip_name} ({installed_version}) — {desc}")
status[pip_name] = {"installed": True, "import_name": import_name, "version": installed_version, "desc": desc}
page_print(report_lines)
# 匯出檢查結果
ts = datetime.now(timezone(timedelta(hours=8))).strftime("%Y%m%d_%H%M%S")
output_fn = f"套件檢查結果_10mod_{ts}.txt"
with open(output_fn, "w", encoding="utf-8") as f:
f.write("🔧 Python 環境健檢(10-modules stable)\n")
f.write("="*50 + "\n")
f.write(f"檢查時間(本地 UTC+8):{now_local_str()}\n\n")
for pip_name, info in status.items():
if info["installed"]:
f.write(f"✔ 已安裝:{pip_name} ({info['version']}) — {info['desc']}\n")
else:
f.write(f"✘ 未安裝:{pip_name} — {info['desc']}\n")
print(f"\n📄 檢查結果已輸出至:{output_fn}\n")
# 安裝缺少的
missing = [k for k, v in status.items() if not v["installed"]]
if missing:
ans = input(f"是否要安裝缺少的 {len(missing)} 個套件?(Y/N):").strip().lower()
if ans == "y":
for pip_name in missing:
print(f"\n⏳ 正在安裝 {pip_name} ...")
ok = pip_install(pip_name)
if ok:
import_name = status[pip_name]["import_name"]
installed_ver = get_installed_version(import_name, pip_name)
if installed_ver is None:
print(f"⚠️ {pip_name} 安裝完成但無法 import,請檢查環境或重啟終端。")
else:
print(f"✅ {pip_name} 安裝並可匯入(版本:{installed_ver})")
status[pip_name]["installed"] = True
status[pip_name]["version"] = installed_ver
else:
print(f"❌ {pip_name} 安裝失敗。")
# 查是否有可更新的套件
print("\n正在檢查是否有可更新的套件(pip list --outdated)...")
outdated = get_outdated_list()
our_outdated = []
for pip_name in PACKAGES.keys():
key = pip_name.lower()
found = None
if key in outdated:
found = outdated[key]
else:
for k,v in outdated.items():
if k.lower() == pip_name.lower():
found = v
break
if found:
our_outdated.append((pip_name, found))
if our_outdated:
lines = ["發現下列已安裝套件有新版:"]
for pip_name, info in our_outdated:
lines.append(f"- {pip_name}: 已安裝 {info.get('version')} → 最新 {info.get('latest')}")
page_print(lines)
ans2 = input("\n是否要更新上述套件?輸入 Y 更新全部,輸入 S 逐一選擇,輸入 N 跳過:").strip().lower()
if ans2 == "y":
for pip_name, _ in our_outdated:
print(f"\n⏳ 正在更新 {pip_name} ...")
ok = pip_upgrade(pip_name)
if ok:
print(f"✅ 已更新 {pip_name}")
else:
print(f"❌ 更新 {pip_name} 失敗。")
elif ans2 == "s":
for pip_name, info in our_outdated:
choice = input(f"要更新 {pip_name}(已裝 {info.get('version')} → 最新 {info.get('latest')})嗎?(Y/N):").strip().lower()
if choice == "y":
pip_upgrade(pip_name)
else:
print("沒有偵測到本機上這些套件有可用更新。")
# 最終檢查輸出
final_lines = []
final_ts = datetime.now(timezone(timedelta(hours=8))).strftime("%Y%m%d_%H%M%S")
final_fn = f"套件檢查結果_10mod_最終_{final_ts}.txt"
for pip_name, (import_name, desc) in PACKAGES.items():
ver = get_installed_version(import_name, pip_name)
if ver is None:
final_lines.append(f"✘ 未安裝:{pip_name} — {desc}")
else:
final_lines.append(f"✔ 已安裝:{pip_name} ({ver}) — {desc}")
print("\n最終檢查結果:\n")
page_print(final_lines)
with open(final_fn, "w", encoding="utf-8") as f:
f.write("🔧 Python 環境健檢(最終結果)\n")
f.write("=" * 50 + "\n")
f.write(f"檢查時間(本地 UTC+8):{now_local_str()}\n\n")
for l in final_lines:
f.write(l + "\n")
print(f"\n📄 最終檢查結果已輸出至:{final_fn}\n")
print("完成。")
if __name__ == "__main__":
main()