データ入力作業をPythonのOCRとSeleniumを用いて自動化を試みる

プログラミング

はじめに

データ入力作業は時間のかかるタスクだが、PythonのOCR技術を活用することで効率化が可能だと考えた。
そこで、OCRエンジン「Tesseract」とブラウザーの操作を自動化するライブラリである「Selenium」を用いて自動化を試みるプロセスを解説する。

この記事では、ブラウザー上に表示された画面をキャプチャし画像として保存、画像からテキストを抽出し、それを整形して保存するまでの一連の流れを構築する方法を示す。


スポンサーリンク
スポンサーリンク

背景

本プロセスは次のステップで構成されている。
1. Seleniumを用いて指定のURLをブラウザで開き、要素を指定して画面のスクリーンショットを取得。
2. 画像前処理。キャプチャした画像をOCR用に最適化。
3. OCR処理とテキスト保存。Tesseract OCRを利用して画像内のテキストを抽出し、保存。

これにより、データ入力タスクを自動化する為のワークフローを構築する。


使用したライブラリ

ツール バージョン 備考
OpenCV 最新版 画像処理
Tesseract OCR 最新版 OCRエンジン
Selenium 最新版 ブラウザ操作
Edge WebDriver 最新版 Microsoft Edgeブラウザの操作に必要
Pillow (PIL) 最新版 画像保存と加工
WebDriver Manager 最新版 WebDriverの自動管理

コードの詳細

以下のコードでは、OCR処理を自動化するワークフローを定義している。

1. ライブラリと環境の初期設定

ライブラリのインポートとディレクトリ、Tesseractパスの設定を行う。

import cv2
import pytesseract
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service as EdgeService
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import os
from datetime import datetime
import time
from PIL import Image

# データ保存用ディレクトリを作成
output_dir = 'data'
if not os.path.exists(output_dir):
os.makedirs(output_dir)

# Tesseract OCRのパスを設定
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# 処理対象URL
url = 'https://input.example.jp/'

2. ブラウザの初期化

Seleniumを用いてMicrosoft Edgeブラウザを操作する。以下の関数でWebDriverを初期化する。

def init_driver():
service = EdgeService(EdgeChromiumDriverManager().install())
options = webdriver.EdgeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
options.use_chromium = True
driver = webdriver.Edge(service=service, options=options)
driver.set_page_load_timeout(30)
return driver

3. OCR用画像の前処理

OpenCVを使用して画像をグレースケールに変換し、リサイズしてOCRに適した形状にする。

def preprocess_image(image_path):
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
scale_percent = 150 # 画像のサイズを150%に拡大
width = int(gray.shape[1] * scale_percent / 100)
height = int(gray.shape[0] * scale_percent / 100)
dim = (width, height)
resized = cv2.resize(gray, dim, interpolation=cv2.INTER_LINEAR)
return resized

OCR(光学文字認識)エンジンが正確にテキストを認識するためには、画像を適切に前処理することが重要だ。このプロセスでは、OpenCVを活用して以下の手順を実行している。

画像の読み込み

image = cv2.imread(image_path)

指定されたパスから画像を読み込む。この際、OpenCVのimread関数を使用する。デフォルトでは、画像はBGR形式で読み込まれる。

  • 入力:ファイルパス(例:'example.png'
  • 出力:画像データ(配列形式)

グレースケールへの変換

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

画像をグレースケール(モノクロ画像)に変換する。この変換により、色情報が削除され、輝度(明るさ)のみが残る。

  • 理由
  • OCRでは色の情報は不要であり、グレースケールにすることで処理速度を向上できる。
  • 余計な情報を取り除くことで、文字認識精度を高められる。

画像サイズの拡大

scale_percent = 150 # 画像のサイズを150%に拡大
width = int(gray.shape[1] * scale_percent / 100)
height = int(gray.shape[0] * scale_percent / 100)
dim = (width, height)
resized = cv2.resize(gray, dim, interpolation=cv2.INTER_LINEAR)

画像を拡大して解像度を上げる。これにより、小さい文字がより認識されやすくなる。

  1. スケールの設定scale_percentで拡大率を指定(例:150%)。
  2. 新しい画像サイズの計算

– 元の幅(gray.shape[1])と高さ(gray.shape[0])を取得。
– 拡大率を掛け算して新しいサイズを算出。
3. リサイズ処理
cv2.resizeを使用して画像サイズを変更。
補間方法cv2.INTER_LINEARを指定。
– 線形補間は滑らかな拡大を可能にする。

  • 理由
  • OCRは小さい文字を正確に認識できない場合があるため、拡大することで文字の形状を明確にし、認識精度を向上させる。

出力:拡大されたグレースケール画像

関数の戻り値として、前処理された画像データを返す。


4. OCR処理と結果の保存

Tesseract OCRを用いて、画像内のテキストを抽出し、ファイルに保存する。

def execute(driver, url):
driver.get(url)
WebDriverWait(driver, 30).until(
EC.presence_of_element_located((By.XPATH, "//iframe[@id='pdf-viewer-iframe']"))
)
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[@id='pdf-viewer-iframe']"))
time.sleep(5)
element = driver.find_element(By.ID, 'viewer')
element_screenshot = 'element_screenshot.png'
element.screenshot(element_screenshot)

# 画像の前処理
preprocessed_image = preprocess_image(element_screenshot)

# ファイル名の生成
now = datetime.now().strftime('%Y%m%d%H%M')
base_name = f'scrshot_{now}_'
extension = 'png'
preprocessed_image_path = os.path.join(output_dir, f'{base_name}1.{extension}')
image_pil = Image.fromarray(preprocessed_image)
image_pil.save(preprocessed_image_path, dpi=(600, 600))

# OCRの実行
custom_config = r'--oem 3 --psm 6'
text = pytesseract.image_to_string(preprocessed_image_path, lang='jpn', config=custom_config)

text_file_name = os.path.join(output_dir, f'text_{now}_1.txt')
with open(text_file_name, 'w', encoding='utf-8') as f:
f.write(text)

print(f'Text successfully saved to {text_file_name}')
print(f'Screenshot successfully saved to {preprocessed_image_path}')

このステップでは、指定されたWebページ上の要素をキャプチャし、前処理を施した画像をOCRエンジン「Tesseract」を使用してテキストに変換する。
最終的に、抽出されたテキストをファイルに保存するプロセスを実行している。


Webページ要素のスクリーンショット取得

driver.get(url)
WebDriverWait(driver, 30).until(
EC.presence_of_element_located((By.XPATH, "//iframe[@id='pdf-viewer-iframe']"))
)
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[@id='pdf-viewer-iframe']"))
time.sleep(5)
element = driver.find_element(By.ID, 'viewer')
element_screenshot = 'element_screenshot.png'
element.screenshot(element_screenshot)
  1. Webページのロード:

– 指定されたURLをdriver.getで開く。
– ページロードを30秒間待機し、指定された要素がロードされるまでWebDriverWaitで確認する。

  1. iframe内要素への切り替え:

– Webページ内のiframe要素(PDFビューア)を特定し、switch_to.frameで操作対象を切り替える。

  1. 指定要素のスクリーンショット取得:

element.screenshotを使用して、対象の要素(ここではviewer)をキャプチャし、画像ファイルに保存。

重要なポイント:
WebDriverWaitを利用して、要素がロードされるまで待機することでエラーを防止。
iframe内の要素を正確に取得するため、フレームの切り替えが必要。


OCR用画像の前処理

preprocessed_image = preprocess_image(element_screenshot)

先ほど取得したスクリーンショット画像をpreprocess_image関数(前段で説明済み)に渡し、グレースケール化とリサイズを行う。これにより、OCRエンジンに適した画像形式を生成する。


ファイル名の生成と保存

now = datetime.now().strftime('%Y%m%d%H%M')
base_name = f'scrshot_{now}_'
extension = 'png'
preprocessed_image_path = os.path.join(output_dir, f'{base_name}1.{extension}')
image_pil = Image.fromarray(preprocessed_image)
image_pil.save(preprocessed_image_path, dpi=(600, 600))
  1. ファイル名の生成:

– 現在時刻(datetime.now)を基にしたユニークな名前を作成。
– 例:scrshot_202312251230_1.png

  1. 画像の保存:

– OpenCVで処理した画像をPillowImage.fromarrayで変換し、PNG形式で保存。
– 保存時に解像度(DPI)を600に設定し、高品質なOCRを可能にしている。


OCRの実行

custom_config = r'--oem 3 --psm 6'
text = pytesseract.image_to_string(preprocessed_image_path, lang='jpn', config=custom_config)
  1. OCRの設定:

--oem(OCRエンジンモード):
3を指定すると、Tesseractの両方のエンジン(LSTMベースと従来型)を使用する。
--psm(ページ分割モード):
6を指定すると、完全なブロックとしての段落認識を行う。
– 設定を最適化することで、テキスト認識の精度を向上。

  1. テキスト抽出:

– 前処理された画像をOCRエンジンに渡し、日本語(jpn)として認識を実行。
– 抽出結果を文字列として取得。


テキストの保存

text_file_name = os.path.join(output_dir, f'text_{now}_1.txt')
with open(text_file_name, 'w', encoding='utf-8') as f:
f.write(text)
  1. ファイル名の生成:

– OCRで抽出したテキストを保存するファイル名を作成(例:text_202312251230_1.txt)。

  1. ファイルへの書き込み:

openを用いてUTF-8形式でファイルを作成し、抽出テキストを保存。
– これにより、OCR結果を後で利用可能な形で保持。


実行結果の確認

print(f'Text successfully saved to {text_file_name}')
print(f'Screenshot successfully saved to {preprocessed_image_path}')

処理が正常に完了したことをコンソールに出力し、保存先を確認できるようにする。


5. メイン処理

これまでの関数を組み合わせて実行。

if __name__ == "__main__":
driver = init_driver()
execute(driver, url)
driver.quit()

実装上の注意点

  1. ブラウザ環境の設定。ブラウザ操作は環境に依存するため、適切なプロファイル設定が必要。
  2. Tesseract OCRの設定。正確な結果を得るため、最適な設定を調整する。
  3. エラーハンドリング。各ステップで例外処理を実装し、失敗時に適切なメッセージを出力。

まとめ

本記事では、PythonとOCRを用いたデータ入力作業の自動化手法を開拓して効率化を試みた。
この記事が生産性を向上させていく一助となれば幸いだ。

コメント