ウェブ上のリソースから学習と実験を行って、いくつかのコードを作成することができました。
Outlook メールボックスに会議への招待が毎回表示されるという状況で行き詰まっています。コードの実行に失敗します。
Python で例外を処理する方法に関するガイダンスを探しています。
import csv
import win32com.client
from datetime import datetime
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Create empty list to store results
data_set = list()
date_id = (datetime.today()).strftime('%Y%m%d') # Used to create the filename
#Iterating through email items in outlook folder
for message in messages:
if messages is not None:
if len(inbox.Items) > 0:
row = list()
row.append(message.Subject)
row.append(message.Categories)
row.append(message.Sender)
#row.append(message.Sender.Address)
row.append(message.To)
row.append(message.SentOn)
row.append(message.CC)
row.append(message.BCC)
# Stores the data in a list
data_set.append(row)
# Print out the result to a csv with headers
with open(date_id + "_"+ 'outlook_Data.csv', 'w', newline='', encoding='utf-8') as csv_file:
headers = ['Subject', 'Category', 'From', 'To', 'Sent On', 'CC', 'BCC']
wr = csv.writer(csv_file, delimiter=',')
wr.writerow(headers)
for line in data_set:
wr.writerow(line)
「実行に失敗しました」とはどういう意味ですか?例外が発生しますか?
– スネークチャームブ2020 年 9 月 3 日 10:45
行 (message.Sender) を指す属性エラーがスローされます。 raise AttributeError("%s.%s" % (self._username_, attr)) AttributeError: <unknown>.Sender
– SaaSy モンスター2020 年 9 月 3 日 10:47
さらなる調査によると、電子メールは別のクラスとみなされ、会議には別のクラスが招待されます。会議への招待がない限りメールボックスではプログラムはスムーズに実行されます。
– SaaSy モンスター2020 年 9 月 3 日 10:49
isinstance(message, TheMeetingInviteClass): continue の場合は?
– スネークチャームブ2020 年 9 月 3 日 10:50
はい、メッセージ内の for メッセージの先頭に if isinstance(message, TheMeetingInviteClass): continue を適用しようとしましたが、機能しません。応募してるのかなコード行が間違っていますか?
– SaaSy モンスター2020 年 9 月 3 日 10:52
この問題はフィルタリングの問題に帰着します。さまざまなタイプのオブジェクトのリストがあり、その一部は処理してはなりません。
この回答では、受信トレイ内の電子メール オブジェクトのタイプをメッセージとし、会議出席依頼のタイプを MeetingInvitation とします。
これら 4 つのアプローチはいずれも適用できます。
試す/除外する/続行する
for message in messages:
row = list()
try:
row.append(message.Subject)
row.append(message.Categories)
row.append(message.Sender)
...
# Stores the data in a list
data_set.append(row)
except AttributeError as ex:
print('Error', ex, 'skipping message', message)
continue
ループの先頭でオブジェクトのタイプを確認します
for message in messages:
if isinstance(message, MeetingInvitation):
continue
row = list()
フィルタ組み込み関数を使用する
filtered_messages = filter(lambda msg: not isinstance(msg, MeetingInvitation), messages)
for message in filtered_messages:
row = list()
...
リスト内包表記を使用します (リスト内包表記が多数ある場合)皆さん、ジェネレーターの理解の方が効率的です - [] を ()) に置き換えてください。
filtered_messages = [msg for msg in msgs if not isinstance(msg, MeetingInvitation)]
for message in filtered_messages:
row = list()
...
isinstance チェックを逆にして、メッセージではないものを除外することもできます。
if not isinstance(message, Message):
continue
または、他の問題のあるタイプを除外するために拡張されます
if isinstance(message, (MeetingInvitation, SomethingElse)):
continue
4 つのアプローチはすべて機能的に同等です。私の意見では、フィルタとリストの理解によるアプローチは、実際のメッセージ処理からフィルタリング プロセスを分離するため、よりクリーンです。
1
try/excel/ continue メソッドを試してみましたが、うまくいきました。無法に。完璧な解決策です。私はまだ Python を学習中なので、「AttributeError」が発生しました。作品を扱うのは私にとって非常に新しいことです。他の 2 つの方法は機能しませんでした。私は「isinstance」についていくつかの研究を行っています。このメソッドは今のところ正しく適用されていないと思います。
– SaaSy モンスター2020 年 9 月 4 日 8:33
Outlook カレンダー項目をスキップしたい場合のもう 1 つの解決策は、item.MessageClass を使用することです。以下は、サンプル コードと詳細の参照リンクです。
https://learn.microsoft.com/en-us/office/vba/outlook/Concepts/Forms/item-types-and-message-classes
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
messages.Sort("[ReceivedTime]", True)
for i, msg in enumerate(messages):
print(msg.MessageClass) # use this in condition
if msg.MessageClass=='IPM.Note':
print('Its a Meeting')
# Identify outlook exchange user
if msg.SenderEmailType == "EX":
print(msg.Sender.GetExchangeUser().PrimarySmtpAddress)
msg_sender = msg.Sender.GetExchangeUser().PrimarySmtpAddress
else:
print(msg.SenderEmailAddress)
msg_sender = msg.SenderEmailAddress
elif msg.MessageClass =='IPM.Schedule.Meeting.Request':
print('Its a Meeting')
# Check only first 20 items change the number as required
if i > 20:
break
Some Outputs from above code
IPM.Note
IPM.Note
IPM.Schedule.Meeting.Request
Its a Meeting
IPM.Note
IPM.Schedule.Meeting.Request
Its a Meeting
この課題を解決してくれた @snakecharmerb に感謝します。他の人が同様のコードに取り組む必要があるかもしれないので、完全に機能するコードを以下に示します。
import csv
import win32com.client
from datetime import datetime
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
# Create empty list to store results
data_set = list()
date_id = (datetime.today()).strftime('%Y%m%d') # Used to create the filename
#Iterating through email items in outlook folder
for message in messages:
row = list()
try:
row.append(message.Subject)
row.append(message.Categories)
row.append(message.Sender)
row.append(message.Sender.Address)
row.append(message.To)
row.append(message.SentOn)
row.append(message.CC)
row.append(message.BCC)
# Stores the data in a list
data_set.append(row)
except AttributeError as ex:
print('Error', ex, 'skipping message', message)
continue
# Print out the result to a csv with headers
with open(date_id + "_"+ 'outlook_Data.csv', 'w', newline='', encoding='utf-8') as csv_file:
headers = ['Subject', 'Category', 'From', 'To', 'Sent On', 'CC', 'BCC']
wr = csv.writer(csv_file, delimiter=',')
wr.writerow(headers)
for line in data_set:
wr.writerow(line)