min117の日記

初期desireもち。趣味Mac,メインFedora,仕事xp。

Python3でGmailを指定ワードで検索して、見つかったメールの添付ファイルを一気にフォルダに保存する

Gmail検索+添付ファイル全保存スクリプト

超便利。ChatGPTで1時間でできた。すごすぎる。

$ python3 myGmailReadBODYArgTENPU.py

$ vim myGmailReadBODYArgTENPU.py

import datetime
from dateutil import parser
import pytz

import sys
import os
import imaplib
import email
from email.header import decode_header

# コマンドライン引数で検索ワードを取得
if len(sys.argv) < 2:

    print('---------------------------')
    print("引数不足")
    print("検索ワードを指定してください")
    print('---------------------------')
    #print(f"python {sys.argv[0]} 検索ワード")
    print("python3 myGmailRead.py '検索ワード' [-v '除外ワード']")
    print('---------------------------')
    sys.exit(1)


search_string = sys.argv[1]
exclude_string = None
print('---------------------------')
print('検索ワードは\n' + search_string)
print('---------------------------')

# print('-v オプションをチェック')
print('除外ワード -v **  がないかチェック')
if '-v' in sys.argv:
    exclude_index = sys.argv.index('-v') + 1
    if exclude_index < len(sys.argv):
        exclude_string = sys.argv[exclude_index]
        print('---------------------------')
        print('除外するワードは\n' + exclude_string)
        print('---------------------------')

# 添付ファイルを保存するディレクト
# attachment_dir = "attachments"
# attachment_dir = "/Users/bash/Downloads/"
# attachment_dir = "/media/WD30EZRX/PT3/"
# print('最後のスラッシュは必要ありません。ディレクトリパスの最後にスラッシュがなくても、os.path.join でファイル名を追加する際に適切に結合されます')
#attachment_dir = "/media/WD30EZRX/PT3"
#attachment_dir = "/media/WD30EZRX/PT3/myGmailReadBODYArgTENPUed"
attachment_dir = "/media/WD30EZRX/PT3/TENPUed"
os.makedirs(attachment_dir, exist_ok=True)

# 添付ファイル名を保存するリスト
saved_attachments = []

# GmailIMAPサーバーに接続
imap_host = "imap.gmail.com"
username = "xxxxxxx@gmail.com"  # あなたのGmailアドレス
password = "xxxxxxxxxxxxxxxxx"     # アプリパスワード

# IMAPサーバーにログイン
mail = imaplib.IMAP4_SSL(imap_host)
mail.login(username, password)

# メールボックスを選択(受信トレイ)
mail.select("inbox")

# 件名に特定の文字列を含むメールを検索(UTF-8対応)
# search_string = "能代"  # 検索したい件名のキーワード
mail.literal = search_string.encode('utf-8')  # 検索キーワードをUTF-8エンコード
#status, messages = mail.search('UTF-8', 'SUBJECT')
status, messages = mail.search('UTF-8', 'BODY')

# メールが見つかった場合、そのメールを取得
if status == "OK":
    for num in messages[0].split():
        status, data = mail.fetch(num, "(RFC822)")
        for response_part in data:
            if isinstance(response_part, tuple):
                msg = email.message_from_bytes(response_part[1])
                # 件名をデコードして表示
                subject, encoding = decode_header(msg["Subject"])[0]
                if isinstance(subject, bytes):
                    subject = subject.decode(encoding if encoding else "utf-8")

                # print('=============================')
                # print(f"件名: {subject}")

                # 差出人を表示
                from_ = msg.get("From")
                # print(f"From: {from_}")

                # メールの本文を表示(エンコーディングに応じてデコード)
                if msg.is_multipart():
                    for part in msg.walk():
                        # テキスト部分を探す
                        if part.get_content_type() == "text/plain":
                            # 送信日時を取得
                            date = msg.get('Date')
                            if date:
                            # datetimeをパースし、タイムゾーンを考慮する
                                try:
                                    dt = email.utils.parsedate_to_datetime(date)
                                    # UTCから日本時間に変換
                                    dt = dt.astimezone(pytz.timezone('Asia/Tokyo'))

                                    # formatted_date = dt.strftime('%Y 年 %m 月 %d 日 %H:%M:%S')
                                    formatted_date = dt.strftime('%a, %Y年%m月%d日 %H:%M:%S')
                                    print(f"送信日時: {formatted_date}")
                                except Exception as e:
                                    print(f"日時の処理中にエラーが発生しました: {e}")

                            # エンコードを確認してデコード
                            charset = part.get_content_charset()
                            if charset is None:
                                charset = 'utf-8'  # デフォルトでUTF-8
                            #OKK body = part.get_payload(decode=True).decode(charset)
                            try:
                                body = part.get_payload(decode=True).decode(charset)
                            except (UnicodeDecodeError, TypeError):
                                # 文字化け対策、ここで他のエンコーディングを試す
                                for alternative_charset in ['iso-2022-jp', 'shift_jis']:
                                    try:
                                        # body = part.get_payload(decode=True).decode(alternative_charset)
                                        body = part.get_payload(decode=True).decode(alternative_charset, errors='replace')
                                        break  # 成功したらループを抜ける
                                    except UnicodeDecodeError:
                                        continue
                                else:
                                    # すべてのデコードに失敗した場合、UTF-8で再デコード
                                    # body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
                                    # すべてのデコードに失敗した場合
                                    body = part.get_payload(decode=True).decode('utf-8', errors='replace')

                            #UTF-8_NG try:
                            #UTF-8_NG     body = part.get_payload(decode=True).decode(charset)
                            #UTF-8_NG except (UnicodeDecodeError, TypeError):
                            #UTF-8_NG     # エラーが発生した場合、UTF-8で再デコードを試みる
                            #UTF-8_NG     try:
                            #UTF-8_NG         body = part.get_payload(decode=True).decode('utf-8', errors='ignore')
                            #UTF-8_NG     except Exception as e:
                            #UTF-8_NG         print(f"デコードエラー: {e}")


                        # 添付ファイルの処理
                        if part.get("Content-Disposition"):
                            filename = part.get_filename()
                            if filename:
                                #添付ファイルを保存
                                #OKK filepath = os.path.join(attachment_dir, filename)
                                #OKK with open(filepath, "wb") as f:
                                #OKK     f.write(part.get_payload(decode=True))
                                #OKK saved_attachments.append(filename) 
                                #OKK print(f"添付ファイルを保存: {filepath}")

                                filepath = os.path.join(attachment_dir, filename)
                                try:
                                    with open(filepath, "wb") as f:
                                        f.write(part.get_payload(decode=True))
                                    print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
                                    print(f"ファイル名: {filename}")  # 保存したファイル名を表示
                                    print(f"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
                                except Exception as e:
                                    print(f"エラー: 添付ファイルの保存に失敗しました: {e}")
                else:
                    charset = msg.get_content_charset()
                    if charset is None:
                        charset = 'utf-8'  # デフォルトでUTF-8
                    body = msg.get_payload(decode=True).decode(charset)

                # 除外ワードがあれば、メールを表示するかどうか判断
                if exclude_string:
                    if exclude_string not in body:
                        print('-----------------------------')
                        #print(f"送信日時: {date}")
                        print(f"送信日時: {formatted_date}")
                        print(f"Subject: {subject}")
                        print(f"From: {from_}")
                        print(f"Body: {body}")
                else:
                    print('=============================')
                    #print(f"送信日時: {date}")
                    print(f"送信日時: {formatted_date}")
                    print(f"Subject: {subject}")
                    print(f"From: {from_}")
                    print(f"Body: {body}")

# 添付ファイルの表示
if saved_attachments:
    print("TENPUU----------")
    for attachment in saved_attachments:
        print(attachment)

# 保存先フォルダの内容を表示
print('------------------------------')
print("保存先フォルダの内容:")
for item in os.listdir(attachment_dir):
        print(item)

# ログアウト
mail.logout()



 

 

1,000万円を超えたbitcoinを少しだけどもらえるURL

https://bitflyer.com/invitation?id=l50e5ljw&lang=ja-JP

ハピタスからポイントもらえるURL

その買うを、もっとハッピーに。|ハピタス