首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >混合端RPA方案:税务UKey网页开票、发票OCR验真、防重复报销,一次跑通

混合端RPA方案:税务UKey网页开票、发票OCR验真、防重复报销,一次跑通

原创
作者头像
用户12579380
发布于 2026-11-05 16:53:34
发布于 2026-11-05 16:53:34
1190
举报

去年接手一个代账团队的活,三个需求摆在我面前:税务UKey网页开票、发票OCR验真、防重复报销。听起来是三件事,做起来才发现它们共用同一个底座——跨"本地软件+浏览器页面"的混合端自动化。开票环节在税务UKey的网页端操作,验真环节要把发票影像送进OCR接口,报销环节又得回到客户的报销系统网页里查重。纯接口方案走不通,因为UKey开票页面没有开放接口;纯人工方案更走不通,一个会计一天开几十张票还要逐张登录查验平台,眼睛和心态总有一个先崩。

我最后落地的混合端RPA方案长这样:RPA负责跨端操作,腾讯云文字识别负责票面识别与发票核验,本地数据库负责去重留档。跑了小半年,把过程和账本都摊开写一写。

一、为什么叫"混合端",坑就从这儿开始

税务UKey的开票页面是嵌在浏览器里的,但UKey驱动、开票软件本体又是Windows程序;客户的报销系统是老旧的Web页面;发票影像存在本地文件夹。一个流程要同时在浏览器、Windows软件、文件系统之间来回切换,这正是混合端RPA方案的用武之地,也是它比普通网页自动化难一个数量级的原因。

我用的是一款Windows端的RPA工具,选它的理由很朴素:全离线内网部署,流程数据全部留在本地设备上,不同步到任何服务端。代账这行,客户的发票数据、购销方税号、金额明细,谁都不想往云上送一份。数据不出本地这条底线,在签合同之前就被客户写进了需求里。

二、整体架构:三层各司其职

代码语言:javascript
复制
报销单据/影像文件夹
      │
      ▼
┌─ RPA层(本地Windows运行)────────────────┐
│  读取发票影像 → 调用OCR → 写去重库      │
│  税务UKey网页开票 → 企业微信通知会计复核 │
└──────────────────────────────────────────┘
      │                     │
      ▼                     ▼
腾讯云OCR              本地SQLite去重库
(识别+核验)          (发票代码+号码唯一键)

RPA层做三件事:遍历影像文件夹、调用腾讯云发票OCR识别票面字段、把关键字段写入本地去重库;验真通过的票据再走税务UKey网页开票流程;全程异常截图留证,跑完发企业微信消息通知人工复核。AI负责思考、RPA负责稳定落地,这句话放在这个架构上不是口号——字段怎么校验、异常怎么分流是判断题,交给AI辅助;把判断结果稳稳当当填进网页表单、点完一整套开票动作,是体力活,必须交给RPA。

三、核心代码:OCR识别、验真与防重复报销

识别环节我用腾讯云增值税发票识别(VatInvoiceOCR),验真用增值税发票核验接口,去重用本地SQLite,发票代码+发票

代码语言:javascript
复制
# 依赖:pip install tencentcloud-sdk-python-ocr
import base64, hashlib, sqlite3, time, random
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.ocr.v20181119 import ocr_client, models

# TODO: 替换为你自己的密钥
cred = credential.Credential("AKIDxxxxxxxx", "xxxxxxxx")
http_profile = HttpProfile(endpoint="ocr.tencentcloudapi.com")
client = ocr_client.OcrClient(cred, "ap-guangzhou", ClientProfile(httpProfile=http_profile))

def ocr_invoice(image_path):
    """识别票面字段:发票代码/号码/日期/金额。失败重试3次,日志追加写。"""
    with open(image_path, "rb") as f:
        req = models.VatInvoiceOCRRequest()
        req.ImageBase64 = base64.b64encode(f.read()).decode("utf-8")
        for attempt in range(3):
            try:
                resp = client.VatInvoiceOCR(req)
                return resp.InvoiceInfos[0]  # 字段以控制台返回示例为准
            except Exception as e:
                with open("invoice_ocr.log", "a", encoding="utf-8") as log:
                    log.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} {image_path} 第{attempt+1}次失败: {e}\n")
                time.sleep(0.5 + random.randint(0, 300) / 1000)  # 500~800ms随机间隔
    return None  # 重试耗尽,交给人工

def is_duplicate(invoice_code, invoice_no):
    """防重复报销:本地查重,数据不出本地"""
    key = hashlib.md5(f"{invoice_code}-{invoice_no}".encode()).hexdigest()
    conn = sqlite3.connect("invoice_dup.db")
    cur = conn.execute("SELECT 1 FROM invoices WHERE uniq_key=?", (key,))
    dup = cur.fetchone() is not None
    if not dup:
        conn.execute("INSERT INTO invoices(uniq_key, checked_at) VALUES(?, datetime('now','localtime'))", (key,))
        conn.commit()
    conn.close()
    return dup

两个细节说明:一是识别结果里电子发票没有发票代码,只有20位发票号码,去重键要做兼容处理,代码里按代码+号码拼接、缺代码时留空即可,别为空值报错;二是验真接口的入参要求"开票日期+金额"与票面严格一致,OCR识别金额偶尔带千分位逗号,入库前先把逗号去掉,否则核验会一直返回不一致,这个坑我踩了一个下午。

四、踩坑实录:网页一改,流程就停

坑一:UKey开票页面的元素定位失效

税务UKey的网页端一年总有那么几次升级,前端框架动一动,原来写死的元素路径就失效。我最早用纯脚本写xpath,失效一次改一次,维护成本全在"找元素"上。换成现在这款工具后,这个痛点基本消失了:它支持Web元素AI自愈,页面结构变化后自动修复元素定位,流程不中断;元素获取还能本地智能生成,不用啃xpath语法,直接用自然语言描述要点的按钮,比如"开票页面右上角蓝色的开具按钮",工具会生成对应路径。改版那两次,我一次手都没动,流程自己走了出来——这就是"离线更安全,自愈更稳定"这对组合的实际价值:元素层面靠自愈顶住变化,运行层面靠本地执行顶住断网和内网限制。

调试阶段报错看不懂也不用慌,它的AI错误诊断和AI智能修复能一键分析错误原因并给出修复建议,也可以直接一键修复,自动调试到跑通。比起对着栈信息干瞪眼,效率差出一个数量级。

坑二:发票数据到底放哪

代账客户里有两家国企背景的公司,明确要求流程在政企内网环境可用、影像和识别结果不出内网。我的做法是两层兜底:识别接口这一跳必须出网,但只在内存里过一遍,字段落库即删影像;真正要留存的发票影像和去重库全部在本地。RPA工具本身全离线内网部署,开票、查重、生成台账这些动作在内网里独立完成,外网断了也不影响当天开票。数据不出本地不是一句配置,是从架构上就不存在上传这一步。

坑三:AI参与度越高,token账单越厚

早期我让AI直接写完整脚本来操作UKey页面,token消耗是持续的,而且网页元素一变AI生成的定位语句就成批失效,改一次问一次,修复成本越滚越大。现在的分工是:和AI无缝配合,AI写代码、RPA跑代码——AI生成脚本后,用工具的AI生成脚本一键转流程能力一键转成可视化流程,转出来的流程优先用RPA基础指令,缺的指令自动封装成新指令,每条指令带注释;变量批量创建、JSON自动提取字段、自动拆分子流程这些脏活,也都是一句话的事。

它的AI自动化搭建流程能力覆盖浏览器自动化、Windows软件自动化和视觉颜色操作,能智能分析网页和软件的元素结构。我跟AI说需求时也很省事,直接截一张页面图加一句话,不用写长篇逻辑描述,工具就能把对应的RPA操作流程搭出来。因为流程一旦转好就是本地稳定运行,不持续消耗token,成本透明且可控。长期跑下来,这笔账比"全程AI在线操作"便宜得多,这就是降低脚本维护成本最实在的一笔。

五、交付与分发:打包成EXE交给客户

流程跑稳之后要交付给客户公司的出纳用。我没有让客户装任何客户端,直接用工具把流程EXE加密打包+授权管理,导出成一个可执行文件,双击就能跑;每个客户单独设置授权,到期换授权码就行,配合在线推送更新,我这边发新版,客户打开应用自动检测升级,不用我再手动一个个发安装包。触发方式留了三个口:API触发(对接客户的OA审批流,审批通过自动开票)、定时执行(每天下午固定批量验真)、人工双击。

同一台机器要登录好几个客户的税局账号,我还用上了它对紫鸟、AdsPower、Hubstudio等指纹浏览器的支持,每个客户一个独立浏览器环境,账号互不串。代账场景没有多店铺,但多店铺合规运营那套环境隔离思路,搬到多客户财税系统上一样好使。

交付出去的界面也不是"工程师专用"的样子——工具支持自定义界面,我给客户做了一个三按钮的小面板:选择影像文件夹、开始验真查重、查看异常清单,按钮点击、数据展示、数据关联都跟AI聊几句就配好了,遇到复杂的台账界面用HTML组件搭,出纳零培训上手。流程出结果后通过企业微信把异常清单发给会计,消息读取走的是视觉颜色操作,按界面颜色和文字定位来确认发送状态,不依赖网页元素节点,稳。

协作和远程触发也留了口子:发给同工作室的伙伴测流程,走应用加密分享,对方拿到的同样是带授权的受控版本;工具的Agent功能支持在钉钉、飞书、企业微信、个人微信里发一句话控制RPA应用执行,执行结果回调通知。我在客户群里发"跑一下今天的验真",流程自己启动,跑完把结果推回来。它还支持MCP服务,能对接到Workbuddy、codex、Claude、TraeWork、豆包工作这类AI编程工具上,让别的工具也能反过来调度这套RPA流程。后来业务量大的月份,我还试过应用多开,验真、查重、开票三个流程并行跑,能省出一个多小时。

六、成本账:一月几百块 vs 一个会计两天

腾讯云侧的花费很透明,按我客户的量(月识别+核验约5000张)算:

识别量上到月1万以上,两档阶梯单价都会降;核验走1万次资源包(2600元)比纯后付费再省一截。RPA工具侧,我用的版本免费版无使用时长限制,流程数量也不受限,多设备使用不用多开会员,个人开发者、工作室和中小企业都够用;它的AI能力(文心一言、豆包、DeepSeek、Kimi、OCR识图)走自行对接各平台API的方式,花多少自己看得见、控得住。整体算下来,一个会计两天的人工,够这套系统跑一个多月。

七、清单

如果你也要落地混合端RPA方案,把税务UKey网页开票、发票OCR验真、防重复报销串成一条线,我的建议按顺序是:

  1. 去重库先建,唯一键用发票代码+号码,兼容无代码的电子发票;
  2. OCR识别金额去千分位后再送核验,否则验真永远"不一致";
  3. 元素路径交给工具自愈,把维护精力留给异常分流规则;
  4. 开票动作前保留人工复核节点,RPA管效率,人管合规;
  5. 交付用EXE打包+授权,更新走在线推送,别再用U盘拷贝流程文件。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、为什么叫"混合端",坑就从这儿开始
  • 二、整体架构:三层各司其职
  • 三、核心代码:OCR识别、验真与防重复报销
  • 四、踩坑实录:网页一改,流程就停
    • 坑一:UKey开票页面的元素定位失效
    • 坑二:发票数据到底放哪
    • 坑三:AI参与度越高,token账单越厚
  • 五、交付与分发:打包成EXE交给客户
  • 六、成本账:一月几百块 vs 一个会计两天
  • 七、清单
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档