質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

1589閲覧

PythonでGmailを取得し、件名や受信日をPandasを用いてExcelに書き込む方法

catwalk

総合スコア13

Gmail

GmailとはGoogleによって提供されているウェブメールのサービスのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

1グッド

0クリップ

投稿2022/10/12 11:23

###前提

Pythonの勉強を独学でやっているものです。
勉強を始めて日が浅いので、訳の分からないことを言っているかもしれませんが、温かい目で見てください・・・

実現したいこと

google APIにてGmailの情報をPandasを使って、Excelに書き込みしたいです

具体的には
・メールの送信者
・受信日
・件名
・本文

上記の要素を受信ボックスのすべてのメール分取得したいと思っています。
Gmailの取得と要素の取得についてはできているのですが、どうやってPndasでデータを格納するのかをご教授いただければと思います。

抽象的な質問で申し訳ありませんが
また可能であれば、皆様がPandsについての理解を深めた際に用いたサイトなどがあれば教えていただきたいです。

下記に現在書いているコードを載せておきます。
(ほぼサイトのコピペですが・・・)

Python

1 2from google.oauth2.credentials import Credentials 3from googleapiclient.discovery import build 4import json 5import base64 6import pandas as pd 7 8 9def get_header(headers, name): 10 for h in headers: 11 if h['name'].lower() == name: 12 return h['value'] 13 14 15def base64_decode(data): 16 return base64.urlsafe_b64decode(data).decode() 17 18 19def base64_decode_file(data): 20 return base64.urlsafe_b64decode(data.encode('UTF-8')) 21 22 23def get_body(body): 24 if body['size'] > 0: 25 return base64_decode(body['data']) 26 27 28def get_parts_body(body): 29 if (body['size'] > 0 30 and 'data' in body.keys() 31 and 'mimeType' in body.keys() 32 and body['mimeType'] == 'text/plain'): 33 return base64_decode(body['data']) 34 35 36def get_parts(parts): 37 for part in parts: 38 if part['mimeType'] == 'text/plain': 39 b = base64_decode(part['body']['data']) 40 if b is not None: 41 return b 42 if 'body' in part.keys(): 43 b = get_parts_body(part['body']) 44 if b is not None: 45 return b 46 if 'parts' in part.keys(): 47 b = get_parts(part['parts']) 48 if b is not None: 49 return b 50 51 52def get_attachment_id(parts): 53 for part in parts: 54 if part['mimeType'] == 'image/png': 55 return part['body']['attachmentId'], 'png' 56 return None, None 57 58def excel_output(output): 59 df = pd.DataFrame(output) 60 writer = pd.ExcelWriter('sample.xlsx',options={'strings_to_urls': False}) 61 df.to_excel(writer, sheet_name="Sheet1")#Writerを通して書き込み 62 writer.close() 63 df 64 65def main(): 66 scopes = ['https://mail.google.com/'] 67 creds = Credentials.from_authorized_user_file('token.json', scopes) 68 service = build('gmail', 'v1', credentials=creds) 69 output = [] 70 71 messages = service.users().messages().list( 72 userId='me', 73 ).execute().get('messages') 74 75 for message in messages: 76 print('=' * 10) 77 m_data = service.users().messages().get( 78 userId='me', 79 id=message['id'] 80 ).execute() 81 82 # ヘッダー情報 83 headers = m_data['payload']['headers'] 84 85 # 日付 86 message_date = get_header(headers, 'date') 87 print(f'日付: {message_date}') 88 89 # 差出人 90 from_date = get_header(headers, 'from') 91 print(f'差出人: {from_date}') 92 93 # 宛先 94 to_date = get_header(headers, 'to') 95 print(f'宛先: {to_date}') 96 97 # 件名 98 sub_date = get_header(headers, 'subject') 99 print(f'件名: {sub_date}') 100 101 body = m_data['payload']['body'] 102 body_data = get_body(body) 103 104 parts_data = None 105 if 'parts' in m_data['payload'].keys(): 106 parts = m_data['payload']['parts'] 107 parts_data = get_parts(parts) 108 # 添付ファイル 109 attachment_id, extension = get_attachment_id(parts) 110 if attachment_id is not None: 111 res = service.users().messages().attachments().get( 112 userId='me', 113 messageId=message['id'], 114 id=attachment_id 115 ).execute() 116 f_data = base64_decode_file(res['data']) 117 118 with open(f'download.{extension}', 'wb') as f: 119 f.write(f_data) 120 121 body_result = body_data if body_data is not None else parts_data 122 print(f'本文: {body_result}') 123 124 output = [from_date,sub_date,parts_data,message_date] #「Output」の配列に格納 125 print(output) 126 127if __name__ == '__main__': 128 main()
takezoux2❤️を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

メールの要素を格納するために、2箇所の修正が必要です。

1 outputへの格納
output = [from_date,sub_date,parts_data,message_date] #「Output」の配列に格納
の行の修正が必要です。
このままだと、単なる代入なので、outputの中身がメールごとに入れ替わってしまいます。
リストのappendを使って、
output.append([from_date,sub_date,parts_data,message_date])
とすることで、outputリストに順に格納していくことができます。

2 エクセルへの書き込み
全メールをoutputに格納したタイミングで、作成済みのexcel_output関数を呼び出す必要があります。
forでの繰り返しの終了後、main関数の最後で、
excel_output(output)
という1行を追加してください。

他の修正箇所について
Gmailのトークンなどが必要であり、ソースコードを実行して挙動を細かく確認できなかったので、
目につく上記2つの修正点以外にも修正すべき箇所があるかもしれません。
その時はまたご質問ください。

pandasの学習サイトについて
基礎的な部分はYoutubeでpandas入門動画を調べて見るのが、分かりやすいだろうと思います。
各機能の具体的な使い方を調べる場合には、note.nkmk.meさんが頼りになります。
pandasだけでなくpython全般でも、上記2つが参考になります。

投稿2022/10/12 12:19

T_F

総合スコア74

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

catwalk

2022/10/12 13:39

ありがとうございました! 無事に格納とExcelに書き込みができました! トークンについては取得していたので問題なかったです。 学習サイトについても今後参考にさせていただきます。
T_F

2022/10/12 14:06

無事動いたようで良かったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問