Author: Produced by 43 COLLEGE 凯寓 (KAIYU) Version: v1.0
Initial Setup
If a runtime error occurs and config.json cannot be found or the mailbox connection fails, read SETUP.md to complete the initial setup.
Cross-Platform Compatibility
| Item | macOS / Linux | Windows |
|---|---|---|
| Python | python3 |
python |
| Script Path | ${CLAUDE_SKILL_DIR}/scripts/process_invoices.py |
${CLAUDE_SKILL_DIR}\scripts\process_invoices.py |
| Default Output | ~/Desktop/发票-日期/ |
%USERPROFILE%\Desktop\发票-日期\ |
| pip Install | pip install ... or pip3 install ... |
python -m pip install ... |
Usage
macOS / Linux:
# 整月处理
python3 ${CLAUDE_SKILL_DIR}/scripts/process_invoices.py 2026-03
# 指定日期范围
python3 ${CLAUDE_SKILL_DIR}/scripts/process_invoices.py 2026-03-01~2026-03-15
# 单日
python3 ${CLAUDE_SKILL_DIR}/scripts/process_invoices.py 2026-03-15
# 自定义输出目录
python3 ${CLAUDE_SKILL_DIR}/scripts/process_invoices.py 2026-03 -o ~/Desktop/三月发票
Windows:
python ${CLAUDE_SKILL_DIR}\scripts\process_invoices.py 2026-03
python ${CLAUDE_SKILL_DIR}\scripts\process_invoices.py 2026-03 -o %USERPROFILE%\Desktop\三月发票
Processing Flow
- Dependency Precheck — exits if a required dependency is missing; missing optional dependencies only produce a warning
- Connect to Mailbox — connects via IMAP SSL (credentials read from config.json)
- Server-Side Search — filters on the mail server by keyword + date to avoid fetching everything
- Keyword Filtering — matches invoice keywords against the email subject/sender/body
- Three-Level Attachment Download:
- Direct attachments (PDF / image / ZIP all supported; including
application/octet-stream-disguised ZIP) - Extract HTTP links from the body (automatically handles HTML entity encoding, supports
.pdf/.png/.jpg/.zipdirect links) - 302 Heuristic: for short links, first
HEADsniff; if the 302 Location's query string contains thepdfUrl=/fileUrl=/downloadUrl=parameter, bypass the SPA landing page and fetch the real PDF directly (SPA platforms such as cloud invoice bwjf.cn) - Playwright browser fallback (requires installing an optional dependency)
- Direct attachments (PDF / image / ZIP all supported; including
- Post-Download Validation:
- Magic bytes file type detection (prevents HTML pages from being saved as PDF)
- Automatic ZIP Extraction: identifies
PK\x03\x04/PK\x05\x06magic bytes to automatically extract the inner PDF (12306 train ticket ZIP / ByteDance-series invoice<a download>direct link); logs only when it contains OFD (pdfplumber does not support OFD) - Invoice validity check (PDF keywords / image dimensions)
- Automatic QR code handling (decode → browser visit → download PDF)
- Field Extraction — pdfplumber table extraction + text regex dual strategy
- Supports negative amounts: 12306 refund red-ink invoices (
¥-88.50) are correctly identified - Red-ink invoice remarks: when the keywords "红冲" or "原发票号码" are detected, automatically writes "退票红冲,原发票号 xxx" in the remarks column
- Fallback when there is no "价税合计" label: 12306 e-tickets directly use the
¥xx.xxformat, taking the amount with the largest absolute value as the total amount including tax
- Supports negative amounts: 12306 refund red-ink invoices (
- Email Body NLP Fallback — each email's body text is scanned first to extract invoice number/invoice date/buyer/seller/total amount including tax; if attachment fetching fails, it can still be recorded in the table (marked "body-extracted, pending verification"); if attachment parsing succeeds but fields are missing, the body is used to fill them in
- Generate Excel — Sheet by buyer, including totals row
- ⚠️ Manual review required: Insert a prominent orange-background sheet on the first page of the xlsx, summarizing items such as download failures, parsing failures, entries recorded only from the email body, and unidentified buyers (type/email subject/field extraction status/recommended action)
- Processing log — Records skipped/failed items
Output structure
~/Desktop/发票-2026-03/
├── 001-XX公司发票通知.pdf
├── 002-YY平台电子发票.pdf
├── 003-ZZ服务发票-qr.pdf ← 二维码发票自动解码下载的 PDF
├── 发票汇总.xlsx
└── 处理日志.txt
Extracted fields
Invoice number, invoice code, invoice date, seller, buyer, amount (excluding tax), tax amount, total amount including tax, remarks (red-letter reversal / original invoice number / fallback source from email body)
Dependencies
Required(missing will exit):
pdfplumber— PDF parsingopenpyxl— Excel generationrequests— HTTP downloadPillow— Image processing
Optional(missing only limits some features):
playwright+ chromium — for downloading invoice links that require JS renderingpyzbar— Automatic QR code image decoding (Windows requires additional installation of libzbar.dll)
Install required dependencies:
pip install pdfplumber openpyxl requests Pillow
Email compatibility
Currently connects to email via the IMAP protocol. Any email that supports IMAP can be configured in config.json:
| imap_server | Remarks | |
|---|---|---|
| QQ Mail | imap.qq.com | IMAP must be enabled and an authorization code generated |
| 163 Mail | imap.163.com | IMAP must be enabled and a client authorization password set |
| Gmail | imap.gmail.com | IMAP must be enabled and an App Password generated |
| Outlook | outlook.office365.com | IMAP must be enabled |
The default configuration is QQ Mail. To change the email, you only need to modify the email、password、imap_server。
Known limitations
- Some JS-heavy platforms (Nuonuo, etc.) may fail with headless Playwright
- Field extraction may be incomplete for non-standard invoice formats
- OSS signed links are time-limited; expired links must be obtained again
- Invoice field extraction is optimized for Chinese VAT invoice formats
- If the ZIP contains only OFD (national standard layout files), it will not be extracted (pdfplumber does not support OFD); this will be noted in the log
- Email body NLP fallback relies on keyword templates; non-standard template emails (such as image-only emails) may still miss fields, so check the ⚠️ Manual review required sheet