1. 程式人生 > >Python模組探祕之二: Smtplib傳送帶有各種附件的郵件

Python模組探祕之二: Smtplib傳送帶有各種附件的郵件

轉自:http://blog.csdn.net/marksinoberg/article/details/51506308

這兩天對Python的郵件模組比較感興趣,於是就查了查資料。同時在實際的編碼過程中也遇到了各種各樣的問題。下面我就來分享一下我與smtplib的故事。

前提條件

我的上一篇博文裡面講解了,傳送郵件必須的條件。這裡同樣是適用的。大致就是要開啟郵箱的SMPT/POP服務等等。如果不明白,可以看看傳送純文字郵件。裡面講的還不錯。 :-)

核心知識點

因為今天主要講解的是如何傳送帶有附件的郵件,那麼核心肯定是附件了。怎麼才能發附件呢?

其實我們換個思路,就不難理解了。因為我們傳送郵件,經過了應用層–>> 傳輸層–>> 網路層–>>資料鏈路層–>>物理層。這一系列的步驟,全都變成了位元流了。所以無論是純文字,圖片,亦或是其他型別的檔案。在位元流的面前,都是平等的。所以我們傳送附件,也是按照發送純文字的模式來做就行,只不過加上一些特殊的標記即可。

\# 首先是xlsx型別的附件
xlsxpart = MIMEApplication(open('test.xlsx', 'rb').read())
xlsxpart.add_header('Content-Disposition', 'attachment', filename='test.xlsx')
msg.attach(xlsxpart)

\# jpg型別的附件
jpgpart = MIMEApplication(open('beauty.jpg', 'rb').read())
jpgpart.add_header('Content-Disposition', 'attachment', filename='beauty.jpg')
msg.attach(jpgpart)

\# mp3型別的附件
mp3part = MIMEApplication(open('kenny.mp3', 'rb').read())
mp3part.add_header('Content-Disposition', 'attachment', filename='benny.mp3')
msg.attach(mp3part)
經過這三小段的程式碼,想必你已經很清楚了吧。無非就是使用MIMEApplication進行包裝一下,然後設定一下內容。最後新增到郵件內容。就是這幾步,就搞定了。

完整的程式碼

# coding:utf-8

#    __author__ = 'Mark sinoberg'
#    __date__ = '2016/5/26'
#    __Desc__ = 實現傳送帶有各種附件型別的郵件

import urllib, urllib2
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication

username = '
[email protected]
' password = 'XXXXXXXX' sender = username receivers = ','.join(['[email protected]']) # 如名字所示: Multipart就是多個部分 msg = MIMEMultipart() msg['Subject'] = 'Python mail Test' msg['From'] = sender msg['To'] = receivers # 下面是文字部分,也就是純文字 puretext = MIMEText('我是純文字部分,') msg.attach(puretext) # 下面是附件部分 ,這裡分為了好幾個型別 # 首先是xlsx型別的附件 xlsxpart = MIMEApplication(open('test.xlsx', 'rb').read()) xlsxpart.add_header('Content-Disposition', 'attachment', filename='test.xlsx') msg.attach(xlsxpart) # jpg型別的附件 jpgpart = MIMEApplication(open('beauty.jpg', 'rb').read()) jpgpart.add_header('Content-Disposition', 'attachment', filename='beauty.jpg') msg.attach(jpgpart) # mp3型別的附件 mp3part = MIMEApplication(open('kenny.mp3', 'rb').read()) mp3part.add_header('Content-Disposition', 'attachment', filename='benny.mp3') msg.attach(mp3part) ## 下面開始真正的傳送郵件了 try: client = smtplib.SMTP() client.connect('smtp.163.com') client.login(username, password) client.sendmail(sender, receivers, msg.as_string()) client.quit() print '帶有各種附件的郵件傳送成功!' except smtplib.SMTPRecipientsRefused: print 'Recipient refused' except smtplib.SMTPAuthenticationError: print 'Auth error' except smtplib.SMTPSenderRefused: print 'Sender refused' except smtplib.SMTPException,e: print e.message

驗證結果

沒有什麼比來張圖片更有說服力的了。如圖 
帶有各種附件的郵件結果圖

錯誤總結

我遇到的錯誤如下:

<code class="hljs tex has-numbering" style="box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; padding: 0px; color: inherit; border-radius: 0px; white-space: pre; display: block; word-wrap: normal; background: transparent;">D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\python</span>.exe E:/Code/Python/MyTestSet/mail/withappedix.py
Traceback (most recent call last):
  File "E:/Code/Python/MyTestSet/mail/withappedix.py", line 51, in <module>
    client.sendmail(sender, receivers, msg.as_string())
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\message</span>.py", line 137, in as_string
    g.flatten(self, unixfrom=unixfrom)
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\generator</span>.py", line 83, in flatten
    self._write(msg)
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\generator</span>.py", line 115, in _write
    self._write_headers(msg)
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\generator</span>.py", line 164, in _write_headers
    v, maxlinelen=self._maxheaderlen, header_name=h).encode()
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\header</span>.py", line 410, in encode
    value = self._encode_chunks(newchunks, maxlinelen)
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\header</span>.py", line 370, in _encode_chunks
    _max_append(chunks, s, maxlinelen, extra)
  File "D:<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Software</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\Python</span>2<span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\lib</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\email</span><span class="hljs-command" style="box-sizing: border-box; color: rgb(0, 0, 136);">\quoprimime</span>.py", line 97, in _max_append
    L.append(s.lstrip())
AttributeError: 'list' object has no attribute 'lstrip'

Process finished with exit code 1
</code><ul class="pre-numbering" style="box-sizing: border-box; margin: 0px; position: absolute; width: 50px; top: 0px; left: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul><ul class="pre-numbering" style="box-sizing: border-box; margin: 0px; position: absolute; width: 50px; top: 0px; left: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

我的解決辦法是 
receiver parameter was list type. either it should be list converted to string using join method or if it is a single recipient, then pass it as a 

string only

是的,就是receivers = ','.join(['[email protected]'])。這樣就搞定了。

也許,你遇到的錯誤不是我這個,那麼也不用擔心,我這裡有一份比較齊全的錯誤碼對照表。你可以對照著你的錯誤碼來查詢具體的錯誤原因。這樣有的放矢,效率會更高一點的。

在編碼的過程中,我也是遇到了很多意想不到的錯誤。而這些錯誤的錯誤碼對我們來說是很有用的。這對我們測試程式碼以及找到其中出錯的原因和有幫助。