A recent project at work has the need to automatically send some information emails to a specified mailbox. So how to use Python to implement the function of automatically sending emails? Let’s talk about it briefly next.
Python SMTP sends email
SMTP (Simple Mail Transfer Protocol) is a simple mail transfer protocol. To put it bluntly, it is a protocol for sending emails. Python’s smplib library simply encapsulates the SMTP protocol and provides support for SMTP. It can send plain text emails, HTML files, and Emails with attachments.
First, we build a SendEmailManager class, which also follows the idea of object-oriented programming. The general structure is as follows:
class SendEmailManager(object): def __init__(self, **kwargs): # Initialization parameters ... def _get_conf(self, key): # Get configuration parameters ... def _init_conf(self): #Initialize configuration parameters ... def _login_email(self): # Log in to the email server ... def _make_mail_msg(self): # Construct text mail object ... def do_send_mail(self): # Send email ...
def init(self, **kwargs)
The initialization function of a class can be used to set object attributes and give an initial value, which can be a parameter or a fixed value. The parameter **kwargs is to pass a dictionary of variable keyword parameters to the function actual parameters. Here we mainly It is to initialize the SMTP server (qq mailbox is used here), the proxy mailbox for sending mail, the client authorization password set in the mailbox, and the variable parameters. The specific code is as follows:
# SMTP server, use qq mailbox here, other mailboxes can be used by Baidu EMAIL_HOST = 'smtp.qq.com' # The proxy email address for sending emails EMAIL_HOST_USER = '[email protected]' # The client authorization password set in the mailbox. Note that this is not the mailbox password. For how to obtain the mailbox authorization code, please Baidu~~~ EMAIL_HOST_PASSWORD = 'xxxxxxxxxxxxx'
def __init__(self, **kwargs): # Initialization parameters self.email_host = EMAIL_HOST self.email_host_user = EMAIL_HOST_USER self.email_host_pass = EMAIL_HOST_PASSWORD self.kwargs = kwargs
def _get_conf(self, key)
Mainly responsible for reading the value in the variable parameter self.kwargs dictionary through key for use by other functions.
def _get_conf(self, key): # Get configuration parameters value = self.kwargs.get(key) if key != "attach_file_list" and (value is None or value == ''): raise Exception("configuration parameter '%s' cannot be empty" % key) return value
def _init_conf(self)
This function is mainly responsible for initializing the configuration parameters returned by the function _get_conf so that the following functions can call related configuration parameters.
def _init_conf(self): #Initialize configuration parameters print(self._get_conf('receives')) self.receives = self._get_conf('receives') self.msg_subject = self._get_conf('msg_subject') self.msg_content = self._get_conf('msg_content') self.msg_from = self._get_conf('msg_from') # attachment self.attach_file_list = self._get_conf('attach_file_list')
def _login_email(self)
Log in to the mail server. I am logging in to the qq mailbox server. The port number is 465. For other mailbox port numbers, please refer to Baidu. The code is as follows:
def _login_email(self): # Log in to the email server try: server = smtplib.SMTP_SSL(self.email_host, port=465) # set_debuglevel(1) can print out all information interacting with the SMTP server server.set_debuglevel(1) # Login E-mail server.login(self.email_host_user, self.email_host_pass) return server except Exception as e: print("mail login exception:", e) raise e
def _make_mail_msg(self)
The function of this function is to construct an email instance object to process the content of the email. A normal email generally has sender and receiver information, email subject, and email body. Some emails also have attachments. For specific settings, see the following code:
def _make_mail_msg(self): # Build mail object msg = MIMEMultipart() msg.attach(MIMEText(self.msg_content, 'plain', 'utf-8')) # Email Subject msg['Subject'] = Header(self.msg_subject, "utf-8") # Sender email information msg['From'] = "<%s>" % self.msg_from # msg['From'] = Header(self.msg_from + "<%s>" % self.email_host_user, "utf-8") msg['To'] = ",".join(self.receives) print("---", self.attach_file_list) if self.attach_file_list: for i, att in enumerate(self.attach_file_list): # Construct attachments and transfer files in the current directory if not att: break att_i = MIMEText(open(att, 'rb').read(), 'base64', 'utf-8') att_i["Content-Type"] = 'application/octet-stream' # The filename here can be written arbitrarily. Whatever name you write will be displayed in the email. att_i["Content-Disposition"] = 'attachment; filename="%s"' % att msg.attach(att_i) return msg
def do_send_mail(self)
To send an email, just string together the above functions and enter the code directly:
def do_send_mail(self): # Send email try: self._init_conf() server = self._login_email() msg = self._make_mail_msg() server.sendmail(self.email_host_user, self.receives, msg.as_string()) server.close() print("Sent successfully!") except Exception as e: print("Mail sending exception", e)
Configure parameters and test whether emails can be sent normally:
if __name__ == "__main__": mail_conf = { 'msg_from': '****@foxmail.com', # The address of the email sender 'receives': ['****@qq.com',], # The address of the email recipient. This is a list, because there may be more than one recipient of the email. 'msg_subject': 'Python send email test', # The subject of the email 'msg_content': 'hello', # The content of the email 'attach_file_list': {"test.py": "test.py", "test.txt": "./test.txt"}, # is a list of attachment file paths, this item is optional. } manager = SendEmailManager(**mail_conf) manager.do_send_mail()
ok, send Success, adding attachments is no problem. Now, we have implemented sending emails using Python, so how to automatically send emails? Next, let’s talk about it.
Send emails automatically
1. Code hard coding implementation
It is an infinite loop in the code, plus an if judgment, and the transmission is executed every 1 hour. The code is as follows:
def delayed_sending(manager): #The parameter manager is the SendEmailManager object begin_time = int(time.time()) while True: end_time = int(time.time()) if end_time - begin_time == 1*60*60: threading.Thread(target=manager.do_send_mail()).start() begin_time = end_time print("Sent...")
At the same time, in order to prevent unknown reasons from blocking the normal operation of the program, multi-threads are added to send emails asynchronously. In this way, after the program is executed, an email will be sent to the specified mailbox every hour. As long as the program does not stop, the emails will continue to be sent! !
Suppose we need to send an email to a specified mailbox at 8 o’clock every day, then we can do this:
def delayed_sending(manager): #The parameter manager is the SendEmailManager object hours = 8 minute = 0 second = 0 while True: now = datetime.datetime.now() if now.hour == hour and now.minute == minute and now.second == second: threading.Thread(target=manager.do_send_mail()).start() print("Sent...")
Although the functions of the above two methods are realized, the implementation method is really low!
2. Implement timing function through modules
In addition to hard coding, we can also implement it through the schedule module of the task timing runtime library in python:
# Use the python task timing runtime library schedule module def send_mail_by_schedule(manager): schedule.every(20).minutes.do(manager.do_send_mail) # Execute every 20 minutes schedule.every().hour.do(manager.do_send_mail) # Execute once every hour schedule.every().day.at("10:00").do(manager.do_send_mail) # Execute once every day at 10:00 schedule.every().monday.do(manager.do_send_mail) # Execute once every Monday schedule.every().friday.at("21:00").do(manager.do_send_mail) # Execute once every Friday at 21:00 while True: schedule.run_pending() time.sleep(1)
Schedule is actually just a timer. In the while True infinite loop, schedule.run_pending() keeps the schedule running to query the above bunch of tasks. In the task, you can set different times to run. This is similar to crontab.
However, if multiple scheduled tasks are run, they are actually executed in order from top to bottom. If the above task is complex and takes a long time, it will affect the running time of the following tasks. If 5 tasks are run every 2 minutes, and each task takes 1 minute, it takes 5 minutes in total. In this way, when the next 2 minutes comes, the previous round of tasks is still running, and then a new round starts. Task. The solution is also very simple: use multi-threading/multi-process.
def run_threaded(manager): threading.Thread(target=manager.do_send_mail()).start() # Use the python task timing runtime library schedule module def send_mail_by_schedule(manager): schedule.every(1).minutes.do(run_threaded, manager) # Execute every 20 minutes schedule.every().hour.do(run_threaded, manager) # Execute once every hour schedule.every().day.at("10:00").do(run_threaded, manager) # Execute once every day at 10:00 schedule.every().monday.do(run_threaded, manager) # Execute once every Monday schedule.every().friday.at("21:00").do(run_threaded, manager) # Execute once every Friday at 21:00 while True: schedule.run_pending() time.sleep(1)
In this way, we can create a thread for each scheduled task and let the task run in the thread, thereby achieving the effect of multiple tasks working in parallel. Does this method save time and effort than the first method? It doesn’t require a lot of code at all. It’s perfect!
Summary
In fact, to put it bluntly, the most important thing about automatically sending emails is to realize the automatic execution of tasks, and there are many implementation solutions. For example, you can also use an asynchronous task scheduler similar to celery to manage the queue. Monitor to realize automatic execution of tasks, etc.
After completing the automatic sending of emails, we can also let the program send us weather forecasts, daily news, chicken soup, etc. every day (it can also be sent to male and female friends) hahaha.
The rapid rise of Python is extremely beneficial to the entire industry, but “There are many popular people and not many people
“, which has led to a lot of criticism, but it still cannot stop its popularity. development momentum.
If you are interested in Python and want to learn Python, here I would like to share with you a Complete set of Python learning materials, which I compiled during my own study. I hope it can help you, let’s work together!
Friends in need can click the link below to get it for free or Scan the QR code below to get it for free
Python complete set of learning materials
1Getting started with zero basics
① Learning route
For students who have never been exposed to Python, we have prepared a detailed Learning and Growth Roadmap for you. It can be said to be the most scientific and systematic learning route. You can follow the above knowledge points to find corresponding learning resources to ensure that you learn more comprehensively.
② Route corresponding learning video
There are also many learning videos suitable for beginners. With these videos, you can easily get started with Python~
③Exercise questions
After each video lesson, there are corresponding exercises to test your learning results haha!
2Domestic and foreign Python books and documents
① Documents and books
3Python toolkit + project source code collection
①Python toolkit
The commonly used development software for learning Python is here! Each one has a detailed installation tutorial to ensure you can install it successfully!
②Python practical case
Optical theory is useless. You must learn to type code along with it and practice it in order to apply what you have learned to practice. At this time, you can learn from some practical cases. 100+ practical case source codes are waiting for you!
③Python mini game source code
If you feel that the practical cases above are a bit boring, you can try writing your own mini-game in Python to add a little fun to your learning process!
4Python interview questions
After we learn Python, we can go out and find a job if we have the skills! The following interview questions are all from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and Alibaba bosses have given authoritative answers. I believe everyone can find a satisfactory job after reviewing this set of interview materials.
5Python part-time channels
Moreover, after learning Python, you can also take orders and make money on major part-time platforms. I have compiled various part-time channels + part-time precautions + how to communicate with customers into documents.
All the above information , if friends need it, you can scan the QR code below to get it for free