Rule-based statement importer and reconciler for Beancount
Project description
Bean-Sieve
Bean-Sieve 是一个基于规则的 Beancount 账单导入与对账工具。
与传统导入器只做「解析 → 导入」不同,Bean-Sieve 支持将账单与已有账本智能对账——自动识别已手动记录的交易,仅生成缺失条目,避免重复。同时也可作为独立的账单解析器,将各类账单统一导出为通用 CSV/XLSX 格式。
功能特性
- 解析 支付宝、微信支付、银行信用卡/借记卡等各类账单
- 对账 与已有 Beancount 账本比对,自动识别已记录交易,补充未记录交易
- 生成 仅输出缺失的待录入条目,支持规则映射账户
- 导出 可作为纯账单解析器,将账单统一导出为 CSV/XLSX
安装
作为 CLI 工具安装(推荐)
# 使用 uv(推荐)
uv tool install beancount-sieve
# 使用 pipx
pipx install beancount-sieve
# 或从源码安装
uv tool install git+https://github.com/Xm798/bean-sieve.git
以上命令会将 bean-sieve 安装到 ~/.local/bin(Linux/macOS)或用户 PATH(Windows)。请确保该目录在 PATH 中。
开发安装
# 本地开发
uv sync
# 包含开发依赖
uv sync --extra dev
在其他项目中引入
# 从 Git 安装
uv add git+https://github.com/Xm798/bean-sieve.git
# 从本地路径安装
uv add --editable ../bean-sieve
Shell 自动补全
# Bash - 添加到 ~/.bashrc
eval "$(bean-sieve completion bash)"
# Zsh - 添加到 ~/.zshrc
eval "$(bean-sieve completion zsh)"
# Fish
bean-sieve completion fish > ~/.config/fish/completions/bean-sieve.fish
支持的数据源
支付平台
| Provider | 名称 | 格式 | 说明 |
|---|---|---|---|
alipay |
支付宝 | CSV | 支付宝导出的交易明细 |
app_store |
App Store | HAR | App Store 购买历史 (reportaproblem.apple.com HAR 导出) |
jd |
京东支付 | CSV | 京东交易流水导出文件 |
wechat |
微信支付 | CSV / XLSX | 微信支付账单流水文件 |
信用卡
| Provider | 名称 | 格式 | 说明 |
|---|---|---|---|
abc_credit |
农业银行信用卡 | EML | 邮件账单 |
boc_credit |
中国银行信用卡 | PDF 账单 | |
bocom_credit |
交通银行信用卡 | EML | 邮件账单 |
bosc_credit |
上海银行信用卡 | EML | 邮件账单 |
ccb_credit |
建设银行信用卡 | EML | 邮件账单 |
cgb_credit |
广发银行信用卡 | EML | 邮件账单 |
cib_credit |
兴业银行信用卡 | EML | 邮件账单 |
cncb_credit |
中信银行信用卡 | XLS | 网银导出账单 |
cmb_credit |
招商银行信用卡 | EML | 邮件账单 |
cmbc_credit |
民生银行信用卡 | EML | 邮件账单 |
hxb_credit |
华夏银行信用卡 | EML | 邮件账单 |
借记卡
| Provider | 名称 | 格式 | 说明 |
|---|---|---|---|
boc_debit |
中国银行借记卡 | CSV | 网银导出账单 |
abc_debit |
农业银行借记卡 | XLSX | Excel 导出账单 |
icbc_debit |
工商银行借记卡 | CSV | CSV 导出账单 |
ccb_debit |
建设银行借记卡 | XLS | XLS 导出账单 |
bocom_debit |
交通银行借记卡 | XLS | XLS 导出账单 |
cmb_debit |
招商银行借记卡 | CSV | CSV 导出账单 |
cib_debit |
兴业银行借记卡 | XLS | XLS 导出账单 |
pab_debit |
平安银行借记卡 | XLS/XLSX | Excel 导出账单 |
zabank_debit |
众安银行 | 综合月结单 |
更多 Provider 正在开发中。
使用方法
命令行
# 对账:解析账单 + 比对账本 + 生成缺失条目
bean-sieve reconcile data/statement/*.csv -l books/ -o pending.bean
# 仅解析:输出标准化交易
bean-sieve parse data/statement/*.csv
# 导出:将解析结果导出为 CSV 或 XLSX
bean-sieve export data/statement/*.csv -f csv -o output/
# 仅检查:显示对账结果,不生成文件
bean-sieve check data/statement/*.csv -l books/
# 提取账单中的支付方式并交互式映射到账本账户
bean-sieve extract-accounts data/statement/*.csv -l books/
# 从账本历史记录中自动生成规则建议
bean-sieve suggest-rules -l books/
# 列出支持的数据源
bean-sieve providers
# 生成 Shell 自动补全脚本
bean-sieve completion bash
Python API
from pathlib import Path
from bean_sieve.providers import get_provider, list_providers
# 查看所有可用的 Provider
for p in list_providers():
print(f"{p['id']}: {p['name']} ({p['formats']})")
# 解析支付宝账单
alipay = get_provider("alipay")
transactions = alipay.parse(Path("data/statement/支付宝交易明细.csv"))
for txn in transactions[:5]:
print(f"{txn.date} | {txn.payee:20s} | {txn.amount:>10} CNY | {txn.description}")
# 解析微信账单
wechat = get_provider("wechat")
transactions = wechat.parse(Path("data/statement/微信支付账单.xlsx"))
配置
配置文件搜索顺序:
- 命令行
-c/--config指定的路径 - 当前目录
./bean-sieve.yaml - 系统配置目录:
- Linux/macOS:
$XDG_CONFIG_HOME/bean-sieve/config.yaml或~/.config/bean-sieve/config.yaml - Windows:
%APPDATA%\bean-sieve\config.yaml
- Linux/macOS:
复制 bean-sieve.example.yaml 为 bean-sieve.yaml(当前目录)或 config.yaml(系统配置目录)并根据需要修改:
# 默认设置
defaults:
currency: CNY
expense_account: Expenses:FIXME
income_account: Income:FIXME
date_tolerance: 0 # 日期模糊匹配容差(天)
# 账户映射(按 provider)
accounts:
alipay:
default: Assets:Current:Alipay
wechat:
default: Assets:Current:Wechat
# 规则匹配(优先级最高,按顺序匹配)
rules:
# 正则匹配 description
- description: ".*瑞幸.*"
payee: 瑞幸咖啡
contra_account: Expenses:Food:Coffee
- description: ".*美团.*外卖.*"
payee: 美团外卖
contra_account: Expenses:Food:Delivery
# 多关键词匹配(OR 逻辑)
- description: "(滴滴|高德|T3出行)"
payee: 打车
contra_account: Expenses:Transport:Taxi
# 时间范围
- description: ".*食堂.*"
time: "11:00-14:00"
contra_account: Expenses:Food:Lunch
- description: ".*食堂.*"
time: "17:00-20:00"
contra_account: Expenses:Food:Dinner
# 忽略某些交易
- description: ".*还款.*"
ignore: true
账单下载方式
借记卡
| 银行 | 下载方式 | 系统要求 | 备注 |
|---|---|---|---|
| 中国银行 | 个人网上银行 | Windows / macOS | 卡号登录,复制查询表格保存为 CSV |
| 农业银行 | 个人网上银行 | Windows / macOS | 需安装安全控件,macOS 需用 Safari |
| 工商银行 | 个人网上银行 | Windows / macOS | 需安装安全控件,macOS 需用 Safari |
| 建设银行 | 个人网上银行 | Windows / macOS | Chrome 即可,无需安全控件 |
| 交通银行 | 个人网上银行 | Windows / macOS | 需安装安全控件,macOS 需用 Safari |
| 招商银行 | 专业版 PC 客户端 | Windows | 需安装客户端 |
| 兴业银行 | 个人网上银行 | Windows / macOS | 需安装安全控件,查询→交易明细查询→流水下载→Excel |
| 平安银行 | 个人网上银行 | Windows / macOS | 扫码登录无需安全控件 |
信用卡
信用卡账单通常通过邮件获取,在发卡行官网或 App 设置账单邮箱即可。部分银行支持网银导出:
| 银行 | 下载方式 | 备注 |
|---|---|---|
| 中信银行 | 信用卡网银 | 登录后导出已出账单明细 XLS |
其他
| 平台 | 下载方式 | 备注 |
|---|---|---|
| Apple | Report a Problem | 登录后 F12 打开控制台,滚动加载完后导出 search 请求为 HAR |
信用卡账单管理方式
| 管理方式 | 银行 | 特点 |
|---|---|---|
| 按户管理 | 招商银行、民生银行、华夏银行、平安银行、浦发银行、北京银行、上海银行 | 信报、还款、积分按户合并管理 |
| 按卡管理 | 广发银行、建设银行 | 独立信报,账单日合并,独立还款。 |
| 按卡管理 | 中信银行、光大银行、交通银行、农业银行、工商银行、兴业银行、中国银行、邮政储蓄 | 独立信报,独立账单,独立还款。 |
按户管理的账户在同一个 Liability 账户下持有多张物理卡,账户名本身无法区分——配置 diagnostics.meta_check_accounts 后,Bean-Sieve 会在 posting 上自动注入 card_last4,并对账本中缺失或冲突的 card_last4 元数据输出 lint 诊断。
Provider Metadata 字段
每个 Provider 解析账单时,除了标准字段(日期、金额、描述、收款方等)外,还会将账单中的其他列存入 metadata。可通过 output_metadata 配置控制哪些字段输出到 Beancount 文件。
支付平台
| Provider | Metadata 字段 |
|---|---|
alipay |
category, peer_account, method, status, merchant_id, tx_type, remarks |
wechat |
tx_type, method, status, merchant_id, remarks, order_type, commission, rebate, rebate_currency |
jd |
method, transaction_type, transaction_status, transaction_category, merchant_order_id, notes, refund_amount |
app_store |
media_type, item_id, adam_id |
信用卡
| Provider | Metadata 字段 |
|---|---|
boc_credit |
original_trans_date, original_post_date |
bocom_credit |
original_date, section |
cgb_credit |
original_date, trans_type |
cib_credit |
original_date |
cmb_credit |
posting_date |
cmbc_credit |
posting_date |
hxb_credit |
original_date |
abc_credit |
— |
bosc_credit |
— |
ccb_credit |
— |
cncb_credit |
— |
借记卡
中国银行 boc_debit
| 字段 | 说明 |
|---|---|
summary |
业务摘要 |
balance |
余额 |
channel |
交易渠道/场所 |
counterparty_account |
对方账户账号 |
cash_remit |
钞/汇 |
农业银行 abc_debit
| 字段 | 说明 |
|---|---|
summary |
交易摘要 |
balance |
本次余额 |
counterparty_account |
对方账号 |
bank |
交易行 |
channel |
交易渠道 |
tx_type |
交易类型 |
工商银行 icbc_debit
| 字段 | 说明 |
|---|---|
summary |
摘要 |
balance |
余额 |
detail |
交易详情 |
location |
交易场所 |
counterparty_account |
对方账户 |
建设银行 ccb_debit
| 字段 | 说明 |
|---|---|
summary |
摘要 |
balance |
账户余额 |
counterparty_account |
对方账号 |
location |
交易地点 |
交通银行 bocom_debit
| 字段 | 说明 |
|---|---|
summary |
摘要 |
balance |
余额 |
method |
交易方式 |
location |
交易地点 |
counterparty_account |
对方账户 |
counterparty_bank |
对方开户行 |
招商银行 cmb_debit
| 字段 | 说明 |
|---|---|
type |
交易类型 |
balance |
余额 |
remark |
交易备注 |
兴业银行 cib_debit
| 字段 | 说明 |
|---|---|
summary |
摘要 |
balance |
账户余额 |
counterparty_bank |
对方银行 |
counterparty_account |
对方账号 |
purpose |
用途 |
channel |
交易渠道 |
remark |
备注 |
平安银行 pab_debit
| 字段 | 说明 |
|---|---|
tx_type |
交易类型(转入/转出) |
summary |
摘要 |
balance |
账户余额 |
note |
备注 |
counterparty_account |
对方账号 |
众安银行 zabank_debit
| 字段 | 说明 |
|---|---|
balance |
交易后余额 |
counterparty |
对手方信息(姓名+账号) |
exchange_info |
换汇的 sell/buy 详情 |
配置示例
全局配置(所有 Provider 生效):
defaults:
output_metadata:
- time
Provider 级别配置(仅该 Provider 生效,与全局合并):
providers:
cib_debit:
output_metadata:
- counterparty_bank
- counterparty_account
output_metadata 写在交易头下,作用于整笔交易;若要把字段写在 posting 行下(如 card_last4 用于区分同一账户下的多张物理卡),使用 posting_metadata:
providers:
hxb_credit:
posting_metadata:
- card_last4
对于"按户管理"的账户(同一账户持有多张物理卡,如 HXB/SPDB/CMB),通过 diagnostics.meta_check_accounts 纳入检查后 card_last4 会被自动注入 posting,并在 ledger 缺失/冲突时产生诊断。详见下文 Posting 元数据与诊断。
Provider 特定功能
借记卡余额断言 (Balance Directive)
对账后可自动生成 Beancount balance 指令,用于校验账户余额。取账单中最后一笔交易的余额,日期为账单结束日次日。
按 Provider 级别控制,默认关闭:
providers:
pab_debit:
accounts:
"6666": Assets:Bank:PAB:6666
balance: true
输出示例:
2026-04-01 balance Assets:Bank:PAB:6666 12345.67 CNY
农业银行信用卡 (abc_credit)
农业银行账单会显示刷卡金抵扣金额,但不会在交易明细中体现。Bean-Sieve 支持:
- 自动核对:比较解析的消费金额与账单应还金额,判断是否平账
- 自动生成刷卡金条目:平账时自动生成刷卡金收入记录
配置
providers:
abc_credit:
accounts:
"1234": Liabilities:Credit:ABC:U-示例卡1234
# 刷卡金收入账户(生成条目时使用)
rebate_income_account: Income:Rebate:ABC
# 关键词:用于识别账本中已存在的刷卡金记录
rebate_keywords:
- 刷卡金
- 返现
去重检测逻辑
配置 rebate_income_account 或 rebate_keywords 后,对账时会在账本的 Extra 条目中查找:
- 日期在账单周期内
- 账户包含卡号后四位
- 金额精确匹配
- 描述包含关键词 或 posting 使用了指定的收入账户
如果找到匹配记录,显示 ✅ 平账 (刷卡金 X.XX 已记录);否则自动生成刷卡金条目。
输出示例
; --- 刷卡金抵扣 ---
2025-11-27 * "农业银行" "刷卡金抵扣 (尾号1234)"
Liabilities:Credit:ABC:U-示例卡1234 1.33 CNY
Income:Rebate:ABC
; ============================================================
; 农业银行信用卡 账单核对
; ============================================================
;
; 卡号: 620000******1234 (尾号 1234)
; 账单周期: 2025/10/28-2025/11/27
;
; 解析消费: 32036.00 CNY
; 账单应还: 32034.67 CNY
; 刷卡金抵扣: 1.33 CNY
;
; 状态: ✅ 平账 (刷卡金 1.33)
Posting 元数据与诊断
支付宝/微信等支付平台的账单中,method 字段(如 华夏银行信用卡(1234))指向实际刷卡的物理银行卡。对于"按户管理"的银行(HXB、SPDB、CMB 等),同一个 Liability 账户名下会挂多张物理卡,账户名本身无法区分用的哪张卡——此时需要把 card_last4 写在 posting 下面来消歧。
通过 diagnostics.meta_check_accounts(子串匹配)列出需要检查的账户:
diagnostics:
meta_check: true
meta_check_accounts:
- Liabilities:Credit:HXB
- Liabilities:Credit:SPDB
- Liabilities:Credit:CMB
列在这里的账户会同时启用两件事:
- Writer 自动注入 —— 输出新交易时在这些账户的 posting 下加
card_last4:
2025-03-15 ! "瑞幸咖啡" "拿铁"
time: "10:23:00"
Liabilities:Credit:HXB -28.00 CNY
card_last4: "1234"
Expenses:Food:Coffee 28.00 CNY
- Metadata 诊断 —— 对账时
card_last4软校验,匹配照常成立,ledger 中缺失或冲突的以 lint 风格输出在 pending.bean 末尾:
; ============================================================
; Metadata diagnostics (2)
; ============================================================
; books/2025/q1.bean:1234 hint missing posting meta `card_last4: "1234"` on Liabilities:Credit:HXB
; books/2025/q2.bean:88 warn posting meta `card_last4` mismatch on Liabilities:Credit:SPDB: ledger "5678", statement "1234"
- hint — ledger 中该交易没有
card_last4,可照提示补上 - warn — ledger 中
card_last4与账单冲突,提示核对(交易本身仍被认为匹配,不会重复生成)
账户名已带卡号的(如 Assets:Bank:ICBC:9999、Liabilities:Credit:BOCOM:U-东航金0001)没必要纳入——不列就不做检查,也不产生诊断。
如需恢复旧的硬过滤行为(冲突即视为不同交易、进 missing),显式关闭:
diagnostics:
meta_check: false
数据格式约定
Transaction 字段
| 字段 | 类型 | 说明 |
|---|---|---|
date |
date | 交易日期 |
time |
time | 交易时间(如有) |
amount |
Decimal | 金额(支出为正,收入为负) |
currency |
str | 币种 |
description |
str | 原始描述 |
payee |
str | 交易对方 |
card_last4 |
str | 银行卡末四位(银行卡 Provider 直接提取;Alipay/WeChat 从 method 尾部 (XXXX) 中提取) |
order_id |
str | 订单号/流水号 |
provider |
str | 数据源标识 |
metadata |
dict | 扩展元数据 |
Metadata 字段
不同 Provider 会提取不同的 metadata:
Alipay:
category: 交易分类peer_account: 对方账号method: 收/付款方式status: 交易状态merchant_id: 商家订单号
Wechat:
tx_type: 交易类型(商户消费、转账、红包等)method: 支付方式status: 当前状态commission: 服务费(如有)
开发
# 安装开发依赖
uv sync --extra dev
# 运行测试
uv run pytest
# 代码检查
uv run ruff check src/ tests/
# 格式化
uv run ruff format src/ tests/
项目结构
bean-sieve/
├── bean-sieve.example.yaml # 配置示例
├── bean-sieve.schema.json # 配置 JSON Schema
├── src/bean_sieve/
│ ├── api.py # API 层
│ ├── cli.py # CLI 入口
│ ├── core/
│ │ ├── types.py # 数据类型定义
│ │ ├── sieve.py # 去重/匹配引擎
│ │ ├── rules.py # 规则匹配引擎
│ │ ├── preset_rules.py # 内置预设规则
│ │ ├── output.py # Beancount 输出生成
│ │ ├── export.py # CSV/XLSX 导出
│ │ └── suggest.py # 规则自动生成
│ ├── providers/
│ │ ├── base.py # Provider 基类
│ │ ├── payment/ # 支付平台(支付宝、微信、京东)
│ │ └── banks/
│ │ ├── credit/ # 信用卡(农行、中行、交行等)
│ │ └── debit/ # 借记卡(建行、工行、平安)
│ └── config/
│ ├── schema.py # 配置 Schema
│ └── wizard.py # 账户映射向导
└── tests/
Community
LINUX DO - 社区讨论与交流
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file beancount_sieve-0.4.0.tar.gz.
File metadata
- Download URL: beancount_sieve-0.4.0.tar.gz
- Upload date:
- Size: 224.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b72bb5d44ead906ea9270b3dc00e9faae71ac8101d8b4437c2fb69b11bbc4f3
|
|
| MD5 |
2b0d5cba8f0d301f7a7d35d280d4910c
|
|
| BLAKE2b-256 |
371f3c09f7ac01f3216a1c867a8371cc174a600fd0fc0bd2adc1c164c1fc6e6c
|
File details
Details for the file beancount_sieve-0.4.0-py3-none-any.whl.
File metadata
- Download URL: beancount_sieve-0.4.0-py3-none-any.whl
- Upload date:
- Size: 124.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9870fa0492c01199cf0b22befc2bd92583551766248e301a1bad163b8b3a802b
|
|
| MD5 |
1a3f96ae0e9e813229bf3ca4a973b4d4
|
|
| BLAKE2b-256 |
79d243a9ca147df59768c94680fec2f18f91c82baf745d3530e043884b1d1f16
|