以下通过python3 实现接收和发送邮件,网上相关说明文档很多。请自己查阅,这里只写入代码,
# 实例:通过poplib 模块接收指定账号的邮件并进行解码处理,结果可视化。
#!/opt/python3/bin/python3 # _*_ coding:utf-8 _*_ # Author: Yong import smtplib import email as pop_email from email.parser import Parser from email.mime.text import MIMEText from email.utils import formataddr, parseaddr from email.header import decode_header import email, poplib, sys # 接收邮件 def decode_str(s): '''进行消息解码''' value, charset = decode_header(s)[0] # decode_header()返回一个list,因为像Cc、Bcc这样的字段可能包含多个邮件地址,所以解析出来的会有多个元素。上面的代码我们偷了个懒,只取了第一个元素。 if charset: value = value.decode(charset) return value def guess_charset(msg): '''返回字符编码''' content_type = msg.get('Content-Type', '').lower() pos = content_type.find('charset=') if pos >= 0: charset = content_type[pos + 8:].strip() return charset def pop_mail(pop_server, logname, logpwd): '''进行接收邮件''' tmp_list = [] mail_file = open('mail.txt', 'w', encoding='utf-8') pop_obj = poplib.POP3(pop_server, 110) try: pop_obj.user(logname) pop_obj.pass_(logpwd) status, mail_list, oct = pop_obj.list() for i in mail_list: # 根据邮件索引ID,循环每一个邮件 tmp_dict = {} # 临时存储每一个邮件,格式{'From':'', 'To':'', 'Subject':'', 'content':''} content_list = pop_obj.retr(bytes.decode(i.split()[0])) # 根据索引ID,提取邮件内容 msg_content = ' '.join([bytes.decode(text) for text in content_list[1]]) msg = Parser().parsestr(msg_content) # 进行邮件头信息的提取 for head in ['From','To','Subject']: value = msg.get(head, '') # 获取指定头的内容 if value: if head == 'Subject': mess_value = decode_str(value) # 对主题进行解码 else: hdr, addr = parseaddr(value) # 获取发件人和接收人的名称和邮箱地址 hdr = decode_str(hdr) addr = decode_str(addr) mess_value = '%s <%s>' % (hdr, addr) tmp_dict[head] = mess_value # 添加到临时字典 # 进行邮件正文内容的提取 if msg.is_multipart(): # 带附件的内容 for part in msg.walk(): if part.get_content_type() == 'text/plain': # 只提取内容正文,不提取附件等其他信息 charset = part.get_charsets()[0] # 获取内容字符集 body = part.get_payload(decode=True) # 获取内容(编码前的) if charset: content = body.decode(charset) # 对内容进行解码 else: content = body # 未解码的直接提取内容 else: # 不带附件的内容 content_type = msg.get_content_type() # 获取内容类型 if content_type == 'text/plain' or content_type == 'text/html': content = msg.get_payload(decode=True) # 提取内容 charset = guess_charset(msg) # 提取字符集 if charset: content = content.decode(charset) # 对内容进行解码 else: content = 'nofound:text/plain,text/html' # 类型没有匹配到 tmp_dict['content'] = content # 添加到临时字典 tmp_list.append(tmp_dict) # 将一封邮件进行处理后,添加到一个列表 pop_obj.quit() # 关闭POP连接 # 循环提取每一份邮件,进行写到文档中 for data in tmp_list: mail_info = ''' 发送者:%s 接收者:%s 主题:%s 内容: %s ''' % (data['From'].strip(), data['To'].strip() if 'To' in data else '群发邮件', data['Subject'].strip(), data['content'].strip()) mail_file.write(mail_info + ' ') mail_file.close() except poplib.error_proto as e: print('pop Error:', e) if __name__ == '__main__': '''输出文件mail.txt''' pop = '接收服务器域名' name = '登录名' pwd = '登录密码' pop_mail(pop, name, pwd)
# 实例:发送邮件
import smtplib import email as pop_email from email.parser import Parser from email.mime.text import MIMEText from email.utils import formataddr, parseaddr from email.header import decode_header import email, poplib, sys def sendmail(message, sendmail_server, logname, logpwd, to_mailer): # to_mailer 为接收者邮件列表 msg = MIMEText(message, 'plain', 'utf-8') msg['From'] = formataddr(['管理员(显示的名称)', 'from_mail@aaaa']) # 邮件接收后,发件人显示的名称和邮箱 msg['To'] = formataddr(['jojo', 'to_mail@bbbbb']) # 邮件接收后,收件人显示的名称和邮箱 msg['Subject'] = 'python test' try: server = smtplib.SMTP('sendmail_server', 25) server.login('logname', 'logpwd') server.sendmail('logname', to_mailer, msg.as_string()) print('邮件发送成功') server.quit() except smtplib.SMTPException as e: print('Error:', e)
实例:实现指定邮箱自动接收且进行自动匹配字典库关键字进行回复,对读取过的邮件有记录功能不再进行处理,测试代码如下:
#!/opt/python3/bin/python3 # _*_ coding:utf-8 _*_ # Author: Yong import smtplib import email as pop_email from email.parser import Parser from email.mime.text import MIMEText from email.utils import formataddr, parseaddr from email.header import decode_header import email, poplib, sys, os import json # 发送邮件 def sendmail(message, sendmail_server, logname, logpwd, to_mailer, sub): # to_mailer 为接收者邮件列表 msg = MIMEText(message, 'plain', 'utf-8') msg['From'] = formataddr(['赵勇', logname]) # 邮件接收后,发件人显示的名称和邮箱 msg['To'] = formataddr([to_mailer[0], to_mailer[1].strip('>')]) # 邮件接收后,收件人显示的名称和邮箱 msg['Subject'] = sub msg['Accept-Language'] = 'zh-CN' msg['Accept-Charset'] = 'ISO-8859-1, utf-8' try: server = smtplib.SMTP(sendmail_server, 25) server.login(logname, logpwd) server.sendmail(logname, to_mailer, msg.as_string()) print('邮件发送成功') server.quit() except smtplib.SMTPException as e: print('Error:', e) # 接收邮件 def decode_str(s): '''进行消息解码''' value, charset = decode_header(s)[0] # decode_header()返回一个list,因为像Cc、Bcc这样的字段可能包含多个邮件地址,所以解析出来的会有多个元素。上面的代码我们偷了个懒,只取了第一个元素。 if charset: value = value.decode(charset) return value def guess_charset(msg): '''返回字符编码''' content_type = msg.get('Content-Type', '').lower() pos = content_type.find('charset=') if pos >= 0: charset = content_type[pos + 8:].strip() return charset def pop_mail(pop_server, logname, logpwd): '''进行接收邮件''' if os.path.isfile(save_file): with open(save_file) as f: index_list = json.load(f) else: index_list = [] pop_obj = poplib.POP3(pop_server, 110) try: mail_index = [] pop_obj.user(logname) pop_obj.pass_(logpwd) status, mail_list, oct = pop_obj.list() for i in mail_list: # 根据邮件索引ID,循环每一个邮件 tmp_dict = {} # 临时存储每一个邮件,格式{'From':'', 'To':'', 'Subject':'', 'content':''} i = bytes.decode(i) if i in index_list: continue else: index_list.append(i) content_list = pop_obj.retr(i.split()[0]) # 根据索引ID,提取邮件内容 # content_list = pop_obj.retr(i) # 根据索引ID,提取邮件内容 msg_content = ' '.join([bytes.decode(text) for text in content_list[1]]) msg = Parser().parsestr(msg_content) # 进行邮件头信息的提取 for head in ['From','To','Subject']: value = msg.get(head, '') # 获取指定头的内容 if value: if head == 'Subject': mess_value = decode_str(value) # 对主题进行解码 else: hdr, addr = parseaddr(value) # 获取发件人和接收人的名称和邮箱地址 hdr = decode_str(hdr) addr = decode_str(addr) mess_value = '%s <%s>' % (hdr, addr) tmp_dict[head] = mess_value # 添加到临时字典 # 进行邮件正文内容的提取 if msg.is_multipart(): # 带附件的内容 for part in msg.walk(): if part.get_content_type() == 'text/plain': # 只提取内容正文,不提取附件等其他信息 charset = part.get_charsets()[0] # 获取内容字符集 body = part.get_payload(decode=True) # 获取内容(编码前的) if charset: content = body.decode(charset) # 对内容进行解码 else: content = body # 未解码的直接提取内容 else: # 不带附件的内容 content_type = msg.get_content_type() # 获取内容类型 if content_type == 'text/plain' or content_type == 'text/html': content = msg.get_payload(decode=True) # 提取内容 charset = guess_charset(msg) # 提取字符集 if charset: content = content.decode(charset) # 对内容进行解码 else: content = 'nofound:text/plain,text/html' # 类型没有匹配到 tmp_dict['content'] = content # 添加到临时字典 mail_index.append(tmp_dict) pop_obj.quit() with open(save_file, 'w') as f: f.write(json.dumps(index_list)) return mail_index except poplib.error_proto as e: print('pop Error:', e) if __name__ == '__main__': custom_dict = { '名字': '勇', '年龄': 38, '性别': '汉' } smtp = 'smtp.263xmail.com' pop = 'pop.263xmail.com' name = 'xxx@xxx.com' pwd = 'xxx' save_file = 'mail_save.json' pop_content = pop_mail(pop, name, pwd) if len(pop_content) == 0: exit('当前没有新邮件') for mail in pop_content: mail_info = ''' ———————————————————————————————————————————————— 发送者:%s 接收者:%s 主题:%s 内容: %s ''' % (mail['From'].strip(), mail['To'].strip() if 'To' in mail else '群发邮件', mail['Subject'].strip(), mail['content'].strip()) to_mail = mail['From'].split('<') sub = 'To: %s' % mail['Subject'] for key,value in custom_dict.items(): if key in mail['content']: mess = str(value) + ' ' + mail_info break else: mess = '没有匹配到字典数据,请自定义' sendmail(mess, smtp, name, pwd, to_mail, sub)