レシートをCSVファイルに出力する
レシート画像を
test.jpg
にリネーム
1 2 3 4 5 6 7 8 9 10 11 12 | from google.cloud import vision client = vision.ImageAnnotatorClient() with open ( "test.jpg" , "rb" ) as fb: content = fb. read () image = vision.Image(content=content) response = client.document_text_detection(image=image) texts = response.text_annotations print(texts[0].description) |
を
1 | python vision_api_test.py |
として実行
結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | それで食楽部 登録番号 15080401017738 とれたて食楽部 2024年8月10日 (土) 08:59 #000011 000801精算機 1 000801精算機1 3901 お会計券 #000003 R9309 09:08 000008 西澤 内8 きゅうり/鈴木仁 ¥150 P2023300101503 内8 きゅうり/小林宗作 ¥130 P2055600101303 内8 リーフレタス/(有)成神工 ¥216 P2086402402169 小計 ¥496 (内税8%対象額 ¥496) 買上点数 3点 合計 ¥496 (税率8%対象額 ¥496) (内消費税等 8% ¥36) 課税事業者 (税率 8%対象額 ¥216) (内消費税等 8% ¥16) 免税事業者 (税率 8%対象額 ¥280) クレジット ¥496 (内消費税等 ¥36) 8、内容は軽減税率対象商品です。 約專業者商品 |
となる
これをCSVに出力できるようにする
この時に
日付、購入した店名、商品名、数量、商品ごとの金額を抽出し
他の情報を削除する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import re import csv from datetime import datetime # 入力されたテキスト text = "" " それで食楽部 登録番号 15080401017738 とれたて食楽部 2024年8月10日 (土) 08:59 #000011 000801精算機 1 000801精算機1 3901 お会計券 #000003 R9309 09:08 000008 西澤 内8 きゅうり/鈴木仁 ¥150 P2023300101503 内8 きゅうり/小林宗作 ¥130 P2055600101303 内8 リーフレタス/(有)成神工 ¥216 P2086402402169 小計 ¥496 (内税8%対象額 ¥496) 買上点数 3点 合計 ¥496 (税率8%対象額 ¥496) (内消費税等 8% ¥36) 課税事業者 (税率 8%対象額 ¥216) (内消費税等 8% ¥16) 免税事業者 (税率 8%対象額 ¥280) クレジット ¥496 (内消費税等 ¥36) 8、内容は軽減税率対象商品です。 約專業者商品 "" " # 情報を抽出 date_match = re.search(r '\d{4}年\d{1,2}月\d{1,2}日' , text) date = datetime.strptime(date_match.group(), '%Y年%m月%d日' ).strftime( '%Y-%m-%d' ) shop_name_match = re.search(r 'とれたて食楽部' , text) shop_name = shop_name_match.group() # 商品情報を正規表現で抽出 items = re.findall(r '内\d+ (.+?) ¥(\d+)' , text) # CSV形式で出力 output = [] for item in items: product_name, price = item row = f "{date},{shop_name},{product_name},1,{price}" output.append(row) # CSVファイルに出力 csv_filename = 'receipt_data.csv' with open (csv_filename, mode= 'w' , newline= '' , encoding= 'utf-8' ) as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow([ "日付" , "店名" , "商品名" , "数量" , "金額" ]) for row in output: csv_writer.writerow(row. split ( ',' )) print(f "CSVファイル '{csv_filename}' に出力しました。" ) |
以下解説
1. 日付の抽出: 正規表現を使用して、日付情報を抽出しています。その後、datetimeを使ってフォーマットをYYYY-MM-DDに変換しています。
2. 店名の抽出: テキスト内の特定の店名を正規表現で探して抽出しています。
3. 商品の抽出: 商品名と価格を正規表現で抽出しています。数量はレシートに明示されていないため、ここでは全て1と仮定しています。
4. CSV形式の出力: csvモジュールを使用して、指定された形式でCSVファイルに出力しています。CSVファイルには、ヘッダー行が含まれています。
このスクリプトを実行すると、指定された形式のCSVファイルが生成されます。生成されたCSVファイルは、receipt_data.csvとして保存されます。このファイルには、各商品の情報がカンマ区切りで含まれています。
しかしこれだと
商品名の後に /生産者もしくは出品者が残ってしまう
実行結果のファイルは
1 2 3 4 | 日付,店名,商品名,数量,金額 2024-08-10,とれたて食楽部,きゅうり/鈴木仁,1,150 2024-08-10,とれたて食楽部,きゅうり/小林宗作,1,130 2024-08-10,とれたて食楽部,リーフレタス/(有)成神工,1,216 |
となっている
このため
商品名の / 以降を削除
またファイルの上書きを防ぐためタイムスタンプをファイル名に追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import re import csv from datetime import datetime # ファイルからテキストを読み込む with open ( 'ocr.txt' , 'r' , encoding= 'utf-8' ) as file : text = file . read () # 情報を抽出 date_match = re.search(r '\d{4}年\d{1,2}月\d{1,2}日' , text) date = datetime.strptime(date_match.group(), '%Y年%m月%d日' ).strftime( '%Y-%m-%d' ) shop_name_match = re.search(r 'とれたて食楽部' , text) shop_name = shop_name_match.group() # 商品情報を正規表現で抽出 items = re.findall(r '内\d+ (.+?) ¥(\d+)' , text) # 現在のタイムスタンプを生成 timestamp = datetime.now().strftime( '%Y%m%d%H%M%S' ) # 出力ファイル名にタイムスタンプを付ける csv_filename = f 'receipt_data_{timestamp}.csv' # CSVファイルに出力 with open (csv_filename, mode= 'w' , newline= '' , encoding= 'utf-8' ) as csvfile: csv_writer = csv.writer(csvfile) # ヘッダー行を書き込み csv_writer.writerow([ "日付" , "店名" , "商品名" , "数量" , "金額" ]) for item in items: product_name, price = item # 商品名の「/」以降を削除 product_name_clean = product_name. split ( '/' )[0] # 出力: 日付, 店名, 商品名, 数量, 金額 row = f "{date},{shop_name},{product_name_clean},1,{price}" csv_writer.writerow(row. split ( ',' )) print(f "CSVファイル '{csv_filename}' に出力しました。" ) |
とコード変更
これで
1 | python ocr_to_csv.py |
とすれば
1 | receipt_data_20240814054441.csv |
が作成され
1 2 3 4 | 日付,店名,商品名,数量,金額 2024-08-10,とれたて食楽部,きゅうり,1,150 2024-08-10,とれたて食楽部,きゅうり,1,130 2024-08-10,とれたて食楽部,リーフレタス,1,216 |
というように商品名のみになる