pop python3_python3 - pop 接收邮件/ smtp 发送邮件

本文提供Python3使用poplib和smtplib模块实现邮件的接收和发送。包括邮件头信息提取、邮件内容解码及附件处理。示例代码涵盖接收邮件并保存到文件,以及自动回复邮件功能。
摘要由CSDN通过智能技术生成

以下通过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 = '\n '.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 ' % (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 + '\n')

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 = '\n'.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 ' % (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) + '\n\n\n' + mail_info

break

else:

mess = '没有匹配到字典数据,请自定义'

sendmail(mess, smtp, name, pwd, to_mail, sub)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值