Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python向Gmail发送带有内联图像的电子邮件_Python_Image_Email_Gmail_Mime - Fatal编程技术网

使用Python向Gmail发送带有内联图像的电子邮件

使用Python向Gmail发送带有内联图像的电子邮件,python,image,email,gmail,mime,Python,Image,Email,Gmail,Mime,我的目标是使用Python向具有内联图像的Gmail用户发送电子邮件。由于图像(我工作中的数据)的敏感性,无法在线托管此图像,然后通过href链接到它 我尝试将base64版本编码为HTML,然后发送该HTML,但众所周知,这不起作用。然后我注意到,在Gmail中,你可以将一个图像拖放到发送框中,它将在接收端内联显示。考虑到这一点,我尝试从Python发送一封电子邮件,并将图像作为附件。这可以在下面的代码中看到,但不幸的是,该图像没有内联显示 我的问题是:如何发送图像,使其以内联方式显示? im

我的目标是使用Python向具有内联图像的Gmail用户发送电子邮件。由于图像(我工作中的数据)的敏感性,无法在线托管此图像,然后通过
href
链接到它

我尝试将
base64
版本编码为
HTML
,然后发送该
HTML
,但众所周知,这不起作用。然后我注意到,在Gmail中,你可以将一个图像拖放到发送框中,它将在接收端内联显示。考虑到这一点,我尝试从Python发送一封电子邮件,并将图像作为附件。这可以在下面的代码中看到,但不幸的是,该图像没有内联显示

我的问题是:如何发送图像,使其以内联方式显示?

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os

gmail_user = "user1@gmail.com"
gmail_pwd = "pass"

to = "user2@gmail.com"
subject = "Report"
text = "Picture report"
attach = 'TESTING.png'

msg = MIMEMultipart()

msg['From'] = gmail_user
msg['To'] = to
msg['Subject'] = subject

msg.attach(MIMEText(text))

part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
   'attachment; filename="%s"' % os.path.basename(attach))
msg.attach(part)

mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
# Should be mailServer.quit(), but that crashes...
mailServer.close()
当我手动向自己发送内联图像时,“原始电子邮件”是这样的:

  Content-Type: multipart/related; boundary=047d7bd761fe73e03304e7e02237

--047d7bd761fe73e03304e7e02237
Content-Type: multipart/alternative; boundary=047d7bd761fe73e03004e7e02236

--047d7bd761fe73e03004e7e02236
Content-Type: text/plain; charset=ISO-8859-1

[image: Inline images 1]

--047d7bd761fe73e03004e7e02236
Content-Type: text/html; charset=ISO-8859-1

<div dir="ltr"><img alt="Inline images 1" src="cid:ii_141810ee4ae92ac6" height="400" width="534"><br></div>

--047d7bd761fe73e03004e7e02236--
--047d7bd761fe73e03304e7e02237
Content-Type: image/png; name="Testing.png"
Content-Transfer-Encoding: base64
Content-ID: <ii_141810ee4ae92ac6>
X-Attachment-Id: ii_141810ee4ae92ac6

我认为您需要添加以下行:

from email.mime.image import MIMEImage

body = MIMEText('<p>Test Image<img src="cid:testimage" /></p>', _subtype='html')
msg.attach(body)


img = MIMEImage(image.read(), 'jpeg')
img.add_header('Content-Id', '<testimage>')
msg.attach(img)
从email.mime.image导入MIMEImage
body=MIMEText(“测试图像”

”,_subtype='html') 附加信息(正文) img=mimimage(image.read(),'jpeg') img.add_标题('Content-Id','') 附加消息(img)

testimage
应替换为唯一标识符

似乎遵循gmail电子邮件模板是可行的:

* multipart/alternative
  - text/plain
  - multipart/related
    + text/html
      <img src="cid:msgid"/>
    + image/png
      Content-ID: <msgid>
要通过gmail发送
msg

import smtplib
import ssl

with smtplib.SMTP('smtp.gmail.com', timeout=10) as s:
    s.starttls(context=ssl.create_default_context())
    s.login(gmail_user, gmail_password)
    s.send_message(msg)
import ssl

s = SMTP_SSL('smtp.gmail.com', timeout=10,
             ssl_kwargs=dict(cert_reqs=ssl.CERT_REQUIRED,
                             ssl_version=ssl.PROTOCOL_TLSv1,
                             # http://curl.haxx.se/ca/cacert.pem
                             ca_certs='cacert.pem')) 
s.set_debuglevel(0)
try:
    s.login(gmail_user, gmail_pwd)
    s.sendmail(msg['From'], [to], msg.as_string())
finally:
    s.quit()
Python 2/3兼容版本
SMTP\u SSL
是可选的,您可以使用问题中的
starttls
方法:

import smtplib
import socket
import ssl
import sys

class SMTP_SSL(smtplib.SMTP_SSL):
    """Add support for additional ssl options."""
    def __init__(self, host, port=0, **kwargs):
        self.ssl_kwargs = kwargs.pop('ssl_kwargs', {})
        self.ssl_kwargs['keyfile'] = kwargs.pop('keyfile', None)
        self.ssl_kwargs['certfile'] = kwargs.pop('certfile', None)
        smtplib.SMTP_SSL.__init__(self, host, port, **kwargs)

    def _get_socket(self, host, port, timeout):
        if self.debuglevel > 0:
            print>>sys.stderr, 'connect:', (host, port)
        new_socket = socket.create_connection((host, port), timeout)
        new_socket = ssl.wrap_socket(new_socket, **self.ssl_kwargs)
        self.file = getattr(smtplib, 'SSLFakeFile', lambda x: None)(new_socket)
        return new_socket

如何在与图像相同的电子邮件中添加文本?请看代码中的MimeText调用:它们在第一个参数中添加纯文本和HTML正文。你可以在那里写任何你喜欢的东西(你缺少一个
导入操作系统
)@ABM:你看到顶部的
#-*-编码:utf-8-*-
了吗?(该代码在Python2和python3上都与
“…”
一起工作)使用python3版本的代码,我收到了邮件,但图像没有显示,我只收到了备用的。还有其他人有这个问题吗?我知道我来晚了,但是我为类似的东西建立了一个简单的邮件类,因为我自己需要时不时地使用它
* multipart/related
  - multipart/alternative
    + text/plain
    + text/html
      <div dir="ltr"><img src="cid:ii_xyz" alt="..."><br></div>
  - image/jpeg
    Content-ID: <ii_xyz>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cgi
import uuid
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text      import MIMEText
from email.mime.image     import MIMEImage
from email.header         import Header    

img = dict(title=u'Picture report…', path=u'TESTING.png', cid=str(uuid.uuid4()))

msg = MIMEMultipart('related')
msg['Subject'] = Header(u'Report…', 'utf-8')
msg['From'] = gmail_user
msg['To'] = ", ".join([to])
msg_alternative = MIMEMultipart('alternative')
msg.attach(msg_alternative)
msg_text = MIMEText(u'[image: {title}]'.format(**img), 'plain', 'utf-8')
msg_alternative.attach(msg_text)

msg_html = MIMEText(u'<div dir="ltr">'
                     '<img src="cid:{cid}" alt="{alt}"><br></div>'
                    .format(alt=cgi.escape(img['title'], quote=True), **img),
                    'html', 'utf-8')
msg_alternative.attach(msg_html)

with open(img['path'], 'rb') as file:
    msg_image = MIMEImage(file.read(), name=os.path.basename(img['path']))
    msg.attach(msg_image)
msg_image.add_header('Content-ID', '<{}>'.format(img['cid']))
import ssl

s = SMTP_SSL('smtp.gmail.com', timeout=10,
             ssl_kwargs=dict(cert_reqs=ssl.CERT_REQUIRED,
                             ssl_version=ssl.PROTOCOL_TLSv1,
                             # http://curl.haxx.se/ca/cacert.pem
                             ca_certs='cacert.pem')) 
s.set_debuglevel(0)
try:
    s.login(gmail_user, gmail_pwd)
    s.sendmail(msg['From'], [to], msg.as_string())
finally:
    s.quit()
import smtplib
import socket
import ssl
import sys

class SMTP_SSL(smtplib.SMTP_SSL):
    """Add support for additional ssl options."""
    def __init__(self, host, port=0, **kwargs):
        self.ssl_kwargs = kwargs.pop('ssl_kwargs', {})
        self.ssl_kwargs['keyfile'] = kwargs.pop('keyfile', None)
        self.ssl_kwargs['certfile'] = kwargs.pop('certfile', None)
        smtplib.SMTP_SSL.__init__(self, host, port, **kwargs)

    def _get_socket(self, host, port, timeout):
        if self.debuglevel > 0:
            print>>sys.stderr, 'connect:', (host, port)
        new_socket = socket.create_connection((host, port), timeout)
        new_socket = ssl.wrap_socket(new_socket, **self.ssl_kwargs)
        self.file = getattr(smtplib, 'SSLFakeFile', lambda x: None)(new_socket)
        return new_socket