Tôi muốn viết chương trình gửi email bằng cách sử dụng smtplib của Python. Tôi đã tìm kiếm thông qua tài liệu và RFC, nhưng không thể tìm thấy bất kỳ thứ gì liên quan đến tệp đính kèm. Vì vậy, tôi chắc chắn có một số khái niệm cấp cao hơn tôi đang bỏ lỡ. Ai đó có thể gợi ý cho tôi về cách các tệp đính kèm hoạt động trong SMTP không?Làm cách nào để gửi tệp đính kèm bằng SMTP?
Trả lời
Điều bạn muốn kiểm tra là mô-đun email
. Nó cho phép bạn xây dựng các thông báo MIME -compliant mà bạn gửi với smtplib.
Cảm ơn bạn đã chỉnh sửa, bạn đã nhanh hơn một chút so với I ;-) –
Vâng, tệp đính kèm không được xử lý theo bất kỳ cách đặc biệt nào, chúng chỉ là "lá" của cây đối tượng Tin nhắn. Bạn có thể tìm thấy câu trả lời cho bất kỳ câu hỏi nào về các mesasges tuân thủ MIME trong phần this của tài liệu trên gói python email.
Nói chung, bất kỳ loại tệp đính kèm nào (đọc: dữ liệu nhị phân thô) có thể được biểu diễn bằng cách sử dụng base64 (hoặc tương tự) Content-Transfer-Encoding
.
Đây là một ví dụ tôi đã loại bỏ một ứng dụng công việc mà chúng tôi đã làm. Nó tạo ra một email HTML với một tập tin đính kèm Excel.
import smtplib,email,email.encoders,email.mime.text,email.mime.base
smtpserver = 'localhost'
to = ['[email protected]']
fromAddr = '[email protected]'
subject = "my subject"
# create html email
html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
html +='<body style="font-size:12px;font-family:Verdana"><p>...</p>'
html += "</body></html>"
emailMsg = email.MIMEMultipart.MIMEMultipart('alternative')
emailMsg['Subject'] = subject
emailMsg['From'] = fromAddr
emailMsg['To'] = ', '.join(to)
emailMsg['Cc'] = ", ".join(cc)
emailMsg.attach(email.mime.text.MIMEText(html,'html'))
# now attach the file
fileMsg = email.mime.base.MIMEBase('application','vnd.ms-excel')
fileMsg.set_payload(file('exelFile.xls').read())
email.encoders.encode_base64(fileMsg)
fileMsg.add_header('Content-Disposition','attachment;filename=anExcelFile.xls')
emailMsg.attach(fileMsg)
# send email
server = smtplib.SMTP(smtpserver)
server.sendmail(fromAddr,to,emailMsg.as_string())
server.quit()
Loại phụ nhiều nên được 'trộn' thay vì 'thay thế' nếu không bạn sẽ không thấy tệp đính kèm trong một số ứng dụng email. – rhyek
Dưới đây là cách gửi e-mail kèm theo tệp đính kèm zip và chủ đề được mã hóa utf-8 + body.
Nó không phải là đơn giản để con số này ra, do thiếu tài liệu và mẫu cho trường hợp cụ thể này.
Các ký tự không phải ascii trong thư trả lời cần được mã hóa, ví dụ: ISO-8859-1. Có thể tồn tại một chức năng có thể làm điều này.
Mẹo:
Gửi cho chính bạn một e-mail, lưu và kiểm tra nội dung để tìm ra cách thực hiện tương tự trong Python.
Dưới đây là đoạn code, cho Python 3:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:set ts=4 sw=4 et:
from os.path import basename
from smtplib import SMTP
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.utils import parseaddr, formataddr
from base64 import encodebytes
def send_email(recipients=["[email protected]"],
subject="Test subject æøå",
body="Test body æøå",
zipfiles=[],
server="smtp.somewhere.xyz",
username="bob",
password="password123",
sender="Bob <[email protected]>",
replyto="=?ISO-8859-1?Q?M=F8=F8=F8?= <[email protected]>"): #: bool
"""Sends an e-mail"""
to = ",".join(recipients)
charset = "utf-8"
# Testing if body can be encoded with the charset
try:
body.encode(charset)
except UnicodeEncodeError:
print("Could not encode " + body + " as " + charset + ".")
return False
# Split real name (which is optional) and email address parts
sender_name, sender_addr = parseaddr(sender)
replyto_name, replyto_addr = parseaddr(replyto)
sender_name = str(Header(sender_name, charset))
replyto_name = str(Header(replyto_name, charset))
# Create the message ('plain' stands for Content-Type: text/plain)
try:
msgtext = MIMEText(body.encode(charset), 'plain', charset)
except TypeError:
print("MIMEText fail")
return False
msg = MIMEMultipart()
msg['From'] = formataddr((sender_name, sender_addr))
msg['To'] = to #formataddr((recipient_name, recipient_addr))
msg['Reply-to'] = formataddr((replyto_name, replyto_addr))
msg['Subject'] = Header(subject, charset)
msg.attach(msgtext)
for zipfile in zipfiles:
part = MIMEBase('application', "zip")
b = open(zipfile, "rb").read()
# Convert from bytes to a base64-encoded ascii string
bs = encodebytes(b).decode()
# Add the ascii-string to the payload
part.set_payload(bs)
# Tell the e-mail client that we're using base 64
part.add_header('Content-Transfer-Encoding', 'base64')
part.add_header('Content-Disposition', 'attachment; filename="%s"' %
os.path.basename(zipfile))
msg.attach(part)
s = SMTP()
try:
s.connect(server)
except:
print("Could not connect to smtp server: " + server)
return False
if username:
s.login(username, password)
print("Sending the e-mail")
s.sendmail(sender, recipients, msg.as_string())
s.quit()
return True
def main():
send_email()
if __name__ == "__main__":
main()
Dưới đây là một ví dụ về một tin nhắn với một tập tin đính kèm PDF, một văn bản "cơ thể" và gửi qua Gmail.
# Import smtplib for the actual sending function
import smtplib
# For guessing MIME type
import mimetypes
# Import the email modules we'll need
import email
import email.mime.application
# Create a text/plain message
msg = email.mime.Multipart.MIMEMultipart()
msg['Subject'] = 'Greetings'
msg['From'] = '[email protected]'
msg['To'] = '[email protected]'
# The main body is just another attachment
body = email.mime.Text.MIMEText("""Hello, how are you? I am fine.
This is a rather nice letter, don't you think?""")
msg.attach(body)
# PDF attachment
filename='simple-table.pdf'
fp=open(filename,'rb')
att = email.mime.application.MIMEApplication(fp.read(),_subtype="pdf")
fp.close()
att.add_header('Content-Disposition','attachment',filename=filename)
msg.attach(att)
# send via Gmail server
# NOTE: my ISP, Centurylink, seems to be automatically rewriting
# port 25 packets to be port 587 and it is trashing port 587 packets.
# So, I use the default port 25, but I authenticate.
s = smtplib.SMTP('smtp.gmail.com')
s.starttls()
s.login('[email protected]','xyzpassword')
s.sendmail('[email protected]',['[email protected]'], msg.as_string())
s.quit()
Điều này đã giải quyết được vấn đề của tôi đối với việc gửi email các tệp excel, điều này thật tuyệt vời vì nó đã giúp tôi thoát khỏi os.system gọi Ruby! Cảm ơn Kevin! – Benjooster
Giải pháp này cũng làm việc cho tôi, sau khi tạo tệp .xls bằng mô-đun Python xlwt. Thay vì gửi qua Gmail, tôi đã sử dụng máy chủ thư của công ty mình. Cảm ơn và +1 –
phương pháp này thực sự hiệu quả và sạch hơn nhiều! –
# -*- coding: utf-8 -*-
"""
Mail sender
"""
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import pystache
import codecs
import time
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
HOST = 'smtp.exmail.qq.com'
PORT = 587
USER = '[email protected]'
PASS = 'yourpass'
FROM = '[email protected]'
SUBJECT = 'subject'
HTML_NAME = 'tpl.html'
CSV_NAME = 'list.txt'
FAILED_LIST = []
def send(mail_receiver, mail_to):
# text = mail_text
html = render(mail_receiver)
# msg = MIMEMultipart('alternative')
msg = MIMEMultipart('mixed')
msg['From'] = FROM
msg['To'] = mail_to.encode()
msg['Subject'] = SUBJECT.encode()
# msg.attach(MIMEText(text, 'plain', 'utf-8'))
msg.attach(MIMEText(html, 'html', 'utf-8'))
try:
_sender = smtplib.SMTP(
HOST,
PORT
)
_sender.starttls()
_sender.login(USER, PASS)
_sender.sendmail(FROM, mail_to, msg.as_string())
_sender.quit()
print "Success"
except smtplib.SMTPException, e:
print e
FAILED_LIST.append(mail_receiver + ',' + mail_to)
def render(name):
_tpl = codecs.open(
'./html/' + HTML_NAME,
'r',
'utf-8'
)
_html_string = _tpl.read()
return pystache.render(_html_string, {
'receiver': name
})
def main():
ls = open('./csv/' + CSV_NAME, 'r')
mail_list = ls.read().split('\r')
for _receiver in mail_list:
_tmp = _receiver.split(',')
print 'Mail: ' + _tmp[0] + ',' + _tmp[1]
time.sleep(20)
send(_tmp[0], _tmp[1])
print FAILED_LIST
main()
- 1. Làm cách nào để gửi email có tệp đính kèm bằng SmtpClient.SendAsync?
- 2. Tôi làm cách nào để gửi tệp đính kèm bằng email trong Racket?
- 3. Kích thước tệp đính kèm email tối đa với SMTP?
- 4. Gửi tệp đã tải lên dưới dạng tệp đính kèm
- 5. Cách gửi email có tệp đính kèm bằng API Windows Phone 7?
- 6. php gửi email html kèm theo tệp đính kèm .csv
- 7. Gửi email có tệp đính kèm Khách hàng Agnostic
- 8. Làm thế nào để gửi một tệp tin Django FileField dưới dạng tệp đính kèm?
- 9. Cách gửi email có tệp đính kèm trong số
- 10. Làm cách nào để thêm tệp đính kèm vào email bằng System.Net.Mail?
- 11. Cách gửi email có tệp đính kèm trong Android
- 12. xóa tệp đính kèm
- 13. Sử dụng SmtpClient để gửi tệp đính kèm
- 14. sendmailR (Part2): Gửi tệp dưới dạng tệp đính kèm thư
- 15. MacOSX: thư mới có tệp đính kèm
- 16. Gửi email có tệp đính kèm tệp PDF bằng cách sử dụng PHP
- 17. Cách đính kèm nhiều tệp vào một email bằng JavaMail?
- 18. Cách gửi email có tệp đính kèm bằng cách sử dụng GmailSender trong android
- 19. cách thêm tệp đính kèm trong PHPMailer?
- 20. gửi e-mail có nhiều tệp đính kèm
- 21. Gửi email có tệp đính kèm bằng cách sử dụng javamail API
- 22. Làm cách nào để lưu tệp đính kèm email vào máy chủ bằng PHP?
- 23. Cách gửi tệp zip dưới dạng tệp đính kèm trong python?
- 24. Gửi email có tệp đính kèm trong Ruby
- 25. gửi email có tệp đính kèm bằng cách sử dụng php
- 26. Mục đích Android: Gửi email có tệp đính kèm
- 27. Gửi email có tệp đính kèm trong django
- 28. tải xuống tệp đính kèm thư bằng Java
- 29. Tạo tệp đính kèm độc lập couchdb bằng cURL
- 30. Cách truy vấn số lượng tệp đính kèm từ trường Tệp đính kèm trong Microsoft Access?
Chỉ cần được rõ ràng, không có gì ở tất cả trong SMTP để xử lý này là, nó hoàn toàn xử lý bởi cơ cấu lại các tài liệu được gửi đi như một tài liệu MIME. Bài viết về MIME trên wikipedia dường như bao gồm các cơ bản khá tốt. – jcoder
Bao gồm liên kết trực tiếp đến phần "ví dụ email" của tài liệu Python sẽ làm cho mọi câu trả lời hoàn tất: http://docs.python.org/library/email-examples.html –