admin

用python代码实现邮件发送
用python程序发送邮件的好处主要有三:自动化任务通知,群发邮件,邮件炸弹主要利用的是SMTP(邮件传输协议),...
扫描右侧二维码阅读全文
30
2018/06

用python代码实现邮件发送

用python程序发送邮件的好处主要有三:自动化任务通知,群发邮件,邮件炸弹

主要利用的是SMTP(邮件传输协议),需要指定对应的smtp_server和smtp_port

这里以QQ为例,首先需要在邮箱中打开SMTP服务,位置是在设置->账户->POP3/IMAP/SMTP,得到授权码

代码如下

#!/usr/bin/env python
#-*-coding:utf-8-*-

# File Name: email.py
# Author: Wang Junjie
# Created Time: 2018-06-29

from __future__ import print_function
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

SMTP_SERVER = "smtp.qq.com"
SMTP_PORT = 25

def send_mail(user,pwd,to,subject,text):
    msg = MIMEMultipart()
    txt = MIMEText(text)

    fp = open('test.png','rb')
    img = MIMEImage(fp.read())
    fp.close()

    msg.attach(txt)
    msg.attach(img)

    msg['From'] = user
    msg['To'] = to
    msg['Subject'] = subject


    smtp_server = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
    print('Connecting To Mail Server.')
    try:
        smtp_server.ehlo()
        print('Starting Encrypted Seccion.')

        smtp_server.starttls()
        smtp_server.ehlo()
        print('Logging Into Mail Server')
        smtp_server.login(user,pwd)
        print('Sending Mail.')
        smtp_server.sendmail(user,to,msg.as_string())
    except Exception as err:
        print ('Sending Mail Failed: {0}'.format(err))
    finally:
        smtp_server.quit()


def main():
    send_mail('1234@qq.com','passwd','5678@qq.com','Important','Test Message')                                                                                                                                      

if __name__ == '__main__':
    main()

这里我们用的是python标准库中的smtplib和mime模块也实现了附件的发送功能,甚至可以搭配.sh或.py套循环来进行邮件轰炸

当然如果不想导入过多模块,也可以使用python生态里的开源项目,比如下面就是用yagmail 来做的一个命令行email客户端并打包上传到pip作为开源项目

cd ~
mkdir email ; cd ./email
touch setup.py
mkdir suemail
touch __init__.py main.py

注意email目录是我们的工作目录,而suemail 里才是项目代码(这很重要,否则最后用python setup.py install 命令是无法打包成功的!)

配置setup.py如下

#!/usr/bin/env python
#-*-coding:utf-8-*-
 
# File Name: setup.py
# Author: Wang Junjie
# Created Time: 2018-06-30

from setuptools import setup

setup(
    name = 'suemail',
    version = '1.0',
    author = 'wjj',
    author_email = '550517968@qq.com',
    description = 'A email client in terminal',
    packages=['suemail'],
    install_requires = ['yagmail'],
    tests_require = ['nose','tox'],
    entry_points={
        'console_scripts':[
            'suemail=suemail.main:main',
        ]
    }                                                                                                                                                                                                               
)

 

内部的console_scripts就是命令行的入口,比如我这里的命令就需要是

suemail -s 'subject' -r 're@...' -f ...

__ini__.py

#!/usr/bin/env python
#-*-coding:utf-8-*-
 
# File Name: __init__.py
# Author: Wang Junjie
# Created Time: 2018-06-30
import argparse
import configparser
from yagmail import *

def get_argparse():
    parser = argparse.ArgumentParser(description = 'This is an email client in terminal')
    parser.add_argument("-s",action = 'store',dest = 'subject',required = True
                       ,help = 'specify a subject(must be in quotes if it has spaces)')
    parser.add_argument('-f',action = 'store',dest = 'conf',required = False,
                       help = 'specify a config file')
    parser.add_argument('-r',action = 'store',dest = 'recipients',required = True,
                       help = 'specify who will receive the email')
    parser.add_argument('-a',action = 'store',dest = 'attaches',nargs = '*',required = False,
                       help = 'add in the extra files')
    parser.add_argument('-v',action = 'version',version = '%(prog)%s 0.2')

    return parser.parse_args()

def get_meta_from_config(config_file):
    config = configparser.SafeConfigParser()

    with open(config_file) as fp: 
        config.readfp(fp)

    meta = Storage()                                                                                                                                                                                                
    for key in ['smtp_server','smtp_port','username','password']:
        try:
            val = config.get('info',key)
        except (ConfigParser.NoSectionError,ConfigParser.NoOpetionError) as err:
            logger.error(err)
            raise SystemExit(err)
        else:
            meta[key] = val 

    return meta

def send_email(meta):
    content = get_email_content()
    body = [content]
    if meta.attaches:
        body.extend(meta.attaches)

    with yagmail.SMTP(user = meta.username,password = meta.password,
                      host = meta.smtp_server,port=int(meta.smtp_port)) as yag:
        logger.info('ready to send email {0} to {1}'.format(meta.subject,meta.recipients))

        ret = yag.send(meta.recipients,meta.subject,body)

 

比较重要的是那个configparser和argparse模块

main.py

#!/usr/bin/env python                                                                                                                                                                                               
#-*-coding:utf-8-*-
 
# File Name: main.py
# Author: Wang Junjie
# Created Time: 2018-06-30
from suemail import *

def main():
    paras = get_argparse()
    meta = get_meta_from_config('/home/dreamboy/.emcli_t.cnf')
    send_email(meta)

if __name__ == '__main__':
    main()

~/.下配置cnf配置文件,主要放置你自己的密码,用户等,避免每次输入

需要以section的形式输入(即这里的info)

目录树

 

最后用python setup.py install 打包安装

在pip官网注册账号后还可以用

twine dist /*上传到PyPI,让别人可以通过pip install 命令下载

Last modification:March 13th, 2019 at 07:06 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment