备选的方案
- mailgun 插件,该插件不错,但是没有外网的情况下,只能pass掉了
- imaplib + email 模块,手撸邮件接收。邮件标题还比较好处理,但是到了邮件内容方面发现并没有那么简单。 首先邮件的maintype 有 'multipart' 和 text格式之别,就是有无附件,或者纯文字。在每种模式当中需要识别编码,utf8 gb2312或者其它。但是有时候,每个厂商的邮件并不是每个编码信息都携带,导致编码和识别很费劲。偶现错误无法定位
我的代码如下,看看哪块还需要补充
以下代码。 Expert 是我的待收邮件人员名单,Email是接收邮件之后存入这里面。外面接口读取Email这个model
import imaplib
import email
import sys
sys.path.append('.')
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "EmergencyResources.settings")
import django
django.setup()
from email.header import decode_header
from email.utils import parseaddr
from datetime import datetime
from boats.models import Email
from Online.models import Expert
from django.conf import settings
class ReciveEmial:
def __init__(self):
self.username = ""
self.password = ""
self.server = None
def all_email(self):
if self.server is None:
self.server = imaplib.IMAP4("imap.163.com", 143)
self.server.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)
self.server.select("INBOX")
return self.server.search(None, 'ALL')
def decode_content(self, content):
header_text, header_coding = decode_header(content)[0]
if header_coding is None:
header_coding = "utf8"
if isinstance(header_text, str):
return header_text
return str(header_text, encoding=header_coding)
def email_body(self, msg):
maintype = msg.get_content_maintype()
# print(maintype)
mail_content = ""
mail_code = msg.get_content_charset()
if maintype == 'multipart':
for part in msg.get_payload():
# print(part.get_content_maintype())
if part.get_content_maintype() == 'text':
mail_content = part.get_payload(decode=True).strip()
try:
if mail_code is None:
mail_code = "utf8"
return mail_content.decode(mail_code)
except Exception as e:
return mail_content.decode("GB2312")
elif maintype == 'text':
text = msg.get_payload(decode=True).strip()
if isinstance(text, bytes):
return text.decode('utf8')
return text
def email_content_parser(self):
# 发件人名单
emails = []
peoples = []
experts = Expert.objects.all()
for expert in experts:
emails.append(expert.email)
peoples.append(expert.name)
# 收件
email_list = self.all_email()[1][0].split()
for number in email_list:
typ, data = self.server.fetch(number, '(RFC822)')
content = data[0][1]
message = email.message_from_bytes(content)
subject = message.get('subject')
try:
result_subject = self.decode_content(subject)
except Exception:
result_subject = self.decode_header(subject)
hdr, result_from = parseaddr(message.get('from'))
result_date = message.get('date')
result_body = self.email_body(message)
messageid = message.get('Message-ID')
if result_from in emails:
people = peoples[emails.index(result_from)]
message = Email.objects.filter(message_id=messageid)
if not message:
Email.objects.create(message_id=messageid, subject=result_subject, date=result_date,
content=result_body, people=people)
if __name__ == '__main__':
import time
while True:
print('--扫描邮件--')
re = ReciveEmial()
re.email_content_parser()
time.sleep(120)
def recive_email():
re = ReciveEmial()
re.email_content_parser()
- 寻找现成的接收邮件模块。。。