#python #python-3.x #concurrency #gmail #imaplib
#python #python-3.x #параллелизм #gmail #imaplib
Вопрос:
Я хочу получить несколько почтовых сообщений по их идентификаторам из Gmail, и для этого я использую Imap. Это отлично работало, пока я не попытался ускорить процесс с помощью ThreadPull executor (даже для двух исполнителей).
если кто-нибудь может подумать о том, в чем причина этой проблемы, это будет очень полезно.
connector.py
def create_data_models(self, msgs_ids, max_workers=2):
data_models = []
#msgs_id_list = [message['id'] for message in messages]
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(self.imapService.fetch_message, msg_id) : msg_id for msg_id in msgs_ids}
for future in concurrent.futures.as_completed(futures):
try:
data = future.result()
data_model = self._create_msg_obj1(data)
data_models.append(data_model)
except Exception as exc:
print('generated an exception: %s' % (exc))
return data_models
imap_service.py
def fetch_message(self, msg_id):
_, data = self.mail.uid('fetch', msg_id, '(RFC822)')
_, mail_data = data[0]
logger.error('Succesfully fetch message from {} with {} id'.format(self.email_address, msg_id))
print('Succesfully fetch message from {} with {} id'.format(self.email_address, msg_id))
return mail_data
Ошибки:
generated an exception: command: UID => unexpected response: b'v5oJ8jIW2KPDzS/DHMN 58yL3Q'
generated an exception: command: UID => unexpected response: b'X-Google-Smtp-Source: APXvYqwtp0c9H1jJ8uZTRW5ZBjIyNbqRgeoGUq8heUUf00uNRHW9Nvyl1dTjYZAy6ijzL29 PTL7'
generated an exception: command: UID => unexpected response: b'X-Received: by 2002:a50:9223:: with SMTP id i32mr19845429eda.40.1566127216934;'
generated an exception: command: UID => unexpected response: b' Sun, 18 Aug 2019 04:20:16 -0700 (PDT)'
generated an exception: command: UID => unexpected response: b'le.com; s=arc-20160816;'
generated an exception: command: UID => unexpected response: b' h=message-id:to:sender:from:reply-to:subject:date:mime-version'
Комментарии:
1. Вы не можете совместно использовать соединение между несколькими потоками: они не потокобезопасны. Вам потребуется несколько подключений. Однако, чтобы уменьшить задержку, вы должны извлекать несколько сообщений для каждой команды, отправляя идентификаторы сообщений, разделенных запятыми. Это значительно ускорит работу, поскольку большинство сообщений ограничено задержкой, а не пропускной способностью.
2. Спасибо, это действительно помогло мне. Теперь моя проблема в том, что я не могу получить тело сообщения, разделенное на обычный текст и HTML-текст. У вас есть какие-либо идеи, как я могу это сделать? @Max
3. Что ж, начните с использования email.message_from_bytes для преобразования его в дерево MIME. Вы можете ходить по дереву… Если вы используете анализаторы нового стиля, он должен быть в состоянии угадать, что это за тело / и
4. Я постараюсь, спасибо @Max
Ответ №1:
Используйте это
import imaplib
import email
host = input('Your Hostname: ')
username = input('Your Username: ')
password = input('Your Password: ')
def get_inbox():
mail = imaplib.IMAP4_SSL(host)
mail.login(username, password)
mail.select("inbox")
_, search_data = mail.search(None, 'SEEN')
my_message = []
for num in search_data[0].split():
email_data = {}
_, data = mail.fetch(num, '(RFC822)')
# print(data[0])
_, b = data[0]
email_message = email.message_from_bytes(b)
for header in ['subject', 'to', 'from', 'date']:
print("{}: {}".format(header, email_message[header]))
email_data[header] = email_message[header]
for part in email_message.walk():
if part.get_content_type() == "text/plain":
body = part.get_payload(decode=True)
email_data['body'] = body.decode()
elif part.get_content_type() == "text/html":
html_body = part.get_payload(decode=True)
email_data['html_body'] = html_body.decode()
my_message.append(email_data)
return my_message
if __name__ == "__main__":
my_inbox = get_inbox()
print(my_inbox)
# print(search_data)
Комментарии:
1. Спасибо, но я не понимаю, как это помогает мне с частью параллелизма. Как я уже сказал, без параллелизма у меня все работает, но я хочу сделать это с параллелизмом