小學新生銜接課程-PDF折分及命名python

功能:滑動兩頁:1-2、2-3…;用最後一頁底部 key 命名

安裝套件
pip install pypdf pdfplumber

pypdf:負責拆分/寫出新 PDF
pdfplumber:負責抽文字(比較適合抓某個區域例如頁面底部)

提示詞(可直接複製貼上)

你是一位資深 Python 工程師,請幫我寫一個可執行的 Python 腳本,需求如下(請一次整合完成):

  1. 輸入檔固定為 all.pdf(與腳本同資料夾)。
  2. 將 PDF 不重疊拆分成每段 2 頁:1-2、3-4、5-6...(以原 PDF 頁序)。
  3. 每段輸出檔名要用「該段最後一頁(也就是偶數頁)」右下角底部的數字 key來命名,例如讀到 26271009 就輸出 26271009.pdf
  4. 不能用 OCR。請用 pdfplumber 讀取文字,且請優先使用 page.chars 依座標篩選右下角字元,再把字元串起來,用正則抽出最後一段數字當 key(不要只用 extract_text(),因為有些 PDF 會讀不到)。
  5. 右下角讀取範圍請用比例參數控制(例如 BOTTOM_RATIORIGHT_RATIO),並在程式開頭可調;預設值給一組合理的(例如 bottom 0.22、right 0.45)。
  6. 若某段抓不到 key,輸出檔名請用 UNKNOWN_頁碼.pdf(頁碼指該段最後一頁的 1-based 頁碼,例如 UNKNOWN_0002.pdf)。
  7. 若 key 重複避免覆蓋:自動加尾碼 _2_3(例如 26271009_2.pdf)。
  8. 若原 PDF 總頁數為奇數:最後單頁可忽略,但需在 console 印出提示。
  9. 輸出到資料夾 out_split/(不存在就建立)。
  10. 請使用 pypdf 寫出拆分後 PDF,pdfplumber 讀 key。附上 pip install 指令與執行方式。

請給我:完整可執行程式碼(單檔即可),並用清楚的註解解釋每個步驟。

 

				
					import re
from pathlib import Path
from pypdf import PdfReader, PdfWriter
import pdfplumber

KEY_REGEX = r"\b(\d{8})\b"

def sanitize_filename(s: str) -> str:
    s = (s or "").strip()
    s = re.sub(r"\s+", " ", s)
    s = re.sub(r'[\\/:"*?<>|]+', "_", s)
    return s.strip(" ._")

def extract_key_from_page_tail(pdf_path: str, page_index: int, tail_lines: int = 25, debug: bool = False):
    with pdfplumber.open(pdf_path) as pdf:
        text = (pdf.pages[page_index].extract_text() or "")

    # 去掉常見雜訊符號(可再加)
    text = text.replace("\uF026", " ")
    lines = [ln.strip() for ln in text.splitlines() if ln.strip()]
    tail = "\n".join(lines[-tail_lines:])

    m = re.search(KEY_REGEX, tail)
    if debug:
        print(f"[DEBUG] page={page_index+1} tail=\n---\n{tail}\n---\nmatch={m.group(1) if m else None}\n")
    return m.group(1) if m else None

def unique_path(p: Path) -> Path:
    if not p.exists():
        return p
    i = 2
    while True:
        cand = p.with_name(f"{p.stem}_{i}{p.suffix}")
        if not cand.exists():
            return cand
        i += 1

def split_every_two(pdf_path="all.pdf", out_dir="out", debug=False):
    out_dir = Path(out_dir)
    out_dir.mkdir(parents=True, exist_ok=True)

    reader = PdfReader(pdf_path)
    n = len(reader.pages)

    for start in range(0, n, 2):
        end = min(start + 2, n)
        writer = PdfWriter()
        for i in range(start, end):
            writer.add_page(reader.pages[i])

        # 先用第1頁,抓不到再用第2頁
        key = extract_key_from_page_tail(pdf_path, start, debug=debug)
        if key is None and end - 1 != start:
            key = extract_key_from_page_tail(pdf_path, end - 1, debug=debug)

        if key is None:
            key = f"pages_{start+1}-{end}"

        key = sanitize_filename(key)
        out_path = unique_path(out_dir / f"{key}.pdf")

        with open(out_path, "wb") as f:
            writer.write(f)

        print(f"輸出: {out_path.name} (頁 {start+1}-{end}, key={key})")

if __name__ == "__main__":
    split_every_two("all.pdf", "out", debug=True)