Skip to main content

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 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 众安银行 PDF 综合月结单

更多 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"))

配置

配置文件搜索顺序:

  1. 命令行 -c/--config 指定的路径
  2. 当前目录 ./bean-sieve.yaml
  3. 系统配置目录:
    • Linux/macOS: $XDG_CONFIG_HOME/bean-sieve/config.yaml~/.config/bean-sieve/config.yaml
    • Windows: %APPDATA%\bean-sieve\config.yaml

复制 bean-sieve.example.yamlbean-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 支持:

  1. 自动核对:比较解析的消费金额与账单应还金额,判断是否平账
  2. 自动生成刷卡金条目:平账时自动生成刷卡金收入记录

配置

providers:
  abc_credit:
    accounts:
      "1234": Liabilities:Credit:ABC:U-示例卡1234
    # 刷卡金收入账户(生成条目时使用)
    rebate_income_account: Income:Rebate:ABC
    # 关键词:用于识别账本中已存在的刷卡金记录
    rebate_keywords:
      - 刷卡金
      - 返现

去重检测逻辑

配置 rebate_income_accountrebate_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

列在这里的账户会同时启用两件事:

  1. 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
  1. 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:9999Liabilities: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

beancount_sieve-0.4.0.tar.gz (224.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

beancount_sieve-0.4.0-py3-none-any.whl (124.7 kB view details)

Uploaded Python 3

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

Hashes for beancount_sieve-0.4.0.tar.gz
Algorithm Hash digest
SHA256 6b72bb5d44ead906ea9270b3dc00e9faae71ac8101d8b4437c2fb69b11bbc4f3
MD5 2b0d5cba8f0d301f7a7d35d280d4910c
BLAKE2b-256 371f3c09f7ac01f3216a1c867a8371cc174a600fd0fc0bd2adc1c164c1fc6e6c

See more details on using hashes here.

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

Hashes for beancount_sieve-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9870fa0492c01199cf0b22befc2bd92583551766248e301a1bad163b8b3a802b
MD5 1a3f96ae0e9e813229bf3ca4a973b4d4
BLAKE2b-256 79d243a9ca147df59768c94680fec2f18f91c82baf745d3530e043884b1d1f16

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page