详解如何通过Python实现批量数据提取
作者:ncq的小舔狗 发布时间:2021-12-23 01:19:10
每天面对成堆的发票,无论是发票还是承兑单据,抑或是其他各类公司数据要从照片、PDF等不同格式的内容中提取,我们都有必要进行快速办公的能力提升。
因此,我们的目标要求就十分明显了,首先要从图片中获取数据,其次将数据统一导入到EXCEL中。
配置需求
1.ImageMagick
2.tesseract-OCR
3.Python3.7
4.from PIL import Image as PI
5.import io
6.import os
7.import pyocr.builders
8.from cnocr import CnOcr
9.import xlwt
分析上图发现票据金额为“贰拾万元整”,数据金额为大写中文,因此在导入Excel之前我们需要将金额票据的数据转换成数字的格式,基于此,我们需要首先完成大写汉字和数字的转换。
def chineseNumber2Int(strNum: str):
result = 0
temp = 1 # 存放一个单位的数字如:十万
count = 0 # 判断是否有chArr
cnArr = ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
chArr = ['拾', '佰', '仟', '万', '亿']
for i in range(len(strNum)):
b = True
c = strNum[i]
for j in range(len(cnArr)):
if c == cnArr[j]:
if count != 0:
result += temp
count = 0
temp = j + 1
b = False
break
if b:
for j in range(len(chArr)):
if c == chArr[j]:
if j == 0:
temp *= 10
elif j == 1:
temp *= 100
elif j == 2:
temp *= 1000
elif j == 3:
temp *= 10000
elif j == 4:
temp *= 100000000
count += 1
if i == len(strNum) - 1:
result += temp
return result
通过上述代码即可实现大写字母与数字的转换,例如输入“贰拾万元整”即可导出“200000”,再将其转换成数字后即可极大地简化表格的操作,也可以在完成表格操作的同时有利于数据归档。
接下来,我们需要分析发票的内部内容,分析下图可知,我们需要获取以下几个数据内容:“出票日期”、“汇票到账日期”、“票据号码”、“收款人”、“票据金额”、“出票人”,可以通过画图软件获取精准定位。
如图,小黑点即鼠标所在地,画图软件左下角即他的坐标。
提取出票日期
def text1(new_img):
#提取出票日期
left = 80
top = 143
right = 162
bottom = 162
image_text1 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text1.show()
txt1 = tool.image_to_string(image_text1)
print(txt1)
return str(txt1)
提取金额
def text2(new_img):
#提取金额
left = 224
top = 355
right = 585
bottom = 380
image_text2 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text2.show()
image_text2.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
temp="".join(temp[0])
txt2=chineseNumber2Int(temp)
print(txt2)
return txt2
提取出票人
def text3(new_img):
#提取出票人
left = 177
top = 207
right = 506
bottom = 231
image_text3 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text3.show()
image_text3.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
txt3="".join(temp[0])
print(txt3)
return txt3
提取付款行
def text4(new_img):
#提取付款行
left = 177
top = 274
right = 492
bottom = 311
image_text4 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text4.show()
image_text4.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
txt4="".join(temp[0])
print(txt4)
return txt4
提取汇票到账日期
def text5(new_img):
#提取汇票到日期
left = 92
top = 166
right = 176
bottom = 184
image_text5 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text5.show()
txt5 = tool.image_to_string(image_text5)
print(txt5)
return txt5
提取票据单据
def text6(new_img):
#提取票据号码
left = 598
top = 166
right = 870
bottom = 182
image_text6 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text6.show()
txt6 = tool.image_to_string(image_text6)
print(txt6)
return txt6
在将数据全部提取完成之后,即进入设置环节,我们需要首先将所有账单文件进行提取,获取他们的文件名和路径。
ocr=CnOcr()
tool = pyocr.get_available_tools()[0]
filePath='img'
img_name=[]
for i,j,name in os.walk(filePath):
img_name=name
在获取完整后,即可进行数据导入Excel的操作。
count=1
book = xlwt.Workbook(encoding='utf-8',style_compression=0)
sheet = book.add_sheet('test',cell_overwrite_ok=True)
for i in img_name:
img_url = filePath+"/"+i
with open(img_url, 'rb') as f:
a = f.read()
new_img = PI.open(io.BytesIO(a))
## 写入csv
col = ('年份','出票日期','金额','出票人','付款行全称','汇票到日期','备注')
for j in range(0,7):
sheet.write(0,j,col[j])
book.save('1.csv')
shijian=text1(new_img)
sheet.write(count,0,shijian[0:4])
sheet.write(count,1,shijian[5:])
sheet.write(count,2,text2(new_img))
sheet.write(count,3,text3(new_img))
sheet.write(count,4,text4(new_img))
sheet.write(count,5,text5(new_img))
sheet.write(count,6,text6(new_img))
count = count + 1
至此,完整流程结束。
附上源码全部
from wand.image import Image
from PIL import Image as PI
import pyocr
import io
import re
import os
import shutil
import pyocr.builders
from cnocr import CnOcr
import requests
import xlrd
import xlwt
from openpyxl import load_workbook
def chineseNumber2Int(strNum: str):
result = 0
temp = 1 # 存放一个单位的数字如:十万
count = 0 # 判断是否有chArr
cnArr = ['壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
chArr = ['拾', '佰', '仟', '万', '亿']
for i in range(len(strNum)):
b = True
c = strNum[i]
for j in range(len(cnArr)):
if c == cnArr[j]:
if count != 0:
result += temp
count = 0
temp = j + 1
b = False
break
if b:
for j in range(len(chArr)):
if c == chArr[j]:
if j == 0:
temp *= 10
elif j == 1:
temp *= 100
elif j == 2:
temp *= 1000
elif j == 3:
temp *= 10000
elif j == 4:
temp *= 100000000
count += 1
if i == len(strNum) - 1:
result += temp
return result
def text1(new_img):
#提取出票日期
left = 80
top = 143
right = 162
bottom = 162
image_text1 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text1.show()
txt1 = tool.image_to_string(image_text1)
print(txt1)
return str(txt1)
def text2(new_img):
#提取金额
left = 224
top = 355
right = 585
bottom = 380
image_text2 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text2.show()
image_text2.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
temp="".join(temp[0])
txt2=chineseNumber2Int(temp)
print(txt2)
return txt2
def text3(new_img):
#提取出票人
left = 177
top = 207
right = 506
bottom = 231
image_text3 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text3.show()
image_text3.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
txt3="".join(temp[0])
print(txt3)
return txt3
def text4(new_img):
#提取付款行
left = 177
top = 274
right = 492
bottom = 311
image_text4 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text4.show()
image_text4.save("img/tmp.png")
temp = ocr.ocr("img/tmp.png")
txt4="".join(temp[0])
print(txt4)
return txt4
def text5(new_img):
#提取汇票到日期
left = 92
top = 166
right = 176
bottom = 184
image_text5 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text5.show()
txt5 = tool.image_to_string(image_text5)
print(txt5)
return txt5
def text6(new_img):
#提取票据号码
left = 598
top = 166
right = 870
bottom = 182
image_text6 = new_img.crop((left, top, right, bottom))
#展示图片
#image_text6.show()
txt6 = tool.image_to_string(image_text6)
print(txt6)
return txt6
ocr=CnOcr()
tool = pyocr.get_available_tools()[0]
filePath='img'
img_name=[]
for i,j,name in os.walk(filePath):
img_name=name
count=1
book = xlwt.Workbook(encoding='utf-8',style_compression=0)
sheet = book.add_sheet('test',cell_overwrite_ok=True)
for i in img_name:
img_url = filePath+"/"+i
with open(img_url, 'rb') as f:
a = f.read()
new_img = PI.open(io.BytesIO(a))
## 写入csv
col = ('年份','出票日期','金额','出票人','付款行全称','汇票到日期','备注')
for j in range(0,7):
sheet.write(0,j,col[j])
book.save('1.csv')
shijian=text1(new_img)
sheet.write(count,0,shijian[0:4])
sheet.write(count,1,shijian[5:])
sheet.write(count,2,text2(new_img))
sheet.write(count,3,text3(new_img))
sheet.write(count,4,text4(new_img))
sheet.write(count,5,text5(new_img))
sheet.write(count,6,text6(new_img))
count = count + 1
来源:https://blog.csdn.net/yyfloveqcw/article/details/129556574


猜你喜欢
- 本文简述了通过创建database link实现ORACLE跨数据库查询的方法1.配置本地数据库服务器的tnsnames.ora文件$vi
- 基本思路是使用opencv来把随机生成的字符,和随机生成的线段,放到一个随机生成的图像中去。虽然没有加复杂的形态学处理,但是目前看起来效果还
- 稀疏矩阵格式 coo_matrixcoo_matrix是最简单的稀疏矩阵存储方式,采用三元组(row, col, data)(或称为ijv
- 实现方法: 建立一个用户附加表InviteUser_NewUser,结构如下: 然后跟着我的思路走: 用户接这个链接后 =》 进
- 如何做一个分页程序? 这在ASP中确实容易实现,但需要技巧,看看下面的分页代码和说明: <angu
- 实际使用Pool 是用于存放临时对象的集合,这些对象是为了后续的使用,以达到复用对象的效果。其目的是缓解频繁创建对象造成的gc压力。在许多开
- 服务器:WINDOWS SERVER 2008 R2SQL:SQL SERVER 2008 R2背景:同一个公司同一个局域网 网
- 简单生成器有许多优点。生成器除了能够用更自然的方法表达一类问题的流程之外,还极大地改善了许多效率不足之处。在 Python 中,
- 因为mounted函数只会在html和模板渲染之后会加载一次,但是在子组件中只有第一次的数据显示是正常的,所以需要再增加一个updated函
- 原型:EventManager是一个重要的原型,它用来赋予对象自定义事件的能力当对象类型的原型继承EventManager时,对象具有定义、
- 一、身份验证配置在sqlserver服务端电脑打开SqlServer Managerment Studio管理工具,首先通过Windows身
- 本文实例讲述了Python3多进程 multiprocessing 模块。分享给大家供大家参考,具体如下:多进程 Multiprocessi
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:<!DOCTYPE html> <html> <head&
- 双系统配置及MySQL数据库存储情境:Windows XP下d:\mysql\data中存有MySQL数据库,Linux系统为Ubuntu
- 因为工作中需要,需要生成一个带表格的图片例如:直接在html中写一个table标签,然后单独把表格部分保存成图片或者是直接将excel中的内
- 关于break/continue这两个关键字在平常的使用过程中一直比较迷糊。好不容易理解了吧,过段时间不使用好像忘记了什么。这个问题也是很多
- 当mysql跨越互联网进行复制时别人可以窃取到mysql的复制信息,这些信息是明文的,因此存在不安全性,这里通过ssl对复制的信息进行加密。
- 代码如下:---在仓储管理中经常会碰到的一个问题 一、关于LIFO与FIFO的简单说明 ---FIFO: First in, First o
- 下面是出现的错误解释RuntimeError: An attempt ha
- 一、环境由于这学期开了图像处理这门课,所以想着在各种实验开始之前自己先动手试一下图像处理那首先要配个环境嘛,配环境真的是我长久以来的噩梦了,