Python学习笔记 - 发送邮件

电子邮件的传输协议是SMTP,Python内置了对SMTP协议的支持,对应的模块是smtplib和email模块。

  • smtplib

    smtplib模块负责在发送邮件的过程中和服务器通信,简单来说就是:

    • 连接服务器
    • 登录邮箱
    • 发送邮件
    • 退出服务器
  • email

    email模块负责和服务器通信的信息,比如邮件内容,附件,收件人,发件人,主题等等。

也就是说smtplib模块负责发邮件,email模块负责写邮件

发送一份邮件的步骤:

用qq邮箱举例:

  1. 第一步要做的就是连接服务器。这里用到的是smtplib模块的SMTP方法:

    • host,SMTP 服务器主机地址
    • port,端口号,默认端口是25

    需要传入上面两个参数,因为不知道所以查一下:

    在qq邮箱的帮助中心找到了。

    但是还没完,因为邮件是私密的信息,不可能用明文传输,所以一般都会加密,所以还要找一下qq邮箱的加密标准。

    同样的在qq邮箱帮助中心找到,是SSL方式加密的。

    smtp模块的不同的加密写法如下:

    import smtplib
    # 端口是用TLS加密
    smtplib_obj = smtplib.SMTP('服务器地址',端口)
    # 端口是用SSL加密
    smtplib_obj = smtplib.SMTP_SSL('服务器地址',端口)
    复制代码

    好了,现在就写代码,连接服务器:

    import smtplib
    
    qq_mail = smtplib.SMTP_SSL('smtp.qq.com', 465)
    复制代码
  2. 然后写用户名密码登录邮箱:

    from_address = input('请输入邮箱账号:')
    password = input('请输入邮箱密码:')
    qq_mail.login(from_address, password)
    复制代码

    登录是用login方法

  3. 写邮件,这里先不用email模块去构造,先直接写一个看看

    to_address = input('请输入收件人地址:')
    message = input('请输入邮件内容:')
    复制代码

    获取收件人地址和邮件内容

  4. 发送邮件

    qq_mail.sendmail(from_address, [to_address], message)
    复制代码

    sendmail方法用来发送邮件,它的参数是:

    • from_addr: 邮件发送者地址。
    • to_addrs: 字符串列表,邮件发送地址。
    • msg: 发送消息
  5. 退出服务器

    qq_mail.quit()
    复制代码
  6. 运行

    这里还有一个小坑,如果你的文件名叫email.py的话,它会报这个错

    AttributeError: module 'smtplib' has no attribute 'SMTP_SSL'
    复制代码

    具体原因看这里stackoverflow,解决办法就是不要用email这个文件名

    如果按照上面的例子一步一步写,那么会出现这个错误:

    smtplib.SMTPAuthenticationError

    这是因为你的邮箱没有开启SMTP服务。现在去开启: 在【设置】- 【账户设置】往下拉会看到这个:

    开启它

    然后你会得到一个16位的授权码,你用smtplib登录邮箱的密码就是这个,不再是邮箱原本的密码。

    用户就会收到一封这样的邮件,没有发件人没有主题,连我们输入的邮件内容都没有

  7. 使用email模块添加主题等信息

    • 使用MIMEText构造邮件内容。

      email.mime.text.MIMEText(_text[, _subtype[, _charset]])

      MIMEText 类用于创建主要类型 text 的MIME对象。

      • _text: 文本内容
      • _subtype:指定文本类型,支持 plain(默认值)或 html类型的字符串。
      • _charset:用于指定文本内容的编码表
      from email.mime.text import MIMEText
      
      msg = MIMEText('你好,这是用python发送的邮件', 'plain', 'utf-8')
      复制代码
    • 使用Header添加邮件的收件人,发件人,主题

      email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

      创建一个MIME兼容的头,可以包含不同字符集中的字符串。

      常用的参数是s和charset(其他参数还没搞清楚 +_+)

      • s:初始标头值
      • charset:charset指定编码表
      from email.header import Header
      
      msg['From'] = Header("发件人",'utf-8')
      msg['To'] = Header("收件人",'utf-8')
      msg['Subject'] = Header('主题', 'utf-8')
      复制代码
    • 使用 parseaddr, formataddr格式化邮件头部信息。

      • email.utils.parseaddr(address)

        email.utils.parseaddr接受包含了邮件地址的字符串,然后返回一个解析后的元组。例子:

        print(parseaddr('name<email_address@qq.com>'))
        # ('name', 'email_address@qq.com')
        复制代码
      • email.utils.formataddr(pair, charset='utf-8')

        formataddr是parseaddr方法的逆,接受包含收件人昵称和邮箱账号的元组或列表,返回一个字符串,例子:

        print(formataddr(('name', 'email_address@qq.com'), 'utf-8'))
        # name <email_address@qq.com>
        复制代码
    • 发送

      qq_mail.sendmail(from_address, [to_address], msg.as_string())
      复制代码

      as_string是MIME实例对象的方法,将整个消息作为字符串返回。

    我在看廖雪峰大神的Python教程的时候,发现他的收件人信息等等都进行了编码处理,教程上说如果有中文的话需要通过Header对象进行编码,我自己写的时候没有编码,直接用的中文也是成功了,所以我也不确定需不需要加这个处理。这里还是加上吧,可能不加会有一些我没遇到的坑,最终用email模块构造邮件的代码是:

    import smtplib
    from email.header import Header
    from email.mime.text import MIMEText
    from email.utils import parseaddr, formataddr
    
    
    def format_addr(str):
        name, address = parseaddr(str)
        return formataddr([Header(name, 'utf-8').encode(), address])
    
    
    try:
        qq_mail = smtplib.SMTP_SSL('smtp.qq.com', 465)
        from_address = input('请输入邮箱账号:')
        password = input('请输入邮箱密码:')
        qq_mail.login(from_address, password)
    
        to_address = input('请输入收件人地址:')
        message = input('请输入邮件内容:')
    
        msg = MIMEText(message, 'plain', 'utf-8')
        msg['From'] = format_addr('神秘人 <%s>' % from_address)
        msg['To'] = format_addr('另一个神秘人 <%s>' % to_address)
        msg['Subject'] = Header('今天吃了吗?', 'utf-8').encode()
    
        qq_mail.sendmail(from_address, [to_address], msg.as_string())
        print('发送成功')
        qq_mail.quit()
    except smtplib.SMTPException as e:
        print('邮件发送失败,原因:%s' % e)
    
    复制代码

    结果

    但是收件人的名字并不是代码里写的,而是qq的昵称,可能腾讯对这个做了什么限制吧。

    一般的文本内容发送就是以上这些了,下面看一下发送附件怎么发送。

  • 发送html邮件

    发送html的邮件很简单,只需要将MIMEText方法中的plain改为html,然后text参数传入html字符串。例子:

    message = '''
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>test</title>
        </head>
        <body>
            <h1>google</h1>
            <a href="https://www.google.com/">点我</a>
        </body>
        </html>'''
    msg = MIMEText(message, 'html', 'utf-8')
    复制代码

  • 发送图片

    图片可以作为邮件本身的内容,也可以作为附件发送。先看作为附件怎么发送:

    from email.mime.base import MIMEBase
    from email.mime.multipart import MIMEMultipart  # 带多个部分的邮件,比如既有图片又有文本
    from email.mime.text import MIMEText  # html格式和文本格式的对象
    from email.mime.image import MIMEImage  # 附件为图片格式的对象
    from email.mime.audio import MIMEAudio  # 附件为音频格式的对象
    from email import encoders  # 编码器
    复制代码

    把图片作为附件发送

    # 因为既有文本又有图片附件,所以用MIMEMultipart创建实例
    msg = MIMEMultipart()
    # attach方法相当于给msg对象,添加不同的部分
    msg.attach(MIMEText('发个图片', 'plain', 'utf-8'))
    
    # 从本地读取一个图片添加为附件:
    with open('./test.jpeg', 'rb') as f:
        mes_image = MIMEImage(f.read())
        # 给图片一个id,如果图片放入html中,那么就要用到它
        mes_image.add_header('Content-ID', 'img_0')
        # 给附件一个名字
        mes_image.add_header('Content-Disposition', 'attachment', filename='test.jpeg')
        # 添加到MIMEMultipart
        msg.attach(mes_image)
    复制代码

    结果:

    完整代码:

    import smtplib
    from email.header import Header
    from email.mime.text import MIMEText
    from email.utils import parseaddr, formataddr
    from email.mime.multipart import MIMEMultipart
    from email.mime.image import MIMEImage
    
    
    def format_addr(str):
        name, address = parseaddr(str)
        return formataddr([Header(name, 'utf-8').encode(), address])
    
    
    try:
        qq_mail = smtplib.SMTP_SSL('smtp.qq.com', 465)
        from_address = input('请输入邮箱账号:')
        password = input('请输入邮箱密码:')
        qq_mail.login(from_address, password)
        to_address = input('请输入收件人地址:')
        # 因为既有文本又有图片附件,所以用MIMEMultipart创建实例
        msg = MIMEMultipart()
        # attach方法相当于给msg对象,添加不同的部分
        msg.attach(MIMEText('发个图片', 'plain', 'utf-8'))
    
        # 从本地读取一个图片添加为附件:
        with open('./test.jpeg', 'rb') as f:
            mes_image = MIMEImage(f.read())
            # 给图片一个id,如果图片放入html中,那么就要用到它
            mes_image.add_header('Content-ID', 'img_0')
            # 给附件一个名字
            mes_image.add_header('Content-Disposition', 'attachment', filename='test.jpeg')
            # 添加到MIMEMultipart
            msg.attach(mes_image)
        msg['From'] = format_addr('神秘人 <%s>' % from_address)
        msg['To'] = format_addr('另一个神秘人 <%s>' % to_address)
        msg['Subject'] = Header('今天吃了吗?', 'utf-8').encode()
    
        qq_mail.sendmail(from_address, [to_address], msg.as_string())
        print('发送成功')
        qq_mail.quit()
    except smtplib.SMTPException as e:
        print('邮件发送失败,原因:%s' % e)
    复制代码

    作为邮件内容发送,作为邮件内容发送,需要使用html格式的内容,然后将图片的id写在img标签的src属性里就可以了:

    msg.attach(MIMEText('''
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>Document</title>
        </head>
        <body>
            <p>发个图片</p>
            <!-- 这里的id,就是mes_image.add_header('Content-ID', 'img_0')这里设置的id-->
            <img src="cid:img_0"
        </body>
        </html>
    ''', 'html', 'utf-8'))
    复制代码

转载于:https://juejin.im/post/5c25c8e76fb9a049fe3537b9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python学习笔记》是由皮大庆编写的一本关于Python语言学习的教材。在这本书中,作者详细介绍了Python语言的基础知识、语法规则以及常用的编程技巧。 首先,作者简要介绍了Python语言的特点和优势。他提到,Python是一种易于学习和使用的编程语言,受到了广大程序员的喜爱。Python具有简洁、清晰的语法结构,使得代码可读性极高,同时也提供了丰富的库和模块,能够快速实现各种功能。 接着,作者详细讲解了Python的基本语法。他从变量、数据类型、运算符等基础知识开始,逐步介绍了条件语句、循环控制、函数、模块等高级概念。同时,作者通过大量的示例代码和实践案例,帮助读者加深对Python编程的理解和应用。 在书中,作者还特别强调了编写规范和良好的编程习惯。他从命名规范、注释风格、代码缩进等方面指导读者如何写出清晰、可读性强的Python代码。作者认为,良好的编程习惯对于提高代码质量和提高工作效率非常重要。 此外,作者还介绍了Python的常用库和模块。他提到了一些常用的库,如Numpy、Pandas、Matplotlib等。这些库在数据处理、科学计算、可视化等领域有广泛的应用,帮助读者更好地解决实际问题。 总的来说,《Python学习笔记》是一本非常实用和全面的Python学习教材。通过学习这本书,读者可以系统地学习和掌握Python编程的基础知识和高级应用技巧,为以后的编程学习和工作打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值