ウェブノウハウ

WEB KNOWHOW

Gmail APIでGmailの受信メールを一括取得&CSV化【Python】

6. 受信メールを全件取得し、表形式のきれいな配列に直す

前回(ラベルを指定して受信メールの本文を一括取得する(ただし500件まで))では、Gmail APIで一度に取得できる最大件数の500件までメールを取得して終わりました。
 
このページでは、500件以上のメールリストを全件取得して、かつ表形式のきれいな配列に直す方法をご紹介します。

※ 前項までのコードは記述した状態で、その下に書いていく処理だけをここでは紹介しますので、前項までのコードを用意してください。


Gmail APIの返り値の中には、メールの内容だけでなく、取得したメールリストの次のメールリスト(要は501件目以降のメールリスト)のトークンなるものも含まれていて、このトークンを使って、最初のメールリストを取得したら次のメールリスト、そのまた次のメールリスト、といった具合に延々とループ処理で回せば、全件を取得することができます。
 
加えて今回は例として、以下のような定型のメール本文から各項目の内容を取り出して、きれいな配列に直して出力する処理も同時に実装してみることにします。
サイトのフォームから問い合わせが入ったときの定型の通知メールなどを想定して。

==定型のメール本文==
お名前  : XXX
会社名 : XXX
メールアドレス : XXX

このたびはお問い合わせありがとうございました。
============
 
それではまずメールを全件取得する関数から。

def gmail_get_messages_body(service, labelIdsValue):
    message_list = []

    # メッセージの一覧を取得
    messages = service.users().messages()
    msg_list = messages.list(userId='me', labelIds=labelIdsValue).execute()
    message_list = gmail_get_messages_body_content(messages, msg_list, message_list)
    
    while 'nextPageToken' in msg_list:
        page_token = msg_list['nextPageToken']
        msg_list = messages.list(userId='me', labelIds=labelIdsValue, pageToken=page_token).execute()
        message_list = gmail_get_messages_body_content(messages, msg_list, message_list)
    
    return message_list

最初の処理では件数指定せず(件数指定しない場合のデフォルト件数は100件)、メールリストと次のメールリストのトークン’nextPageToken’を取得し、次からはwhile文で’nextPageToken’を指定してメールリストを取得して、最終的に全件取得するような関数です。
 
次に、上記のgmail_get_messages_bodyから呼ばれる、メールの本文を項目別に分けてきれいな配列に直す関数。

def gmail_get_messages_body_content(messages, msg_list, message_list):
    
    # 各message内容確認
    for message_id in msg_list["messages"]:
        message = {}
        
        # 各メッセージ詳細
        msg = messages.get(userId='me', id=message_id['id']).execute()
                    
        # 本文
        if(msg["payload"]["body"]["size"]!=0):
            decoded_bytes = base64.urlsafe_b64decode(
                msg["payload"]["body"]["data"])
            decoded_message = decoded_bytes.decode("UTF-8")
        else:
            #メールによっては"parts"属性の中に本文がある場合もある
            decoded_bytes = base64.urlsafe_b64decode(
                msg["payload"]["parts"][0]["body"]["data"])
            decoded_message = decoded_bytes.decode("UTF-8")

        #メールアドレス
        mail = find_mailaddress(decoded_message)
        message['mail'] = mail
        
        #会社名
        company = find_company(decoded_message)
        message['company'] = company
        
        #名前
        pname = find_name(decoded_message)
        message['pname'] = pname
        
        # 日付
        date = gmail_get_messages_body_date(messages,message_id)
        message['date'] = date

        message_list.append(message)
            
    return message_list

 
gmail_get_messages_body_content関数内で受信日時を取得する関数

def gmail_get_messages_body_date(messages,msg):
    msg_id = msg['id']
    m = messages.get(userId='me', id=msg_id, format='raw').execute()
    raw = base64.urlsafe_b64decode(m['raw'])
   
    # Emailを解析する
    eml = email.message_from_bytes(raw)
   
    date = dateutil.parser.parse(eml.get('Date')).strftime("%Y-%m-%d")
    return date

 
同様に、メールアドレスを取得する関数

def find_mailaddress(body):
    target = 'メールアドレス : '
    target_end = '\r\n\r\nこのたびはお問い合わせ'
    idx = body.find(target)
    idx_end = body.find(target_end)
    r = body[idx+10:idx_end]
    return r

 
同様に、会社名を取得する関数

def find_company(body):
    target = '会社名 : '
    target_end = '\r\nメールアドレス'
    idx = body.find(target)
    idx_end = body.find(target_end)
    r = body[idx+6:idx_end]
    return r

 
同様に、お名前を取得する関数

def find_name(body):
    target = 'お名前  : '
    target_end = '\r\n会社名'
    idx = body.find(target)
    idx_end = body.find(target_end)
    r = body[idx+7:idx_end]
    return r

 
これで関数はできあがりです。
さっそく実行します。

message_list = gmail_get_messages_body(service, 'XXXXXX') # XXXXXX にはラベルのIDを入れる

中身を見てみましょう。

message_list

きれいに整形された配列がずらっと出てくるはずです。
あとはこれをCSVなどに落とせば、他のツールやシステムにもインポートできるメール一覧のできあがりです。

【100ウェブ新着情報メルマガ】

WordPressカスタマイズ事例やウェブ制作ノウハウの新着情報、お役立ち情報を
リアルタイムにメルマガ配信!