电子邮件是最古老的互联网服务之一,发明于1969年,它已经50岁了!它并不要求收信人发信人同时连接网络,邮件存放于服务器,所以至今在企业内部还在大量使用。而且它是开放协议,没有被某大公司垄断。我们完全可以拿来做一个可靠的消息来源。
比如说我们在远程主机运行一个耗时较长的任务,或者搭建某个自己写的后台服务,当某些事件发生时,就可以发送一个邮件,手机任何一个邮件客户端都可以接收推送。
国内较好的邮件服务器就是QQ邮件了,它支持SMTP, ftjMAP, 默认都支持SSL的,这点很重要。要知道SMTP, POP密码都是明文显示在TCP包里。要开启SMTP/IMAP, 要在QQ邮件里做一下设置,拿到授权码,这个就是做为SMTP/IMAP的密码,而不是QQ密码。
用IMAP接收邮件
python标准库里的imaplib就支持IMAP, 连接imap.qq.com即可
with IMAP4_SSL("imap.qq.com") as M:
M.noop()
M.login("111111@qq.com", "gzoyimtltnqsbdba") #qq邮件地址和刚才拿到的授权码,注意不是QQ号码和QQ密码
M.select()
typ, data = M.search(None, 'ALL') #ALL为所有邮件,可替换为想搜索的字符串
count = 10
pcount = 1
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)') #RFC822 为email标准
for response_part in data:
if isinstance(response_part, tuple):
part = response_part[1].decode('utf-8')
msg = email.message_from_string(part) #收到的邮件包
parseHeader(msg)
parseBody(msg)
pcount += 1
if pcount > count:
break
上面的msg包含了邮件本身的所有信息,我们感兴趣的有from, to, cc, subject, body等,分别代表了发件人,收件人,抄送列表,标题和邮件主体。python提供了email库帮助从message里提取。
subject = message.get('Subject')
# subject=str(message)
# if subject is not None:
h = email.header.Header(subject, charset='utf-8')
dh = email.header.decode_header(h)
subject = str(dh[0][0], encoding="utf-8")
subject = encoded_words_to_text(subject)
# .encode('utf-8')
# print(h)
# # 发件人
from_sb = encoded_words_to_text(email.utils.parseaddr(message.get('from'))[0])
if len(from_sb) == 0:
from_sb = encoded_words_to_text(email.utils.parseaddr(message.get('from'))[1])
# # 收件人
to_sb = email.utils.parseaddr(message.get('to'))[1]
# # 抄送人
cc = email.utils.parseaddr(message.get_all('cc'))[1]
# try:
fmt = "ddd, D MMM YYYY HH:mm:ss Z"
# date = arrow.get(message['Date'], fmt)
date = arrow.get(message['Received'].split(';')[1], fmt)
print(f"{from_sb:30} {subject:80} {date.humanize():20}")
arrow是python的一个第三方时间库,humanize可以生成one month ago这样容易懂的格式。
encoded_words_to_text方法是专门用来处理=?utf-8?q?打头的字符串的,因为电子邮件设计当初是只考虑ASCII码的,因为unicode还没诞生!为了支持unicode,又兼容以前的邮件,所以引入了这样的字符串格式。
def encoded_words_to_text(encoded_words):
if not encoded_words.startswith("=?"):
return encoded_words
encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
charset, encoding, encoded_text = re.match(encoded_word_regex, encoded_words, flags=re.IGNORECASE).groups()
if encoding.upper() == 'B':
byte_string = base64.b64decode(encoded_text)
elif encoding.upper() == 'Q':
byte_string = quopri.decodestring(encoded_text)
return byte_string.decode(charset)
###用smtplib发送邮件
发送相对于接收就很简单了,在用QQ授权码登录smtp.qq.com服务器后调用sendemail就可以了,唯一要注意的一点是sendmail的msg参数是指email的所有内容,并没有提供subject和body的专门参数。所以我们需要用换行符分开。
def send_mail(fromaddr, toaddrs, subject, body):
# Add the From: and To: headers at the start!
msg = ("From: %s\r\nTo: %s\r\nSubject: %s\n\n%s"
% (fromaddr, ", ".join(toaddrs), subject, body))
while True: # 从命令行接收邮件内容,直到连按两下回车
try:
line = input()
except EOFError:
break
if not line:
break
msg = msg + line
print("Message length is", len(msg))
server = SMTP_SSL('smtp.qq.com')
server.set_debuglevel(1) #打开调试
server.login("111111@qq.com", "gzoyimtltnqsbdba")
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
扫码关注公众号,获取最新文章
来源:CSDN
作者:DigiHacker
链接:https://blog.csdn.net/atulxqiang/article/details/104374459