1. 为什么需要本地文本比对服务
在日常工作和学习中,我们经常会遇到需要比较文本相似度的场景。比如写论文时要检查引用内容是否重复,做数据分析时需要清洗相似记录,或者运营人员要排查重复发布的内容。传统做法要么是手动比对(眼睛都要看花),要么依赖第三方在线工具(隐私没保障)。这时候搭建一个本地化的文本比对服务就显得特别实用。
我去年帮一个做电商的朋友处理商品描述去重时就深有体会。他们每天要上传几百个商品,很多描述都是大同小异。如果每次都复制粘贴到网页工具里比对,不仅效率低下,关键是把未发布的商品信息传到第三方服务器也存在风险。后来我们用按键精灵+本地服务搭建的自动化方案,直接把效率提升了十几倍。
2. 搭建本地文本比对服务
2.1 环境准备
首先需要安装Node.js环境,这是目前最轻量级的本地服务方案。到官网下载LTS版本安装包,一路下一步就行。安装完成后在命令行输入:
node -v npm -v看到版本号说明安装成功。接着新建项目文件夹,初始化npm:
mkdir text-compare && cd text-compare npm init -y安装必要的依赖包。我们需要express处理HTTP请求,以及string-similarity这个超好用的文本相似度计算库:
npm install express string-similarity2.2 编写服务端代码
创建一个server.js文件,写入以下代码:
const express = require('express'); const similarity = require('string-similarity'); const app = express(); const port = 3000; // 中间件设置 app.use(express.urlencoded({ extended: true })); app.use(express.json()); // 核心比对接口 app.post('/compare', (req, res) => { const { text1, text2 } = req.body; if(!text1 || !text2) { return res.status(400).json({ error: '请提供text1和text2参数' }); } const score = similarity.compareTwoStrings(text1, text2); res.json({ similarity: score, percentage: `${(score * 100).toFixed(2)}%` }); }); // 启动服务 app.listen(port, () => { console.log(`服务已启动: http://localhost:${port}`); });这个服务做了三件事:
- 接收POST请求,获取待比较的text1和text2参数
- 使用string-similarity计算相似度(返回值0-1之间)
- 返回包含相似度分数和百分比的JSON数据
启动服务试试:
node server.js用Postman测试下,发送POST请求到http://localhost:3000/compare,Body选x-www-form-urlencoded,填入:
text1=苹果手机 text2=苹果手机壳应该会收到类似这样的响应:
{ "similarity": 0.8, "percentage": "80.00%" }3. 按键精灵对接本地服务
3.1 基础POST请求封装
按键精灵2014版虽然有点年头,但处理HTTP请求完全够用。新建脚本,添加以下函数:
Function CompareText(text1, text2) Dim http, url, params Set http = CreateObject("Msxml2.XMLHTTP") url = "http://localhost:3000/compare" params = "text1=" & text1 & "&text2=" & text2 http.Open "POST", url, False http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" http.Send params If http.Status = 200 Then Dim result result = http.responseText CompareText = ParseJson(result)("percentage") Else CompareText = "请求失败: " & http.Status & " " & http.statusText End If End Function这个函数做了几个关键处理:
- 设置正确的Content-Type请求头
- 将两个文本拼接到POST参数中
- 解析返回的JSON获取百分比结果
3.2 增强错误处理
实际使用时网络可能不稳定,添加重试机制:
Function SafeCompare(text1, text2, retryTimes) Dim i, result For i = 1 To retryTimes result = CompareText(text1, text2) If Left(result, 4) <> "请求失败" Then Exit For End If Delay 1000 // 等待1秒后重试 Next SafeCompare = result End Function3.3 实际应用案例
假设我们要检查两段商品描述的相似度:
desc1 = "全新苹果iPhone13 Pro Max 256GB 石墨色 国行正品" desc2 = "全新苹果iPhone13 Pro 128GB 银色 港版正品" similarity = SafeCompare(desc1, desc2, 3) TracePrint "相似度: " & similarity运行后会输出类似:"相似度: 72.34%"
4. 进阶优化技巧
4.1 性能优化方案
当需要批量比较时,直接串行请求效率太低。可以改用数组处理:
Dim texts(5) texts(0) = "文本1" texts(1) = "文本2" // ...填充更多文本 For i = 0 To UBound(texts)-1 For j = i+1 To UBound(texts) sim = SafeCompare(texts(i), texts(j), 2) TracePrint "文本" & i+1 & "与文本" & j+1 & "相似度: " & sim Next Next4.2 结果可视化
在按键精灵界面添加进度条显示:
Call Plugin.Msg.ShowScrTXT(0, 0, 800, 600, "文本比对进度", "CENTER", 12, 0, 0) For i = 1 To 100 // ...比对逻辑 Call Plugin.Msg.ShowScrTXT(0, 30, 800, 600, "已完成 " & i & "%", "CENTER", 12, 0, 0) Delay 50 Next4.3 服务监控
在Node.js服务端添加心跳检测:
// 添加健康检查接口 app.get('/health', (req, res) => { res.json({ status: 'UP', memoryUsage: process.memoryUsage() }); });按键精灵端可以定时检测:
Function CheckServiceHealth() Dim http Set http = CreateObject("Msxml2.XMLHTTP") http.Open "GET", "http://localhost:3000/health", False http.Send If http.Status = 200 Then Dim result result = ParseJson(http.responseText) TracePrint "服务状态: " & result("status") Else TracePrint "服务异常!" End If End Function5. 常见问题排查
5.1 连接被拒绝
如果按键精灵报"连接被拒绝",检查:
- Node服务是否启动成功
- 防火墙是否阻止了3000端口
- 服务地址是否拼写正确
5.2 中文乱码问题
确保两端编码一致:
- 服务端添加响应头:
res.setHeader('Content-Type', 'application/json; charset=utf-8');- 按键精灵设置请求头:
http.setRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"5.3 性能瓶颈
当处理长文本时(超过1000字),建议:
- 服务端添加长度限制
- 按键精灵端分段处理
- 使用更高效的算法(如simhash)
6. 扩展应用场景
这个方案不仅适用于文本比对,稍加改造还能实现:
- 本地敏感词过滤服务
- 自动化的内容审核系统
- 数据清洗的去重模块
我曾经用类似方案帮一个出版社搭建了稿件查重系统,编辑只需要把稿件拖到指定文件夹,按键精灵就会自动比对所有历史稿件,标记出重复率超过阈值的内容段落。