Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

python - Embed picture in email

I currently have a program that will randomly select quotes from a list and email them. I'm now trying to embed an image in the email as well. I've come across a problem where I can attach the email but my quotes no longer work. I have researched online and the solutions are not working for me. Note that I am using Python 3.2.2.

Any guidance would be appreciated.

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

attachment = 'bob.jpg' 

msg = MIMEMultipart()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject_header

#msgText = MIMEText(<b>%s</b><br><img src="cid:bob.jpg"><br>, 'html') % body

fp = open(attachment, 'rb')
img = MIMEImage(fp.read())
fp.close()

msg.attach(img)

#email_message = '%s
%s
%s' % (subject_header, body, img)
email_message = '%s
%s' % (subject_header, body)

emailRezi = smtplib.SMTP(mail_server, mail_server_port)
emailRezi.set_debuglevel(1)
emailRezi.login(mail_username, mail_password)
emailRezi.sendmail(from_addr, to_addr, email_message)
#emailRezi.sendmail(from_addr, to_addr, msg.as_string())
emailRezi.quit()

As you can tell from the code above I've tried different ways (referencing the #)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are going through royal pains to construct a valid MIME message in msg, then ditching it and sending a simple string email_message instead.

You should probably begin by understanding what the proper MIME structure looks like. A multipart message by itself has no contents at all, you have to add a text part if you want a text part.

The following is an edit of your script with the missing pieces added. I have not attempted to send the resulting message. However, see below for a modernized version.

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText  # Added
from email.mime.image import MIMEImage

attachment = 'bob.jpg'

msg = MIMEMultipart()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject

msgText = MIMEText('<b>%s</b><br/><img src="cid:%s"/><br/>' % (body, attachment), 'html')   
msg.attach(msgText)   # Added, and edited the previous line

with open(attachment, 'rb') as fp:
    img = MIMEImage(fp.read())
img.add_header('Content-ID', '<{}>'.format(attachment))
msg.attach(img)

print(msg.as_string()) # or go ahead and send it

(I also cleaned up the HTML slightly.)

Since Python 3.6, Python's email library has been upgraded to be more modular, logical, and orthogonal (technically since 3.3 already really, but in 3.6 the new version became the preferred one). New code should avoid the explicit creation of individual MIME parts like in the above code, and probably look more something like

from email.message import EmailMessage
from email.utils import make_msgid

attachment = 'bob.jpg'

msg = EmailMessage()
msg["To"] = to_addr
msg["From"] = from_addr
msg["Subject"] = subject

attachment_cid = make_msgid()

msg.set_content('<b>%s</b><br/><img src="cid:%s"/><br/>' % (body, attachment_cid), 'html')

with open(attachment, 'rb') as fp:
    msg.add_related(
        fp.read(), 'image', 'jpeg', cid=attachment_cid)

# print(msg.as_string()), or go ahead and send

You'll notice that this is quite similar to the "asparagus" example from the email examples documentation in the Python standard library.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...