簡單三步,用 Python 發郵件

0. 前言

發送電子郵件是個很常見的開發需求。好比你寫了個監控天氣的腳本,發現次日要下雨,或者網站上關注的某個商品降價了,就能夠發個郵件到郵箱來提醒本身。html

使用 Python 腳本發送郵件並不複雜。不過因爲各家郵件的發送機制和安全策略不一樣,經常會由於一些配置問題形成發送失敗。今天咱們來舉例講講如何使用 Python 發送郵件。編程

本文主要內容包括,瞭解發郵件的思路,發送郵件須要的一些設置,發送一封簡單的郵件,發送一封包含附件的郵件,在寫代碼過程當中咱們須要注意哪些問題等等。(完整參考代碼地址見文末)安全

1. 思路

使用腳本發送郵件的思路其實和客戶端發送郵件同樣,過程都是:服務器

登陸 — > 寫郵件 —> 發送微信

只不過經過腳本發送時咱們須要考慮到整個過程的方方面面。如下爲思路導圖:併發

2. Python-email 模塊

與發送郵件相關的 Python 模塊:app

smtplib學習

是關於 SMTP(簡單郵件傳輸協議)的操做模塊,在發送郵件的過程當中起到服務器之間互相通訊的做用。網站

emailui

簡單來講,即服務器之間通訊的信息,包括信息頭、信息主體等等。

舉個簡單的例子,當你登陸郵箱,寫好郵件後點擊發送,這部分是由 SMTP 接管;而寫郵件、添加附件是由 email 模塊控制。

3. 開通電子郵箱的SMTP功能

在使用腳本發郵件以前,咱們須要打開本身郵箱的 SMTP 功能,各家郵箱的設置方法就不一一講述了,具體使用時能夠百度一下,下面以 163 郵箱設置爲例作一個簡單的演示:

4. 簡單代碼

實踐出真知,咱們結合一個簡單的代碼來理解這一過程:登陸 163 郵箱,向 qq 郵箱發送郵件。

腳本分爲三個步驟:

  1. 設置好服務器端信息
  2. 郵件主體信息
  3. 登陸發送

另外在處理文本時,咱們須要使用 MIMEText 類。

import smtplib
from email.mime.text import MIMEText
#設置服務器所需信息
#163郵箱服務器地址
mail_host = 'smtp.163.com'
#163用戶名
mail_user = '159*****02'
#密碼(部分郵箱爲受權碼)
mail_pass = '7******x'
#郵件發送方郵箱地址
sender = '159*****02@163.com'
#郵件接受方郵箱地址,注意須要[]包裹,這意味着你能夠寫多個郵件地址羣發
receivers = ['59*****02@qq.com']

#設置email信息
#郵件內容設置
message = MIMEText('content','plain','utf-8')
#郵件主題
message['Subject'] = 'title'
#發送方信息
message['From'] = sender
#接受方信息
message['To'] = receivers[0]

#登陸併發送郵件
try:
    smtpObj = smtplib.SMTP()
    #鏈接到服務器
    smtpObj.connect(mail_host,25)
    #登陸到服務器
    smtpObj.login(mail_user,mail_pass)
    #發送
    smtpObj.sendmail(
        sender,receivers,message.as_string())
    #退出
    smtpObj.quit()
    print('success')
except smtplib.SMTPException as e:
    print('error',e) #打印錯誤

結果:

注意事項:

一些郵箱登陸好比 QQ 郵箱須要 SSL 認證,因此 SMTP 已經不能知足要求,而須要SMTP_SSL,解決辦法爲:

#啓動
smtpObj = smtplib.SMTP()
#鏈接到服務器
smtpObj.connect(mail_host,25)
#######替換爲########
smtpObj = smtplib.SMTP_SSL(mail_host)

5. 帶有附件的email

上面咱們介紹了發送字符串的郵件,但這明顯不知足現代郵件的需求,下面咱們介紹如何發送內容以 HTML 格式,而且帶有圖片和文本文件的郵件。

處理多種形態的郵件主體咱們須要 MIMEMultipart 類,而處理圖片須要 MIMEImage 類。

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

#設置登陸及服務器信息
mail_host = 'smtp.163.com'
mail_user = '159*****02'
mail_pass = '7******x'
sender = '159*****02@163.com'
receivers = ['7******0@qq.com']

#設置eamil信息
#添加一個MIMEmultipart類,處理正文及附件
message = MIMEMultipart()
message['From'] = sender
message['To'] = receivers[0]
message['Subject'] = 'title'
#推薦使用html格式的正文內容,這樣比較靈活,能夠附加圖片地址,調整格式等
with open('abc.html','r') as f:
    content = f.read()
#設置html格式參數
part1 = MIMEText(content,'html','utf-8')
#添加一個txt文本附件
with open('abc.txt','r')as h:
    content2 = h.read()
#設置txt參數
part2 = MIMEText(content2,'plain','utf-8')
#附件設置內容類型,方便起見,設置爲二進制流
part2['Content-Type'] = 'application/octet-stream'
#設置附件頭,添加文件名
part2['Content-Disposition'] = 'attachment;filename="abc.txt"'
#添加照片附件
with open('1.png','rb')as fp:
    picture = MIMEImage(fp.read())
    #與txt文件設置類似
    picture['Content-Type'] = 'application/octet-stream'
    picture['Content-Disposition'] = 'attachment;filename="1.png"'
#將內容附加到郵件主體中
message.attach(part1)
message.attach(part2)
message.attach(picture)

#登陸併發送
try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host,25)
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(
        sender,receivers,message.as_string())
    print('success')
    smtpObj.quit()
except smtplib.SMTPException as e:
    print('error',e)

6.小結

經過上面的代碼,想必你們已經對發郵件有了基本的認識。

從總體上咱們要把握整個過程的思路:

  1. 登陸
  2. 寫郵件
  3. 發送

微觀上咱們須要瞭解:

  • smtplib/email 模塊的代碼規則;
  • 何時使用 SMTP,何時使用 SMTP_SSL?
  • 針對不一樣的郵件內容須要使用到不一樣的類,MIMEmultipart、MIMEText、MIMEIamge 等等;
  • 怎麼去設置附件信息

固然,看再多教程,不如親自動手寫一段代碼。你們不妨都本身發一封郵件試一試。

在公衆號(crossincode)中回覆『email』,能夠獲取實例代碼。

其餘文章及回答:

Python 與 Excel 不得不說的事 - Crossin的編程教室 - 知乎專欄

Python-Excel 模塊哪家強?- Crossin的編程教室 - 知乎專欄

爆款遊戲《貪吃蛇大做戰》的 Python 實現 - Crossin的編程教室 - 知乎專欄

NBA 舉辦編程馬拉松 - 數據分析時代的到來 - Crossin的文章 - 知乎專欄

想用 Python 作數據分析?先玩玩這個再說 - Crossin的文章 - 知乎專欄

用 Python 實現你的量化交易策略 - Crossin的文章 - 知乎專欄

學習編程的過程當中可能會走哪些彎路,有哪些經驗能夠參考? - Crossin 的回答

你是如何自學 Python 的? - Crossin 的回答

Python 抓取網頁亂碼緣由分析 - Crossin的編程教室 - 知乎專欄

Crossin的編程教室

微信ID:crossincode

論壇:Crossin的編程教室

相關文章
相關標籤/搜索