Python實現(xiàn)批量識別圖片文字并保存到excel中
1. 需求分析
識別圖片中的文字【采用百度的通用文字識別】;
文字篩選,按照分類獲取對應的文本;
采用 openpyxl 實現(xiàn)將數(shù)據(jù)存入 excel 中。
2. 獲取 access_token
獲取本地緩存的 access_token;
如果本地緩存的 access_token 過期,從百度獲取遠程 access_token。
# 獲取 access_token
def get_access_token():
access_token = get_local_access_token()
if access_token == False:
return get_request_access_token()
else:
return access_token
3. 本地 access_token
是否存在保存 token 的文件夾,不存在就創(chuàng)建,并且返回 False,表示本地沒有找到 access_token;
獲取文件夾中的 access_token 文件,篩選文本文件,access_token 保存在文本文件中;
如果沒有找到保存 access_token 的文件,返回 False;
獲取文件名中的數(shù)字,進行排序,獲取最后一個最新的文件;
獲取存儲token的時間;
由于token的有效時間是30天,因此判斷29進行刷新;
獲取token執(zhí)行的當前時間;
判斷如果超出有效期,重新刷新 access_token;
獲取本地文件中緩存的 access_token。
# 獲取本地的 access_token
def get_local_access_token():
# 是否存在保存 token 的文件夾,不存在就創(chuàng)建,并且返回 False,表示本地沒有找到 access_token
if not os.path.exists(f'./token/'):
os.makedirs(f'./token/')
return False
# 獲取文件夾中的token
files = os.listdir("./token")
file_names = list(filter(lambda x : x.split('.').pop() in ['txt'], files))
# 如果沒有找到保存 access_token 的文件,返回 False
if len(file_names) == 0:
return False
sort_names = list(sorted(file_names, key=lambda x:(int(re.sub('\D', '', x)),x)))
last_time_name = sort_names[-1]
# 存儲token的時間
save_time = int(re.sub('\D', '', last_time_name))
# 由于token的有效時間是30天,因此判斷29進行刷新
effective_time = 60 * 60 * 24 * 29
# 獲取token執(zhí)行的當前時間
current_time = int(time.time())
# 保存 access_token 的變量
access_token = ""
# 判斷如果超出有效期,重新刷新 access_token
if current_time - save_time > effective_time:
return False
else:
# 獲取本地文件中緩存的 access_token
with open("./token/" + last_time_name, "r",encoding="utf-8") as f:
access_token = f.read()
return access_token
4. 遠程 access_token
使用在百度控制臺獲取的 key 和 secret,組裝一個獲取 access_token 的地址;
定義一個發(fā)起請求的 headers ;
使用 requests 發(fā)起請求,獲取 access_token ;
獲取返回結(jié)果【response】中的 access_token ;
判斷 access_token 存在,就以當前時間戳為文件名,將 access_token 寫入文件中;
返回獲取的遠程的 access_token;
如果 access_token 無效,輸出報錯,關閉彈窗。
# 獲取百度的 access_token
def get_request_access_token():
url = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={key}&client_secret={secret}'
payload = ""
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
if response:
access_token = response.json().get('access_token')
if access_token:
with open("./token/" + str(int(time.time())) + ".txt", "w",encoding="utf-8") as f:
f.write(access_token)
return str(access_token)
else:
print(response.json())
print('無正確的 access_token 返回!?。?)
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
5. 獲取所有需要識別的圖片
獲取文件夾下的所有文件名稱;
過濾獲取所有的圖片文件名列表。
# 獲取文件夾下所有圖片文件名稱
def get_all_image_names(path):
names = os.listdir(path)
image_names = list(filter(lambda x : x.split('.').pop() in ['jpg', 'png', 'jpeg', 'bmp'], names))
return image_names
6. 獲取所有圖片的圖片信息
使用 all_list_data 存儲返回圖片的信息;
循環(huán)圖片名列表,讀取每一張圖片的信息;
返回所有圖片的信息。
# 獲取所有圖片的圖片信息
def get_all_image_info(path, image_names, access_token):
all_list_data = []
for name in image_names:
all_list_data += get_image_to_text(access_token, f"{path}/{name}")
# print('all_list_data',all_list_data)
return all_list_data
7. 獲取圖片中的文字
設置采用識別文字的api接口;
讀取圖片,組裝為請求參數(shù);
用請求接口和 access_token 拼接為完整的獲取圖片中文本信息的接口;
使用 requests 發(fā)起請求,獲取圖片中識別的文本信息;
讀取返回的文本結(jié)果 words_result;
如果 words_result 存在,使用 words_to_object 對每個返回結(jié)果進行處理;
否則輸出錯誤,同時關閉窗口。
# 獲取圖片中的文字
def get_image_to_text(access_token, path):
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
# 二進制方式打開圖片文件
with open(path, 'rb') as f:
img = base64.b64encode(f.read())
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
words_result = response.json().get("words_result")
if words_result:
print(f'圖片:{path} 讀取完成!')
return words_to_object(words_result)
time.sleep(0.5)
else:
print(response.json())
print('識別文字無返回?。?!')
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
8. 文本信息篩選
通過【收益率】獲取需要數(shù)據(jù)的起始標識;
篩選獲取【清倉次數(shù)】關鍵字,為當前次進入;
否則【清倉】存在,就是結(jié)束。
# 將文本信息列表轉(zhuǎn)字典
def words_to_object(words_result):
start = 0
date_list = []
# print('words_result',words_result)
# 獲取起始角標
for index,item in enumerate(words_result):
if item.get("words") == "收益率":
start = index
break
for index,item in enumerate(words_result):
if index > start:
words = item.get("words")
if '清倉次數(shù)' in words:
words_split = words.split(',清倉盈利')
value = words_split[1]
start_word = index
if value == '' and words_result[index + 1]:
value = words_result[index + 1].get("words")
start_word = index + 1
if index < len(words_result) - 1:
date_list.append({
"name": words_split[0],
"value": value,
"lists": [[]]
})
elif '清倉' in words:
date_list[-1]["lists"][-1].append(words)
if index < len(words_result) - 1 and '清倉次數(shù)' not in words_result[index + 1].get("words"):
date_list[-1]["lists"].append([])
else:
if index > start_word:
date_list[-1]["lists"][-1].append(words)
return date_list
9. 讀取數(shù)據(jù)保存到excel中
將需要的數(shù)據(jù)拼接到一個列表中;
獲取盈利數(shù)據(jù)轉(zhuǎn)浮點數(shù),返回列表;
對盈利點數(shù)求和;
通過盈利點數(shù)排序;
通過持有天數(shù)排序;
循環(huán)將數(shù)據(jù)存入到excel表格中;
判斷表格是否存在,存在就刪除,重新保存;
不存在就直接保存;
關閉彈窗,程序運行結(jié)束。
# 將讀取數(shù)據(jù)保存到excel中
def save_info_to_excel(infos):
info = openpyxl.Workbook()
sheet = info.active
all_infos = []
for item in infos:
lists = item.get("lists")
if lists and len(lists) > 0:
all_infos += lists
all_infos_total = list(map(lambda vals: float(vals[2].replace(',','')), all_infos))
total = sum(all_infos_total)
# print('total',total)
sorted_infos = list(sorted(all_infos, key=lambda vals: float(vals[2].replace(',',''))))
# print('sorted_infos',sorted_infos)
days_infos = list(sorted(all_infos, key=lambda vals: int(vals[1])))
# print('days_infos',days_infos)
for index,vals in enumerate(all_infos):
# 直接數(shù)據(jù)列表
sheet.cell(row=index+1, column=1).value = vals[0]
sheet.cell(row=index+1, column=2).value = vals[1]
sheet.cell(row=index+1, column=3).value = vals[2]
sheet.cell(row=index+1, column=4).value = vals[3]
sheet.cell(row=index+1, column=5).value = vals[4]
# 盈利金額排序
infos = sorted_infos[index]
sheet.cell(row=index+1, column=7).value = infos[0]
sheet.cell(row=index+1, column=8).value = infos[1]
sheet.cell(row=index+1, column=9).value = infos[2]
sheet.cell(row=index+1, column=10).value = infos[3]
sheet.cell(row=index+1, column=11).value = infos[4]
# 按照持有時間排序
days = days_infos[index]
sheet.cell(row=index+1, column=13).value = days[0]
sheet.cell(row=index+1, column=14).value = days[1]
sheet.cell(row=index+1, column=15).value = days[2]
sheet.cell(row=index+1, column=16).value = days[3]
sheet.cell(row=index+1, column=17).value = days[4]
# 總積
sheet.cell(row=len(all_infos) + 1, column=1).value = '總計'
sheet.cell(row=len(all_infos) + 1, column=2).value = round(total,2)
if not os.path.exists('./股票清倉信息.xlsx'):
info.save('./股票清倉信息.xlsx')
else:
os.remove('./股票清倉信息.xlsx')
info.save('./股票清倉信息.xlsx')
print('股票清倉信息.xlsx保存成功')
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
10. 獲取信息圖片示例


11. 運行實例

12. 運行結(jié)果

13. 各個文件的位置

14. 完整代碼
import requests
import json
import base64
import os
import time
import re
import openpyxl
from openpyxl.styles import *
id = '35108270'
key = 'xxx'
secret = 'xxx'
# 獲取 access_token
def get_access_token():
access_token = get_local_access_token()
if access_token == False:
return get_request_access_token()
else:
return access_token
# 獲取本地的 access_token
def get_local_access_token():
# 是否存在保存 token 的文件夾,不存在就創(chuàng)建,并且返回 False,表示本地沒有找到 access_token
if not os.path.exists(f'./token/'):
os.makedirs(f'./token/')
return False
# 獲取文件夾中的token
files = os.listdir("./token")
file_names = list(filter(lambda x : x.split('.').pop() in ['txt'], files))
# 如果沒有找到保存 access_token 的文件,返回 False
if len(file_names) == 0:
return False
sort_names = list(sorted(file_names, key=lambda x:(int(re.sub('\D', '', x)),x)))
last_time_name = sort_names[-1]
# 存儲token的時間
save_time = int(re.sub('\D', '', last_time_name))
# 由于token的有效時間是30天,因此判斷29進行刷新
effective_time = 60 * 60 * 24 * 29
# 獲取token執(zhí)行的當前時間
current_time = int(time.time())
# 保存 access_token 的變量
access_token = ""
# 判斷如果超出有效期,重新刷新 access_token
if current_time - save_time > effective_time:
return False
else:
# 獲取本地文件中緩存的 access_token
with open("./token/" + last_time_name, "r",encoding="utf-8") as f:
access_token = f.read()
return access_token
# 獲取百度的 access_token
def get_request_access_token():
url = f'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={key}&client_secret={secret}'
payload = ""
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
if response:
access_token = response.json().get('access_token')
if access_token:
with open("./token/" + str(int(time.time())) + ".txt", "w",encoding="utf-8") as f:
f.write(access_token)
return str(access_token)
else:
print(response.json())
print('無正確的 access_token 返回?。?!')
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
# 獲取圖片中的文字
def get_image_to_text(access_token, path):
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
# 二進制方式打開圖片文件
with open(path, 'rb') as f:
img = base64.b64encode(f.read())
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers)
if response:
words_result = response.json().get("words_result")
if words_result:
print(f'圖片:{path} 讀取完成!')
return words_to_object(words_result)
time.sleep(0.5)
else:
print(response.json())
print('識別文字無返回!??!')
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
# 將文本信息列表轉(zhuǎn)字典
def words_to_object(words_result):
start = 0
date_list = []
# print('words_result',words_result)
# 獲取起始角標
for index,item in enumerate(words_result):
if item.get("words") == "收益率":
start = index
break
for index,item in enumerate(words_result):
if index > start:
words = item.get("words")
if '清倉次數(shù)' in words:
words_split = words.split(',清倉盈利')
value = words_split[1]
start_word = index
if value == '' and words_result[index + 1]:
value = words_result[index + 1].get("words")
start_word = index + 1
if index < len(words_result) - 1:
date_list.append({
"name": words_split[0],
"value": value,
"lists": [[]]
})
elif '清倉' in words:
date_list[-1]["lists"][-1].append(words)
if index < len(words_result) - 1 and '清倉次數(shù)' not in words_result[index + 1].get("words"):
date_list[-1]["lists"].append([])
else:
if index > start_word:
date_list[-1]["lists"][-1].append(words)
return date_list
# 獲取所有圖片的圖片信息
def get_all_image_info(path, image_names, access_token):
all_list_data = []
for name in image_names:
all_list_data += get_image_to_text(access_token, f"{path}/{name}")
# print('all_list_data',all_list_data)
return all_list_data
# 獲取文件夾下所有圖片文件名稱
def get_all_image_names(path):
names = os.listdir(path)
image_names = list(filter(lambda x : x.split('.').pop() in ['jpg', 'png', 'jpeg', 'bmp'], names))
return image_names
# 將讀取數(shù)據(jù)保存到excel中
def save_info_to_excel(infos):
info = openpyxl.Workbook()
sheet = info.active
all_infos = []
for item in infos:
lists = item.get("lists")
if lists and len(lists) > 0:
all_infos += lists
all_infos_total = list(map(lambda vals: float(vals[2].replace(',','')), all_infos))
total = sum(all_infos_total)
# print('total',total)
sorted_infos = list(sorted(all_infos, key=lambda vals: float(vals[2].replace(',',''))))
# print('sorted_infos',sorted_infos)
days_infos = list(sorted(all_infos, key=lambda vals: int(vals[1])))
# print('days_infos',days_infos)
for index,vals in enumerate(all_infos):
# 直接數(shù)據(jù)列表
sheet.cell(row=index+1, column=1).value = vals[0]
sheet.cell(row=index+1, column=2).value = vals[1]
sheet.cell(row=index+1, column=3).value = vals[2]
sheet.cell(row=index+1, column=4).value = vals[3]
sheet.cell(row=index+1, column=5).value = vals[4]
# 盈利金額排序
infos = sorted_infos[index]
sheet.cell(row=index+1, column=7).value = infos[0]
sheet.cell(row=index+1, column=8).value = infos[1]
sheet.cell(row=index+1, column=9).value = infos[2]
sheet.cell(row=index+1, column=10).value = infos[3]
sheet.cell(row=index+1, column=11).value = infos[4]
# 按照持有時間排序
days = days_infos[index]
sheet.cell(row=index+1, column=13).value = days[0]
sheet.cell(row=index+1, column=14).value = days[1]
sheet.cell(row=index+1, column=15).value = days[2]
sheet.cell(row=index+1, column=16).value = days[3]
sheet.cell(row=index+1, column=17).value = days[4]
# 總積
sheet.cell(row=len(all_infos) + 1, column=1).value = '總計'
sheet.cell(row=len(all_infos) + 1, column=2).value = round(total,2)
if not os.path.exists('./股票清倉信息.xlsx'):
info.save('./股票清倉信息.xlsx')
else:
os.remove('./股票清倉信息.xlsx')
info.save('./股票清倉信息.xlsx')
print('股票清倉信息.xlsx保存成功')
print('3s 后自動關閉打印窗口!')
time.sleep(3)
print('關閉打印窗口!')
if __name__ == '__main__':
path = './images'
# 獲取 access_token
access_token = get_access_token()
# 獲取images下所有文件
image_names = get_all_image_names(path)
# 獲取所有圖片的信息
if access_token and len(image_names) > 0:
all_info = get_all_image_info(path, image_names, access_token)
# 將信息存儲到excel表格中
save_info_to_excel(all_info)
15. 總結(jié)
識別存在一定的誤差,所以對返回數(shù)據(jù)進行處理時,需要細心篩選你需要的數(shù)據(jù);
access_token 是 30 天有效期,因此建議請求一次,就將最新的進行存儲到本地,下次直接使用本地有效 access_token;
以上就是Python實現(xiàn)批量識別圖片文字并保存到excel中的詳細內(nèi)容,更多關于Python識別圖片文字的資料請關注腳本之家其它相關文章!
相關文章
如何利用python寫GUI及生成.exe可執(zhí)行文件
工作中需要開發(fā)一個小工具,簡單的UI界面可以很好的提高工具的實用性,由此開啟了我的第一次GUI開發(fā)之旅,這篇文章主要給大家介紹了關于如何利用python寫GUI及生成.exe可執(zhí)行文件的相關資料,需要的朋友可以參考下2021-12-12
在Tensorflow中實現(xiàn)梯度下降法更新參數(shù)值
今天小編就為大家分享一篇在Tensorflow中實現(xiàn)梯度下降法更新參數(shù)值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
使用Python將JSON,XML和YAML數(shù)據(jù)寫入Excel文件
JSON、XML和YAML作為主流結(jié)構(gòu)化數(shù)據(jù)格式,因其層次化表達能力和跨平臺兼容性,已成為系統(tǒng)間數(shù)據(jù)交換的通用載體,本文將介紹如何使用Python導入JSON、XML和YAML格式數(shù)據(jù)到Excel文件中,需要的可以參考下2025-04-04
詳解python string類型 bytes類型 bytearray類型
這篇文章主要介紹了python string類型 bytes類型 bytearray類型,需要的朋友可以參考下2017-12-12

