WPS AirScript脚本合集(十八):通过HTTP获取图片调用百度智能云OCR进行文字识别

之前发过一篇教程,WPS AirScript脚本合集(十五):文字识别!调用百度智能云OCR服务识别图片内容

指路链接:https://mp.weixin.qq.com/s/2fkNeV0y34xnE71cZRaD2Q

教程是直接将图片的URL放置在body的请求参数中,具体代码如下:

const resp2 = HTTP.fetch('https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=' + AccessToken, { 
      method: 'POST',
      timeout: 2000,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: `url=${encodeURIComponent(currentUrl)}` 
    });

    const ocrResult = resp2.json();

不过查看百度智能云文字识别的API文档,除了可以直接传参图片完整URL外,还可以传参图像数据,指路链接:https://cloud.baidu.com/doc/OCR/s/1k3h7y3db,而且参数处理的优先级是image 优先于url

那就来试试image的请求方式吧~

一、WPS网络API开发指南

由于涉及到发送HTTP请求服务,所以需要先在脚本编辑器对应的脚本内添加网络API

对应的开发指南看这里:https://open.wps.cn/documents/app-integration-dev/guide/dbsheet/AirScript/AirScript-advanced-http.html

二、多维表格数据表及字段结构

1、数据表名:百度智能云文字识别

2、视图名:表格视图

3、字段设置:

  • 字段名称:编号 - 字段类型:编号 - 编号格式:000001

  • 字段名称:图片 - 字段类型:图片和附件 -显示样式:已缩略图样式显示 - 图片上传方式:无需勾选 仅可通过移动端拍摄上传

  • 字段名称:图片识别结果 - 字段类型:文本 - 禁止录入重复值:否 - 默认值:无

  • 字段名称:图片URL - 字段类型:文本 - 禁止录入重复值:否 - 默认值:无

三、自动化流程设置

注意“执行AirScript脚本”-配置参数-脚本入参和脚本返回值需切换英文输入法输入,如果第3步“修改记录”-配置参数-设置字段值点击+号无“第2步AirScript脚本的返回值”,需检查第2步“执行AirScript脚本”中配置参数-脚本入参和脚本返回值输入内容是否正确!

四、AirScript脚本

// 配置区
const ClientId = '填写百度智能云文字识别应用API的API Key';
const ClientSecret = '填写百度智能云文字识别应用API的Secret Key';

// 1. 获取当前记录ID
const recordid = Context.argv.recordid || Application.Selection.GetSelectionRecordIds()[0][0];
console.log("当前记录ID:", recordid);

// 2. 获取附件字段的值
const dbCellValue = Application.Sheets("百度智能云文字识别").Views("表格视图").RecordRange(recordid, "@图片").Value;
const attachments = dbCellValue.Value;

// 3. 创建URL数组和结果数组
const urlArray = [];
const recognitionResults = [];

// 将每个附件的URL添加到urlArray中
for (let i = 0; i < attachments.length; i++) {
    const attachment = attachments[i];
    console.log("LinkUrl:", attachment.LinkUrl);
    urlArray.push(attachment.LinkUrl);
}

console.log("URL数组:", urlArray);

// 4. 获取Access Token
const resp1 = HTTP.fetch('https://aip.baidubce.com/oauth/2.0/token', {
    method: 'POST',
    timeout: 2000,
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: `grant_type=client_credentials&client_id=${encodeURIComponent(ClientId)}&client_secret=${encodeURIComponent(ClientSecret)}`
});

const tokenResult = resp1.json();
console.log("access_token:", tokenResult.access_token);
const AccessToken = tokenResult.access_token;

// 5. 针对数组中的每个URL先获取图片并转换为base64,再去掉头部并进行urlencode
for (let j = 0; j < urlArray.length; j++) {
    const currentUrl = urlArray[j];
    console.log(`正在处理第 ${j + 1} 个URL:`, currentUrl);
    
    try {
        // 5.1 通过HTTP获取图片数据
        const imageResponse = HTTP.get(currentUrl, {
            timeout: 10000  // 设置10秒超时
        });
        console.log(`第 ${j + 1} 个图片下载响应状态:`, imageResponse.status);

        if (imageResponse.status !== 200) {
            throw new Error(`图片下载失败,HTTP状态码: ${imageResponse.status}`);
        }

        // 5.2 将图片数据转换为Base64编码
        const base64WithHeader = `data:image/jpeg;base64,${imageResponse.binary().toString('base64')}`;
        console.log(`第 ${j + 1} 个图片Base64编码(含头部)长度:`, base64WithHeader.length);

        // 5.3 去掉Base64编码的头部信息
        // 移除"data:image/[格式];base64,"这样的头部,只保留纯Base64数据
        const pureBase64 = base64WithHeader.replace(/^data:image\/\w+;base64,/, '');
        console.log(`第 ${j + 1} 个图片纯Base64编码长度:`, pureBase64.length);

        // 5.4 对纯Base64数据进行URL编码
        const encodedBase64 = encodeURIComponent(pureBase64);
        console.log(`第 ${j + 1} 个图片URL编码后的Base64长度:`, encodedBase64.length);

        // 5.5 使用Base64数据调用OCR接口(而不是直接使用URL)
        const resp2 = HTTP.fetch('https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=' + AccessToken, { 
            method: 'POST',
            timeout: 2000,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: `image=${encodedBase64}`  // 使用image参数传递Base64数据
        });

        const ocrResult = resp2.json();
        console.log(`第 ${j + 1} 个OCR识别结果:`, ocrResult);

        // 6. 文字识别结果处理
        let result = '';
        if (!ocrResult || !ocrResult.words_result) {
            result = `第 ${j + 1} 个附件:未获取到OCR识别结果`;
        } else {
            result = ocrResult.words_result.map(item => item.words).join('\n');
        }
        
        // 将识别结果添加到结果数组中
        recognitionResults.push(result);
        console.log(`第 ${j + 1} 个识别结果:`, result);
        
    } catch (error) {
        console.error(`处理第 ${j + 1} 个URL时发生错误:`, error);
        recognitionResults.push(`第 ${j + 1} 个附件:识别失败 - ${error.message}`);
    }
}

// 7. 将所有识别结果合并为一个完整的字符串
const finalResult = recognitionResults.join('\n\n============\n\n');
console.log("最终识别结果字符串:", finalResult);

// 返回最终结果
return {
    urlArray: `${urlArray}`,
    finalResult: `${finalResult}`
}

五、脚本编辑器控制台输出

在对应视图中选中某一行记录,“图片”列需存在图片,然后打开WPS脚本编辑器,点击直接运行

执行结果如下:

六、动图演示

七、友情说明

如果是从云文档上传的图片,图片识别结果返回“识别失败 - 图片下载失败,HTTP状态码: 302”,大概率是因为访问这张图片需要WPS账号申请访问权限,不信的话可以登录另一个账号去尝试访问这张图片URL试试看哟o(∩_∩)o

广东省
浏览 155
2
2
分享
2 +1
5
2 +1
全部评论 5
 
λ公式探索者
得空细细看一下
· 广西
回复
bokuto
· 广东省
回复
 
λ公式探索者
就喜欢技术贴!!!!可惜不能关注你 对了,这个百度接口要收费吗
· 广西
回复
bokuto
官方文档有说明,个人认证每月1000次免费~
· 广东省
1
回复