利用阿里云的接口扫描图片中的Excel数据
背景
在日常工作的数据分析中,我们经常会遇到一些图片文件,上面是表格数据,那么我们怎么把这些数据写入常用的数据处理工具,如Excel,python中去呢?
最笨的方法当然是直接手动输入,但是这种方法效率极低,如果遇到长数据,上百条数据,经常输着输着就眼花缭乱了,更何况作为一个专业的数据处理人员,怎么能用这么耗时耗力的方法呢!
经过笔者的仔细研究,发现阿里云,腾讯云这些平台的云市场早就有这样的api接口,我们只需要把图片传过去,这些云平台就会在服务器上进行识别,传回给我们一个json文件,我们可以把这个json文件处理成Excel或者其他类型的数据。
接下来我们以处理为Excel表格数据为例来进行说明:
购买阿里云服务
首先我们调用的api接口在这个地方高精度OCR文字识别
我们需要购买之后才能知道自己账号的appcode,阿里云也是根据appcode来对使用次数进行监测。
注册阿里云的账号实名认证这几部就不细说了,接下来说一下怎么找自己的appcode,如下图所示:
点进最后一个栏目云市场,就可以找到自己的appcode
调用阿里云的api
# ocr高精度文字识别的官方文档
'''
调用地址:https://ocrapi-advanced.taobao.com/ocrservice/advanced
请求方式:POST
返回类型:JSON
请求参数(body)
{
//图像数据:base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,和url参数只能同时存在一个
"img": "",
//图像url地址:图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,和img参数只能同时存在一个
"url": "",
//是否需要识别结果中每一行的置信度,默认不需要。 true:需要 false:不需要
"prob": false,
//是否需要单字识别功能,默认不需要。 true:需要 false:不需要
"charInfo": false,
//是否需要自动旋转功能,默认不需要。 true:需要 false:不需要
"rotate": false,
//是否需要表格识别功能,默认不需要。 true:需要 false:不需要
"table": false,
//字块返回顺序,false表示从左往右,从上到下的顺序,true表示从上到下,从左往右的顺序,默认false
"sortPage": false
}
正常返回示例:
{
//唯一id,用于问题定位
"sid": "bfcb418f71fd057f11ea4e17b15688dc27f9d4c6a47a867a376f251706266353341da54c",
//算法版本
"prism_version": "1.0.6",
//识别的文字块的数量,prism_wordsInfo数组大小
"prism_wnum": 2,
//角度,
"angle": 范围:0-360,0表示向上,90表示向右,180表示向下,270度表示向左
//识别的文字的具体内容
"prism_wordsInfo": [
{
//文字块
"word": "2017",
//置信度
"prob": 99,
//文字块的位置,按照文字块四个角的坐标顺时针排列,分别为左上XY坐标、右上XY坐标、右下XY坐标、左下XY坐标
"pos": [
{
"x": 107,
"y": 203
},
{
"x": 247,
"y": 203
},
{
"x": 247,
"y": 213
},
{
"x": 107,
"y": 213
}
],
//单字信息
"charInfo": [
{
//单字文字
"word": "2",
//单字置信度
"prob": 99,
//单字左上角横坐标
"x": 777,
//单字左上角纵坐标
"y": 2993,
//单字宽度
"w": 26,
//单字长度
"h": 30
},
{
"word": "0",
"prob": 99,
"x": 803,
"y": 2989,
"w": 32,
"h": 37
},
{
"word": "1",
"prob": 99,
"x": 835,
"y": 2989,
"w": 38,
"h": 39
},
{
"word": "7",
"prob": 99,
"x": 873,
"y": 2988,
"w": 38,
"h": 40
}
],
//如果该文字块在表格内则存在该字段,tableId表示表格的id
"tableId": 0,
//如果该文字块在表格内则存在该字段,表示表格中单元格的id
"tableCellId": 0
}
],
//表格信息,如果不存在表格,则改字段内容为空
"prism_tablesInfo": [
{
//表格id,和prism_wordsInfo信息中的tableId对应
"tableId": 0,
//表格中横坐标单元格的数量
"xCellSize": 1,
//表格中纵坐标单元格的数量
"yCellSize": 1,
//单元格信息,包含单元格在整个表格中的空间拓扑关系
"cellInfos": [
{
//表格中单元格id,和prism_wordsInfo信息中的tableCellId对应
"tableCellId": 0,
//单元格中的文字
"word": ":2017",
//xStartCell缩写,表示横轴方向该单元格起始在第几个单元格,第一个单元格值为0
"xsc": 0,
//xEndCell缩写,表示横轴方向该单元格结束在第几个单元格,第一个单元格值为0,如果xsc和xec都为0说明该文字在横轴方向占据了一个单元格并且在第一个单元格内
"xec": 0,
//yStartCell缩写,表示纵轴方向该单元格起始在第几个单元格,第一个单元格值为0
"ysc": 0,
//yEndCell缩写,表示纵轴方向该单元格结束在第几个单元格,第一个单元格值为0
"yec": 0,
//单元格位置,按照单元格四个角的坐标顺时针排列,分别为左上XY坐标、右上XY坐标、右下XY坐标、左下XY坐标
"pos": [
{
"x": 107,
"y": 203
},
{
"x": 247,
"y": 203
},
{
"x": 247,
"y": 213
},
{
"x": 107,
"y": 213
}
]
}
]
}
]
}
失败返回示例:
{
"error_code": 400,
"error_msg": "img和url参数不能同时存在"
}
'''
# 调用api并返回json数据,储存
import urllib.request
import urllib.parse
import json
import time
import base64
jpg_path = r'图片绝对地址'
with open(jpg_path + '.jpg', 'rb') as f: # 以二进制读取本地图片
data = f.read()
encodestr = str(base64.b64encode(data),'utf-8')
#请求头
# 请修改为你自己的appcode,可从云市场订单或者api网关处获得
# 去注册了就在后台可以看到,把xxxxx改为你的appcode就好了
AppCode = "上文提到的APPCODE"
headers = {
'Authorization': 'APPCODE ' + AppCode,
'Content-Type': 'application/json; charset=UTF-8'
}
def posturl(url, data={}):
try:
params = json.dumps(dict).encode(encoding='UTF8')
req = urllib.request.Request(url, params, headers)
r = urllib.request.urlopen(req)
html =r.read()
r.close()
return html.decode("utf8")
except urllib.error.HTTPError as e:
print(e.code)
print(e.read().decode("utf8"))
time.sleep(1)
url_request = "https://ocrapi-advanced.taobao.com/ocrservice/advanced"
dict = {'img': encodestr,
'rotate': True,
'table': True}
html = posturl(url_request, data=dict)
text = json.loads(html)
将json串转化为Excel表格
xCellSize = text['prism_tablesInfo'][0]['xCellSize']
yCellSize = text['prism_tablesInfo'][0]['yCellSize']
word = text['prism_tablesInfo'][0]['cellInfos'][0]['word']
xsc = text['prism_tablesInfo'][0]['cellInfos'][0]['xsc']
xec = text['prism_tablesInfo'][0]['cellInfos'][0]['xec']
ysc = text['prism_tablesInfo'][0]['cellInfos'][0]['ysc']
yec = text['prism_tablesInfo'][0]['cellInfos'][0]['yec']
print('xCellSize:', xCellSize)
print('yCellSize:', yCellSize)
print('word:', word)
print('xsc:', xsc)
print('xec:', xec)
print('ysc:', ysc)
print('yec:', yec)
# 导入 xlwt 库
import xlwt
# 创建 xls 文件对象
wb = xlwt.Workbook()
# 新增两个表单页
sheet_name = 'test'
sh1 = wb.add_sheet(sheet_name, cell_overwrite_ok=True)
# 数据写入Excel
# len(text['prism_tablesInfo'])
# 有多个table
prism_tablesInfo = text['prism_tablesInfo']
for table in prism_tablesInfo:
cellInfos = table['cellInfos']
for cell in cellInfos:
word = cell['word']
xsc = cell['xsc']
xec = cell['xec']
ysc = cell['ysc']
yec = cell['yec']
sh1.write(ysc, xsc, word)
# 最后保存文件即可
save_file = '保存文件名'
wb.save(save_file + '.xlsx')