2012-11-08 141 views
0

我試圖使用Gmail和Python中的smtplib模塊發送文本消息。Python:smtplib將新行添加到消息

的基本功能實現,並使用下面的代碼,我完全可以在我的手機收到這些短信:

server = smtplib.SMTP('smtp.gmail.com', 587) 
server.ehlo() 
server.starttls() 
server.login('email', 'password') 
server.sendmail('email', 'recipient', '\nhttp://apple.com') 

現在,它可能是一些實用的提我送一條鏈接。有人可能會問,爲什麼我在示例鏈接前插入了\n;顯然,沒有它,smtplib將鏈接處理爲標題,因此它會發送一條空消息。

然而,一個換行符被添加到我的消息,像這樣:

http://apple.com 
newline here 

我無法理解爲什麼這種情況發生:

  • 被添加的smtplib一個新行,因爲消息是一個鏈接?
  • 是因爲我收到短信作爲短信?
  • 是Gmail添加換行符?
+1

順便說一句,你可能想在那裏使用'['recipient']',而不僅僅是'recipient'。將單個字符串視爲一個元素列表有一個特殊的例外,但最好不要依賴它。 (如果我沒記錯的話,有一個版本的Python發送一個unicode而不是'str',這意味着你得到了一個unicode字符列表......) – abarnert

+0

謝謝,你是對的,它更安全。 – elliottbolzan

回答

2

參數不是消息體,而是整個消息。所以,它必須是一個有效的RFC(2)822消息。

截至the documentation末注云:

在一般情況下,你將要使用的電子郵件包的特徵來構建的電子郵件,然後你就可以轉換爲字符串,並通過sendmail的發();看電子郵件:例子。

然而,正上方的示例,演示如何生成一個簡單的消息自己:

# Add the From: and To: headers at the start! 
msg = ("From: %s\r\nTo: %s\r\n\r\n" 
     % (fromaddr, ", ".join(toaddrs))) 

如果你想知道什麼是有效的電子郵件信息,請參閱RFC 2822(也可能RFC 822,其中2822取而代之,但有一些有用的不同解釋和例子)。但簡短的版本是這樣的:它是一系列標題行,每行以\r\n結尾,後面跟着一個空行(意思是\r\n\r\n),後面跟着一個消息體。

因此,從技術上講,您的代碼甚至不應該工作,因爲它只有\n而不是\r\n前綴。

更重要的是,您發送的郵件根本沒有標題。甚至不包括你可能認爲你包括的From:To:。作爲the documentationsendmail說:

的from_addr和to_addrs參數被用於構建由傳輸代理使用的消息信封。 SMTP不以任何方式修改郵件標題。

這可能會也可能不會被各種服務器視爲無效(或垃圾郵件)。

同時,最後多餘的換行符是因爲所有行必須以\r\n結尾,並且SMTP是面向行的協議。如果消息沒有以換行符結束,那麼根本沒有辦法表示消息已經完成。

如果您想了解詳細信息,請參閱RFC2821,其中解釋了SMTP協議。尤其要看2.3.1郵件對象,2.3.7行和4.1.1.4數據(數據)。但簡短的版本是發送消息需要DATA命令,該命令必須以\r\n.\r\n結尾,並且「該終止序列的第一個也是結束數據的最後一行(消息文本)」。這意味着無法發送不以換行符結束的消息。

如果您真的想要,可以通過將您的正文封裝在MIME消息中來解決此問題; MIME消息本身當然會以換行符結束,但這不會影響您的封裝體。有幾種方法可以做到這一點 - 但是您需要收件人能夠處理您發送的任何內容,而且我猜測這些方式都不能用於電子郵件 - 短信網關(更不用說短信接收端點)。

+0

雖然我對此感到有些失望,但您的答案令人難以置信。非常感謝 ! – elliottbolzan

+0

@boopyman:是的,你可以從兩個字符的換行符,額外的空白,信封中重複出現的信息重複標題等等中發現,該電子郵件並不是圍繞140字節消息的想法設計的...... – abarnert

+0

是的,我絕對明白你的意思。但是,是否有Python發送短信的替代方法,可能不是通過電子郵件發送,不會添加換行符?這只是爲了美觀,但它仍然困擾着我;) – elliottbolzan