需求背景
图片形式的表格,截图,里面有包括公司名称在内的信息,要提取公司名称的名单,把它转成Excel的形式。单张图片的话,直接qq / 微信截图识别就可以,但是业务上是需要识别多张图片(至少20张),每月一到两次。
探索过程
一开始想的是找找相关的python包,类似与word2pdf、pdf转图片等等,也都有对应的包,我用着也还顺手。也找到了相关的包,but…
试了easyocr包,安装没啥问题,import导包就报错了,找了半天原因,无果。
试了BeautifulSoup包,运行出错,解决一个报错又冒出一个…几番折腾无果,马上放弃。
试了easyocr包,import导入就报错,这个torch模块一直有问题,查了半天资料,试了几种方法都没有解决,估计这个包没人在维护了,本身就出了问题。
试了TesseractOCR包,中间也报错了,不过在我坚持不懈之下,终于都解决了,装上 包,去github手动下载语言包,手动给他装上,run它,终于跑出来了,我打松一口气,心说:“忙活大半天,总算让我搞定了。”but…
一看控制台,识别的效果……惨不忍睹,一半的字都是错的!!
这才想起查资料的过程中看到一句话“可以识别出来,但是效果也就那样。”我当时还想着,肯定是你的原因,我来弄肯定效果不错,哈哈哈,网友不会骗人的。
终于,还是网友的话点醒了我“搞什么乱七八糟的代码啊包啊,还不如qq截图识别来的精确。”走投无路之下,脑中灵光一闪:qq识别的好,为什么不能用qq呢?有个东西可是叫“接口”啊。
于是回归主线,之前也试过百度云的接口,结果也没弄成,测代码一直提示身份验证不成功,于是就放弃了,当时也就顺带把其他的云接口判了死刑。现在没办法啊,能想到的方法都试过了,有枣没枣的打一杆子吧。
一试腾讯云,注册账号,开通服务,一测代码,成立!!效果就是qq、微信识图的程度!!腾讯云牛批!!
解决过程及代码
1.腾讯云注册账号和实名认证
登录这个地址 https://cloud.tencent.com/document/product/598/37140 现完成腾讯云账号注册和实名认证,再根据引导新建应用获取 id 和 key 。有了 id 和 key ,并不能马上跑代码,会报错说没有身份验证。
2.开通文字识别功能
点这个链接 https://cloud.tencent.com/login?s_url=https%3A%2F%2Fconsole.cloud.tencent.com%2Focr%2Fgeneral 去开通该功能,开通后到达下一个时间整点,再跑代码,就不会报错了。
3.代码逻辑
know()方法调用腾讯云的接口,对图片内容进行识别,返回的结果是json格式的文件,把返回json放到 https://www.json.cn 网站进行解析,看清楚json的具体结构,对症下药对json进行处理,提取我们想要的文字内容。
draw()方法里,把json转为字典,根据实际的特点提取到公司的名称,放到一个数组里。draw_puls()方法只是我根据实际情况对文字提取做的补丁,可以不用看。
得到了公司名称的数组,把它转为DataFrame,调用to_csv()或to_excel(),即可完成图片到Excel的转换,nice!
# 导包
import json
import poocr
import json
import os
def know(img_path):
'''
# 调用腾讯云的接口,识别图片内容,返回json格式
# 获取id和key的地址:https://cloud.tencent.com/document/product/598/37140
# 全部功能 的文档:https://mp.weixin.qq.com/s/WxICBZZSgkm-OrvXB82hbg
# 可以填写本地图片的地址:img_path,也可以填写在线图片的地址:img_url ,如果2个都填,则只用在线图片img_url
'''
id = 'AKIDhE******************************'
key = 'oQt7*****************************'
return poocr.ocr.GeneralBasicOCR(img_path, id=id, key=key)
def draw(jsons):
'''
# 提取公司名称,返回公司名称的数组
'''
df = json.loads(str(jsons).replace("'", "\"")) # 把json转为字典
entablishments = []
for words in df['TextDetections']:
word = words['DetectedText']
if ('限' in word) and ('司' in word):
entablishments.append(word)
return entablishments
def draw_puls(jsons):
'''
# 提取公司名称,返回公司名称的数组 【找可能会被遗漏的公司】
# finds数组可以更新!
'''
df = json.loads(str(jsons).replace("'", "\"")) # 把json转为字典
entablishments = []
point = 0 # 做一个指针
finds = ['个人独资企业','合伙企业','个人独资企业分支机构','农民专业合作社']
for words in df['TextDetections']:
point += 1 # 人为给字典标下标
word = words['DetectedText']
if any(find in word and find for find in finds):
entablishments.append(df['TextDetections'][point-2]['DetectedText'])
print(df['TextDetections'][point-2]['DetectedText'])
return entablishments
# 识别所有的公司名称
img_path = 'imgs'
paths = os.listdir(img_path)
entablishments_all = []
for p in paths:
result = know(img_path + '/' + p)
entablishments = draw(result)
entablishments_all.extend(entablishments)
dates = '2024-04' # 迁入日期
df = pd.DataFrame({
'公司名称': entablishments_all,
'迁入日期': dates
})
df.index = df.index + 1 # 更新索引从1开始
df.to_csv('迁入企业名单.csv', encoding='gbk')
最后的效果:
总结
这次解决这个问题,前后花了4天时间(当然是上班间隙,让我一个问题连续弄4天我也顶不住),断断续续的,倒也让我没被彻底难住、放弃。虽然就是一个简单的图片文字识别功能,手机上甚至都是自动识别,但是真正要将它适配到我们具体的工作场景时,就不是简单的事了。
拆分思维
一开始想的是找一个包,直接就帮我完成“输入图片——输出Excel”的过程,结果并没有那么理想的包,最终的完成过程是“输入图片——识别文字内容——编排文字格式——输出Excel”,由此也可见,当某个问题无法一下子解决时,可以尝试把问题分解开来,解决它的子问题,则整个问题也就会迎刃而解。
腾讯云的功能还有很多,个人注册也有免费试用额度,一般而言都够用了,还是编程界那句谚语:“不必再造车轮”,腾讯云帮我封装好了api,我拿来用就好了,不用想着自己设计一个什么代码。
水磨工夫
解决问题的能力只有在解决问题的过程中才能够提升。我从刚开始接触java时见到代码爆红就慌,到现在python爆红几次都一脸淡然。这其中解决了许许多多的问题,也就是在这种水磨工夫之下,厚积薄发,我成长了。有耐心、信心和一个小问题磕四天。回头看,我真要给自己点个赞!!
码字不易,如果文章对你有那么一丢丢启发,麻烦点个赞吧~
打个补丁-20240605
本月实际应用后,发现一个问题,多张图片进行识别,最后有个别图片的内容识别的不准确,导致公司的名字搜不到,影响后续工作。
识别不准确以后想回来原图片找找它的原图,结果很不好找。不知道是哪张图片里识别的。
因此,应该优化一下代码,把识别内容来自哪张图片也记录下来。
新建一个数组,同步记录每个识别内容的图片名称。这样就更方便了,当有发现识别有误的时候,再返回去看原始图片就OK了。哈哈,一段好用的代码总要经过一点一点的优化,共勉~