Superb Garbages 2

千野純一(chinorin)のはてなダイアリーの続きです。

秋月電子通商の購入履歴(1)受注確認メールから抽出

 ・秋月電子通商という全人類が毎日必ず訪れる生活になくてはならない超重要インフラとも言うべきショップのウェブサイトがあるんですけど、先日リニューアルしまして、見た目をなるべく変えない努力をしているように見えて非常に好感が持てるのはいいんですが、2023年2月より前の購入履歴が全て消えてしまいました。聞いてないよ~。

・はい。本当に俺が聞いてなかっただけ。ちゃんとアナウンスもされていたらしい。

・大方の予想通りパーツ管理は杜撰どころか壊滅的なわたしです。当然購入履歴が見られないと困ってしまうんだが、𝕏などを見ると「購入履歴が消えちゃったから、過去に買ったものをもう一度重複して買ってしまうかもしれないなあ。しょうがないなあ」とニヤニヤしている強者も散見され、さすが沼に頭頂部まで浸かってる人は違うな、ああはなりたくねえな、と決意を新たにしましたとさ。めでたしめでたし。

・いや、ごめん、その気分はすげえわかる。電子部品を買い散らかすことは喜びであり、ストックが確かあるはずという安心感に代わるものはこの世にない。そして買ったはずなのにどんなに探しても見つからないパーツは消費せずに済むのが喜ばしく、仕方ないからまた注文するのも快楽であるのだ。ストックとは⋯。

・で、困ってしまうのでとりあえず注文確認メールから抽出することにした。全てGmailに届いているので、まず検索して該当するメールに適当なラベルをつけ*1、次にGoogle TakeoutでGmailの該当するラベルを選択してエクスポート*2。関係ないメールが混じっていても問題にはならないのでラベルづけはけっこう適当でもよい。

・エクスポートされた内容は「ナントカ.mbox」という1つのファイルにまとめられており、これはテキストファイルなので簡単に扱える。というわけで優秀な友達に購入履歴っぽい部分を抽出するPythonコードを書いてもらった。【ヘッダの中の日付にあたる行】と【「【ご注文者】」という文字列を見つけたらその行から「【お支払方法】」のある行まで】を新たなファイルにまとめて書き出すというもの。

・例によって著作権を主張せずパブリックドメインに供することにする。使用の際は自己責任で。

# 秋月電子通商の注文確認メールから注文履歴をまとめるPythonコード
#   (1) .mboxファイル(つまりテキストファイル。input_file)を読んで、
#   (2) start_patternを含む行からend_patternを含む行までを抽出
#   (3) ヘッダから日付を抽出
#   (4) 2と3をテキストファイル(output_file)に書き出す
#   ※入力する.mboxファイルはあらかじめUTF-8にしておくこと。
# written by Chinorin and Merry LLM. No Rights Reserved.
# This program is released into the public domain under the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.

import re

# ファイル名
input_file = 'akizuki.mbox'
output_file = 'history.txt'

# 正規表現パターン
start_pattern = re.compile(r'【ご注文明細】')
end_pattern = re.compile(r'【お支払方法】')
date_pattern = re.compile(r'^Date:.*')

def extract_text(input_file, output_file, start_pattern, end_pattern, date_pattern):
    with open(input_file, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    output_lines = []  # 出力するテキストを格納するリスト
    extracting = False  # テキスト抽出中フラグ
    last_date_line = None  # 最後に見つかった日付行を保持

    for line in lines:
        if date_pattern.search(line):
            # 最後に見つかった日付行を更新
            last_date_line = line
            continue  # 以降の処理をスキップ

        if start_pattern.search(line) and not extracting:
            if last_date_line:
                # 最後に見つかった日付行を追加
                output_lines.append(last_date_line)
                output_lines.append('---\n')  # 日付行の区切りを明確にする
                last_date_line = None  # 日付行をリセット
            extracting = True  # 抽出開始
        
        if extracting:
            output_lines.append(line)  # テキスト抽出中の行を追加
        
        if end_pattern.search(line) and extracting:
            extracting = False  # 抽出終了
            output_lines.append('---\n')  # 抽出セクションの区切りを明確にする

    # ファイルの最後が日付で終わる場合に対応
    if last_date_line and not extracting:
        output_lines.append(last_date_line)
        output_lines.append('---\n')

    with open(output_file, 'w', encoding='utf-8') as file:
        file.writelines(output_lines)

# 関数を呼び出し
extract_text(input_file, output_file, start_pattern, end_pattern, date_pattern)

Googleから出てきた.mboxファイルはエンコードがJISなので、あらかじめUTF-8に変換しておくこと。秀丸なら ファイル→エンコードの種類→Unicode(UTF-8)→内容を維持したまま適用 でおk。シフトJISでも encoding='utf-8' のところを 'shift_jis' にするだけだが、JISのままでは 'iso-2022-jp' とかにしてもなぜか読めなかった。

・なお、入力ファイルに余計なメールが含まれている場合、普通にやると日付だけが抽出されてしまうので、日付が2回以上連続でマッチしたらそのうちの最後の1回のみを書き出すようになっている。

・入力ファイル名(akizuki.mbox)、出力ファイル名(history.txt)、開始パターン(【ご注文者】)、終了パターン(【お支払方法】)、日付パターン(Date:.*)それから区切り(---\n)なんかを改変すると他の用途にも使えるかもしれない。パターンについては全て正規表現として扱われるので、半角記号とかはエスケープする必要があるかも。

・以上、注文履歴をそのまんま書き出すでござるの巻。このままでもまあまあ便利だと思うけど、次はいったんCSVにしてからもう少し加工していきたい。つづく。

・あ、これ、次のをすぐに書かなきゃいけないやつ。

*1:左のチェックボックスにチェックを入れ、上部の「ラベル」アイコン→新規作成で新しいラベルを作る。

*2:まず「選択をすべて解除」し、Ctrl+F等からGmail(メール)を検索、右のチェックボックスにチェックを入れ、「メールのすべてのデータが含まれます」をクリック→「メールのすべてのメッセージを含める」を解除→「すべて選択」の位置を2回クリックするなどしてすべて解除→該当するラベルにチェックを入れる→OK→一番下の「次のステップ」→エクスポート先などを設定→「エクスポートを作成」をクリック。そんでしばらく待つ。