做自动化开发三年,接过三十多个 RPA 项目,我越来越确信:纯可视化拖拽的 RPA 流程只能解决 60% 的问题;剩下 40% 的复杂场景,必须靠 Python 脚本兜底。
去年帮一家制造企业做 ERP 数据迁移,用某大厂 RPA 的可视化流程写了两百多步,逻辑越写越乱。更关键的是——社区版不支持打包 EXE,交付还得让客户装一整套客户端。后来改用 Python 封装核心算法,流程节点从两百多缩减到三十几个,效率提升 8 倍,最终打包成独立 EXE 交付,客户双击就能跑。
本文核心:RPA 深度集成 Python,实现自定义指令开发、第三方库调用、复杂数据处理,并打包成可独立运行的 EXE 应用。 文末附选型 checklist,帮你避开伪离线、假免费的坑。
import pandas as pd
input_path = args["excel_path"]
df = pd.read_excel(input_path)
result = df[
(df["金额"] > 1000) & (df["状态"] == "已完成")
].groupby("部门").agg({"金额": ["sum", "mean", "count"]}).reset_index()
args["output_json"] = result.to_json(orient="records", force_ascii=False)局限:代码分散难复用;很多工具社区版写多了就提示升级付费。
# data_processor.py
import sys, json, pandas as pd
from datetime import datetime, timedelta
def process_sales_data(input_file, output_file, date_range_days=30):
df = pd.read_excel(input_file)
df = df.dropna(subset=["订单号", "金额"])
df = df.drop_duplicates(subset=["订单号"], keep="first")
df["订单日期"] = pd.to_datetime(df["订单日期"])
cutoff = datetime.now() - timedelta(days=date_range_days)
df = df[df["订单日期"] >= cutoff]
mean_val, std_val = df["金额"].mean(), df["金额"].std()
df["是否异常"] = abs(df["金额"] - mean_val) > 3 * std_val
df["金额_环比"] = df["金额"].pct_change() * 100
df.to_excel(output_file, index=False)
return {"status": "success", "total_rows": len(df)}
if __name__ == "__main__":
result = process_sales_data(sys.argv[1], sys.argv[2], int(sys.argv[3]) if len(sys.argv)>3 else 30)
print(json.dumps(result, ensure_ascii=False))痛点:如果工具有运行时长限制(比如某工具社区版单次超 30 分钟自动中断),脚本执行到一半就被杀。选工具时务必确认:是否有运行时长限制、是否有流程数量限制。
将 Python 逻辑封装成 RPA 自定义指令,像原生组件一样拖拽调用。一次开发,全团队复用。
# custom_commands/data_cleaner.py
import pandas as pd, numpy as np
class DataCleaner:
@staticmethod
def execute(config):
df = pd.read_excel(config["input_path"])
original = len(df)
for op in config.get("operations", []):
if op["type"] == "remove_duplicates":
df = df.drop_duplicates(subset=op["params"]["subset_cols"])
elif op["type"] == "fill_missing":
s = op["params"].get("strategy", "mean")
for c in df.select_dtypes(include=[np.number]).columns:
df[c] = df[c].fillna(df[c].mean() if s=="mean" else df[c].median())
df.to_excel(config["output_path"], index=False)
return {"status": "success", "original": original, "final": len(df)}
def main(args): return DataCleaner.execute(args)核心优势:自定义指令数量没有上限,不会被工具方限制。
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.chart import BarChart, Reference
def create_report(data_path, output_path):
wb = openpyxl.Workbook()
ws = wb.active
df = pd.read_excel(data_path)
for col, h in enumerate(df.columns, 1):
cell = ws.cell(row=1, column=col, value=h)
cell.font = Font(bold=True, color="FFFFFF")
cell.fill = PatternFill(start_color="4472C4", fill_type="solid")
for r, row in enumerate(df.values, 2):
for c, v in enumerate(row, 1):
ws.cell(row=r, column=c, value=v)
chart = BarChart()
chart.add_data(Reference(ws, min_col=2, min_row=1, max_row=len(df)+1))
ws.add_chart(chart, "H2")
wb.save(output_path)import requests
from bs4 import BeautifulSoup
def scrape(url_list):
results = []
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
for url in url_list:
resp = requests.get(url, headers=headers, timeout=15)
soup = BeautifulSoup(resp.text, "html.parser")
results.append({
"title": soup.select_one("h1").get_text(strip=True) if soup.select_one("h1") else "",
"price": soup.select_one("span.price").get_text(strip=True) if soup.select_one("span.price") else ""
})
return resultsimport pdfplumber
def extract_pdf_tables(pdf_path, output_excel):
tables = []
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
for t in page.extract_tables():
tables.append(pd.DataFrame(t[1:], columns=t[0]))
if tables:
pd.concat(tables).to_excel(output_excel, index=False)痛点:5 个电商平台字段命名不一致、货币单位不统一、时间格式混乱、重复订单。
class OrderDataProcessor:
FIELD_MAP = {
"订单金额": ["订单金额", "实付金额", "payment_amount", "total_amount"],
"订单号": ["订单号", "order_id", "订单编号"],
"下单时间": ["下单时间", "order_time", "create_time"]
}
RATES = {"CNY": 1.0, "USD": 7.25, "EUR": 7.85}
@classmethod
def standardize(cls, df, platform):
mapping = {c: s for s, ps in cls.FIELD_MAP.items() for c in df.columns if c in ps}
df = df.rename(columns=mapping)
df["来源"] = platform
return df
@classmethod
def parse_amount(cls, val, cur="CNY"):
try:
return float(str(val).replace(",","").replace("¥","")) * cls.RATES.get(cur,1)
except: return 0
@classmethod
def process(cls, files):
dfs = []
for f in files:
df = pd.read_excel(f["path"])
df = cls.standardize(df, f["platform"])
if "订单金额" in df.columns:
df["金额_人民币"] = df["订单金额"].apply(lambda x: cls.parse_amount(x, f.get("currency","CNY")))
dfs.append(df)
merged = pd.concat(dfs).drop_duplicates(subset=["订单号","金额_人民币"], keep="first")
return merged客户环境往往:无 Python、不能装软件、内网隔离、要求双击即用。传统 PyInstaller 问题多:依赖缺失、体积大、无授权机制。更关键的是——很多工具社区版根本不支持打包 EXE。
能力 | 价值 |
|---|---|
一键打包 EXE,零环境依赖 | 客户双击即用 |
自定义操作界面 | 看起来像正经软件 |
内网离线运行 | 满足安全合规 |
硬件指纹绑定(CPU序列号+主板UUID) | 防止无限复制 |
功能白名单(基础/专业/企业版) | 差异化授权 |
加密分享(AES-256) | 安全交付 |
API 触发(本地 HTTP 接口) | 嵌入现有系统 |
定时执行(内置 Cron) | 自动化运维 |
IM 集成(钉钉/飞书/企微) | 降低使用门槛 |
授权策略:
硬件指纹绑定:
绑定方式: CPU序列号 + 主板UUID
防破解: 授权文件与硬件指纹强关联,复制到其他机器无法运行
功能白名单:
基础版: [数据清洗, 格式转换]
专业版: [基础版 + 数据分析, 图表生成]
企业版: [全部功能]
加密分享:
算法: AES-256
方式: 生成加密授权文件,接收方导入即激活打包 EXE 后最大维护痛点是版本更新。理想方案:应用启动时自动检测服务器新版本,静默下载并提示重启。 修复 bug 后无需手动给每个客户发安装包,打开应用就能自动更新。
很多工具宣传"支持本地部署",实测:首次启动需联网激活 License、定期联网续期、流程文件默认同步云端、保存后读取发现往 sync 域名发流量。
真离线必须满足:License 本地校验、流程数据本地存储、组件内置完整、72 小时网络审计零外联。
加固项 | 操作 | 验证方法 |
|---|---|---|
运行账号最小权限 | 专用账号,仅授权必要目录 | 访问无关目录应被拒绝 |
网络行为审计 | 防火墙阻断所有出站 | Wireshark 采集 72h 零外联 |
流程文件防拷贝 | 硬件指纹绑定 + 授权密码 | 未授权设备运行报错 |
数据不出域 | 流程数据本地闭环 | 监控网络流量确认 |
部分工具采用"平台统一接入、按调用量收费",存在中间商加价、无法自选模型、数据过第三方服务器的风险。更隐蔽的是——有些工具把 AI 调用量算进自己计费体系,你被收了过路费还不自知。
import requests, json
class AIManager:
CONFIGS = {
"deepseek": {"url": "https://api.deepseek.com/v1/chat/completions", "model": "deepseek-chat"},
"kimi": {"url": "https://api.moonshot.cn/v1/chat/completions", "model": "moonshot-v1-8k"},
"doubao": {"url": "https://ark.cn-beijing.volces.com/api/v3/chat/completions", "model": "doubao-pro-128k"},
"wenxin": {"url": "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions", "model": "ernie-bot-4"}
}
def __init__(self, model, api_key):
self.cfg = self.CONFIGS[model]
self.key = api_key
def chat(self, prompt, system="你是一个专业的数据处理助手"):
r = requests.post(self.cfg["url"], headers={"Authorization": f"Bearer {self.key}"}, json={
"model": self.cfg["model"], "messages": [{"role":"system","content":system},{"role":"user","content":prompt}]
}, timeout=30)
return r.json()["choices"][0]["message"]["content"]费用优势:按官方 API 标准计费无中间商差价、用多少付多少成本可控、数据直发官方服务器路径透明、支持内网代理转发满足隔离环境。
import base64
def image_to_text(image_path, api_key):
with open(image_path, "rb") as f:
img = base64.b64encode(f.read()).decode()
r = requests.post("https://api.moonshot.cn/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}"},
json={"model": "moonshot-v1-8k-vision-preview",
"messages": [{"role": "user", "content": [
{"type": "text", "text": "提取图片中所有文字,JSON返回"},
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{img}"}}
]}]})
return r.json()["choices"][0]["message"]["content"]from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import subprocess
def launch_browser(browser_type="ziniao", profile_id="profile_001"):
configs = {
"ziniao": {"exe": "C:\\Program Files\\紫鸟浏览器\\ZiniaoBrowser.exe", "port": 9222},
"bitbrowser": {"exe": "C:\\Program Files\\比特浏览器\\BitBrowser.exe", "port": 9233},
"hubstudio": {"exe": "C:\\Program Files\\Hubstudio\\Hubstudio.exe", "port": 9244},
"adspower": {"api": "http://local.adspower.net:50325/api/v1/browser/start"}
}
cfg = configs[browser_type]
if browser_type != "adspower":
subprocess.Popen([cfg["exe"], f"--remote-debugging-port={cfg['port']}", f"--profile-id={profile_id}"])
opt = Options()
opt.add_experimental_option("debuggerAddress", f"127.0.0.1:{cfg['port']}")
return webdriver.Chrome(options=opt)
else:
r = requests.get(cfg["api"], params={"user_id": profile_id}).json()
opt = Options()
opt.add_experimental_option("debuggerAddress", r["data"]["ws"]["selenium"])
return webdriver.Chrome(options=opt)2026 年趋势:Agentic RPA——大模型理解意图,RPA 执行动作,支持在 IM 内控制应用执行并回调通知结果。
def handle_dingtalk(message, cfg):
ai = AIManager("deepseek", cfg["api_key"])
parsed = json.loads(ai.chat(f"解析意图和参数,JSON返回:{message}"))
# 触发本地 RPA
result = requests.post("http://127.0.0.1:16888/api/run",
json={"flow": parsed["flow_name"], "params": parsed["parameters"]},
timeout=300).json()
# 回调通知 IM
reply = f"任务{'完成' if result['status']=='success' else '失败'}\n结果:{result.get('output','')}"
requests.post(cfg["webhook"], json={"text": reply})
# Webhook 回调业务系统
if cfg.get("callback_url"):
requests.post(cfg["callback_url"], json={"task_id": result.get("id"), "status": result["status"]})
return reply成本项 | 某大厂社区版 | 某工具企业版 | 无限制方案 |
|---|---|---|---|
基础使用费 | 免费 | 8000元/年起 | 免费版零成本 |
打包 EXE | ❌ 不支持 | ✅ 支持 | ✅ 免费版支持 |
运行时长限制 | 30分钟/次 | 无限制 | ✅ 无限制 |
流程数量限制 | 5个 | 无限制 | ✅ 无限制 |
多设备使用 | 需多开会员 | 按设备授权 | ✅ 无需多开会员 |
AI 调用费用 | 平台加价30% | 平台加价30% | ✅ 自备API,零加价 |
离线部署 | 需联网激活 | 部分支持 | ✅ 完全离线 |
数据存储 | 强制同步云端 | 可选本地 | ✅ 本地存储 |
关键结论:个人开发者接单交付、工作室给客户提供数据服务、中小企业内部自动化——无运行时长限制、无流程数量限制、多设备无需多开会员这三个特性直接决定项目可行性和利润率。
画像 | 场景 | 核心价值 |
|---|---|---|
个人开发者 | 接单交付自动化工具 | 打包EXE + 授权管控 = 产品化交付 |
个人工作室 | 给客户提供数据服务 | 内网离线 + 费用透明 = 合规可控 |
中小企业 | 内部流程自动化 | 免费起步 + 多设备无限制 = 低成本 |
政务/金融/医疗 | 敏感数据处理 | 数据本地 + 审计闭环 = 安全合规 |
跨境电商 | 多店铺运营自动化 | 指纹浏览器 + 离线运行 = 安全稳定 |
基础能力:内嵌 Python?外部脚本?自定义指令?第三方库安装方便?
交付能力:一键打包 EXE?零环境依赖?自定义界面?授权管控(时间/硬件指纹/功能)?
安全合规:完全离线?License 本地校验?数据不上云?AI 费用透明?
扩展能力:API 触发?定时执行?IM 集成(钉钉/飞书/企微/微信)?指纹浏览器对接?回调通知?
成本评估(重点!):免费版是否阉割?是否有运行时长限制?是否有流程数量限制?多设备是否需多开会员? AI 是否强制走平台计费?打包 EXE 是否额外收费?
坑一:伪免费。某工具社区版只能保存 5 个流程、单次运行 30 分钟自动中断、不支持打包 EXE。真正的免费版:无使用时长限制、无流程数量限制、支持打包 EXE、AI 自备 API。
坑二:伪离线。某工具首次启动需联网激活 License、保存流程后读取发现往 sync 域名发流量。真正的离线:License 本地校验、数据本地存储、组件内置完整、72h 网络审计零外联。
坑三:多设备割韭菜。某工具按设备收费,家里一台、公司一台、客户现场一台就得买 3 份授权。务必确认是否支持多设备无需多开会员。
坑四:元素维护成本高。传统 RPA 依赖 XPath,网页改版后全部失效。支持元素获取本地智能生成的工具,可自动推荐最稳定的元素路径,大幅降低维护成本。
RPA 调用 Python 脚本是复杂自动化场景的必选项。可视化流程串联业务步骤,Python 脚本处理复杂逻辑,两者结合才能覆盖真实世界需求。
工具选型是关键。免费可用、离线运行、打包交付、授权管控、费用透明、无运行时长限制、无流程数量限制、多设备无需多开会员——这几个需求叠加,可选范围其实很小。建议按 checklist 逐项实测,不要只看宣传文档。
数据安全是底线,交付体验是竞争力,成本控制是生存线。把这三件事做好,RPA + Python 就能从内部脚本变成可交付的产品。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。