iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
Build on Google AI

把履歷修改工程化:從「聽起來有道理」到用 Gemini 打造可驗證的 AI 職涯助理系列 第 8 篇

Day 08 - 從貼文字到上傳 PDF:解析履歷、處理失敗與確認內容

  • 分享至 

  • xImage
  •  

Recap: 昨天把履歷拆成欄位了,但輸入還是靠貼的

沒有人的履歷是純文字檔
從人力銀行下載、從 Word 匯出,拿到的都是 PDF

今天讓它可以上傳

只用 pypdf

全域範圍裡排除了雲端 PDF 解析服務,所以沒有 Document AI 那種選項
pypdf 一個套件,page.extract_text() 一行就有文字

問題是抽出來的東西不一定能用

抽完不直接分析

/extract/pdf 只做一件事:回傳抽出來的文字,然後停住

// 刻意只填進 textarea,不直接送分析:使用者確認過的文字才是分析的依據。
resumeText.value = data.text || "";

因為 pypdf 對版面複雜的履歷常常把欄位順序打亂
兩欄式排版會被拉成一長條,技能欄插進工作經歷中間

直接送去分析的話,使用者看到的是一份「不知道為什麼怪怪的」報告
而他永遠不會知道問題出在抽取那一步,不是模型

所以抽完先填進輸入框,讓他自己看、自己改,改完再按分析
畫面上寫「共 N 頁,抽出 N 個字。請確認下方文字是否正確」

失敗不是一種

抽取會失敗的狀況很多,但使用者能做的補救完全不同,所以訊息要分開

狀況 回什麼 使用者能做什麼
有密碼 400 先解除密碼再上傳
整份抽不出文字 422 改貼純文字,通常是掃描檔
只有某幾頁抽不到 200 + warning 自己看那幾頁補上
超過 5 MB 或 10 頁 400 縮檔案
上傳的不是 PDF 415 —
是 PDF 但檔案壞了 400 —

第三列是重點
一份十頁的履歷,第 7 頁是張圖,沒道理整份退回

except Exception:  # pypdf 對破損頁面會丟各種例外,單頁失敗不該讓整份失敗
    text = ""

一頁少於 20 個字就當作沒抽到,記進 empty_pages
最後回一句「第 7 頁幾乎沒有抽到文字,可能是圖片或掃描。請確認下方內容是否完整」

加密那邊有個陷阱:有些 PDF 只設了空密碼
所以先試 reader.decrypt(""),解不開才報錯

測試只測壞掉的輸入

repo 裡不放真實履歷,happy path 沒東西可測
但這個模組大部分的工作本來就是處理壞輸入

空白頁 PDF 拿來當掃描檔用:

def _blank_pdf(pages: int = 1) -> bytes:
    w = PdfWriter()
    for _ in range(pages):
        w.add_blank_page(width=595, height=842)  # A4

五個測試:空檔、超大、不是 PDF、頁數超標、整份抽不出文字
最後一個順便斷言狀態碼是 422,不是 400
「檔案沒問題但內容抽不出來」跟「檔案有問題」要分得開

版本:pypdf 6.18.0、python-multipart 0.0.32、fastapi 0.141.1

明天

輸入有了,結構也有了
明天開始對照:職缺要求一條一條拿去履歷裡找證據,找不到的就說找不到


上一篇
Day 07 - 讓模型輸出可被程式使用:履歷與職缺的結構化解析
下一篇
Day 09 - 沒寫到不等於不會:建立職缺要求與履歷證據對照
系列文
把履歷修改工程化:從「聽起來有道理」到用 Gemini 打造可驗證的 AI 職涯助理 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言