It's easy to send an email . But receiving e-mail is a little more trouble . Here is the content of the email 、 title 、 The sender and others resolve .
Let's say QQ Mailbox as an example . It should be noted that , Some companies exchange Mailbox often requires the company to open authorization in the background .
import smtplib
from email.header import Header # Used to correct Email Code the title
from email.mime.text import MIMEText # Responsible for constructing text
from email.mime.image import MIMEImage # Responsible for the construction of pictures
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase # When you add attachments, you use
from email.utils import parseaddr, formataddr
from email.mime.application import MIMEApplication
## Need to carry out pop The set mailboxes are :ailiyun、qq,163 etc.
# Set login and server information
import poplib
#import settings
import imaplib
import email # Import two libraries
import base64
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
class UserInfo:
def __init__(self,mail_address,mail_password):
self.mail_user_name = mail_address.split("@")[0] # Mail user name
self.mail_password = mail_password
self.mail_address = mail_address
## Send / receive mailbox configuration
class MailSettings:
# port => 126,: 25 qq and 163: 465 ,ssl: 443,ailiyun:993
def __init__(self,name,send_host,send_port,server_host,server_port,is_ssl_host ):
self.send_port = send_port
self.send_host = send_host
self.server_host = server_host
self.server_port = server_port
self.is_ssl_host= is_ssl_host
self.name = name
def get_attaches():
pass
## Refers to the contents of an email , Send multiple different recipients
## If an email is sent , Show only one recipient , If there is N Recipients , We need to define N It's an email message
def set_email_from_and_to_info(user,receivers,subject):# subject It's a description
# Add one MIMEmultipart class , Deal with text and attachments
message = MIMEMultipart()
message['From'] = user.mail_address
message['To'] = ", ".join(receivers) ## You can target multiple , This will display all the sent messages on this email
message['Subject'] = subject
return message
## Can handle all kinds of attachments
def set_content_and_attaches(message,content_body,content_type,attache_paths):
# The text usually has html And plain text (plain) Format ; html The format is convenient for typesetting and tabulation
content = MIMEText(content_body, content_type, 'utf-8') ## plain and html Different ways
message.attach(content) ## Text
## The following deals with the related attachments
attach_num =0
for attach_path in attache_paths:
attach_num += 1
attach_name = get_filename_from_path(attach_path) ## Split the path into files
file_name = " The attachment _:"+ str(attach_num) + ":" + attach_name
_part = MIMEApplication(open(attach_path,'rb').read()) ## The attachment 1
_part.add_header('Content-Disposition', 'attachment', filename=file_name)
message.attach(_part)
return message
def get_filename_from_path(path):
split_info = path.split("\\")
return split_info[-1]
def send_email(message,user,mail_info,receivers): ## to be continued
try:
if mail_info.is_ssl_host:
print("smtp_ssl connect -> ")
smtp = smtplib.SMTP_SSL(mail_info.send_host,mail_info.send_port) ##
#smtp.set_debuglevel(2) ## If you need to print out the debugging information
else:
print("smtp connect ->")
smtp = smtplib.SMTP()
smtp.connect(mail_info.send_host,mail_info.send_port)
smtp.ehlo()
smtp.starttls()
#smtp.set_debuglevel(2) ## If you need to print out the debugging information
print("login .....")
smtp.login(user.mail_user_name,user.mail_password)
## Send separately or uniformly
print("login success ! send_mail....")
#print(message)
smtp.sendmail(user.mail_address,receivers,message.as_string()) ## Send separately ; Not a collection send ; Unified sending is another mode
print(' Mail sent successfully !',receivers)
smtp.quit()
except smtplib.SMTPException as e:
print(' Failed to send mail , Specific information :',e)
# SMTP The protocol is used to send mail ,POP3 and IMAP The protocol is used to receive mail
def pop_receive_email(user,mail_info):
try:
# Connect to POP3 The server :
server = poplib.POP3(mail_info.server_host) #settings.pop3_server)
# Identity Authentication :
server.user(user.mail_user_name) # mail_address ?
server.pass_(user.mail_password)
# stat() Return the number of messages and space :
print('Messages: %s. Size: %s' % server.stat())
# list() Return all mail numbers :
resp, mails, octets = server.list()
# You can see the list returned similar to [b'1 82923', b'2 2184', ...]
# Get the latest email , Pay attention to the index number from 1 Start :
latest_mail_index = len(mails)
resp, lines, octets = server.retr(latest_mail_index)
# lines Stores each line of the original text of the message ,
# You can get the original text of the whole email :
msg_content = b'\r\n'.join(lines).decode('gbk') ## utf-8
# The email will be parsed later :
msg = Parser().parsestr(msg_content)
print(msg)
# The mail index number directly removes the mail from the server
# server.dele(index)
# Close the connection :
server.quit()
except BaseException as e:
print(e)
def imap_receive_email(user,mail_info):
try:
M = imaplib.IMAP4_SSL(host = mail_info.server_host,port = mail_info.server_port)
print(' Connected to server ')
M.login(user.mail_user_name,user.mail_password)
print(' Has landed ')
print(M.noop())
M.select()
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
# print('Message %s\n%s\n' % (num, data[0][1]))
# print(data[0][1].decode('utf-8'))
msg = email.message_from_string(data[0][1].decode('gbk')) # bug
print(msg)
break
M.close()
M.logout()
except BaseException as e:
print(e)
# Theme analysis
def parser_subject(msg):
subject = msg['Subject']
value, charset = decode_header(subject)[0]
if charset:
value = value.decode(charset)
print(' Email subject : {0}'.format(value))
return value
# Mail information analysis
def parser_address(msg):
hdr, addr = parseaddr(msg['From'])
# name Sender email name , addr Email address of sender
name, charset = decode_header(hdr)[0]
if charset:
name = name.decode(charset)
print(' Sender email name : {0}, Email address of sender : {1}'.format(name, addr))
## How to receive mail on a specific date ?
## Mail receiving is a full push ?
## Mail parsing , How to drop attachments ?
qq_send_host = 'smtp.qq.com'#
qq_server_host = "imap.qq.com"
qq_send_port = 465 #465
qq_server_port = 993 ## Receive mail
qq_is_ssl_host = True
mail_address = '*****@qq.com'
mail_pass ='n********' ## qq It's an authorization code , Not the account password
receivers = ['h*****@sina.com.cn',"s****@163.com"]
subject = " title : This is a test email , Please do not reply !"
content_body = " Text : This is the body of the test email "
content_type = "plain"
#content_html = r'D:\mail\content.html' # Text html Empty template
attach_01 = r"D:\mail\df_y.csv" # xlsx
attach_02 = r'D:\mail\ Signature .jpg' #jpg
attach_03 = r'D:\mail\ The latest report of Shanghai real estate market .pdf' #pdf
attaches = [attach_01,attach_02,attach_03]
user = UserInfo(mail_address,mail_pass)
mail_settings = MailSettings("qq",qq_send_host,qq_send_port,qq_server_host,qq_server_port,qq_is_ssl_host)
mode = 1 # 0 :=> email ; 1: Receive mail
if mode ==0:
message = set_email_from_and_to_info(user,receivers,subject)
message = set_content_and_attaches(message,content_body,content_type,attaches)
#print("message :",message)
send_email(message,user,mail_settings,receivers)
else:
if 'imap' in mail_settings.server_host: # imap
imap_receive_email(user,mail_settings)
else: # pop3
pop_receive_email(user,mail_settings)