【问题标题】:unable to send mail in python无法在python中发送邮件
【发布时间】:2018-07-17 03:44:28
【问题描述】:

我正在尝试使用email 模块将一堆照片发送到我的电子邮件地址。但是当我运行我的程序时,什么都没有发生。我无法弄清楚我的程序出了什么问题。我该如何解决这个问题?

Python 代码:

import os
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

fromadd = 'fromadd@gmail.com'
toadd = 'toadd@gmail.com'

def send():
    msg = MIMEMultipart()

    msg['From'] = fromadd
    msg['To'] = toadd
    msg['Subject'] = 'Photos'

    text = MIMEText('Pics')
    msg.attach(text)

    screenshot_data = open(files, 'rb').read()
    webcam_data = open(files, 'rb').read()

    send_image = MIMEImage(screenshot_data, name=os.path.basename(files))
    send_images = MIMEImage(webcam_data, name=os.path.basename(files))

    msg.attach(send_image)
    msg.attach(send_images)

    sessions = smtplib.SMTP('smtp.gmail.com', '587')
    sessions.ehlo()
    sessions.starttls()
    sessions.ehlo()
    sessions.login(fromadd, 'Password')
    sessions.sendmail(fromadd, toadd, msg.as_string())
    sessions.quit()


def main():

    global files

    for files in os.listdir(r'C:\NONE'):

        if os.path.isfile(files) and files.endswith(".jpg"):
            send()
            print('File Sent: ' + files) 
            os.remove(files)

    else:
        pass

 if __name__ == '__main__':
     main()

【问题讨论】:

  • 附带说明:您为什么将files 设为全局变量,而不是将其作为参数传递给send?另外,为什么用一个变量来表示单个文件名 files 而不是 filefilename
  • 这不是您将参数传递给函数的方式。删除 global files 并将 files 变量(顺便考虑将其重命名为单数名词)传递给您的 send() 函数。
  • 不管怎样,你确定你确实有直接在C:\NONE 目录中以.jpg 结尾的文件吗?因为如果是这样,print 应该打印出一些东西。如果什么都没有打印出来,要么你那里没有任何文件,要么main中的逻辑有问题;由于从未调用过send,因此您要询问的错误不能在send 中。 (当然,你也可能有错误,但如果你连那一步都做不到,那也无所谓了。)
  • 我认为 files 只能在 main 函数中访问,所以我为文件声明了全局变量。我只是在我的程序中调用了 ** files** 变量来简化程序
  • 是的,我在 C:\NONE 目录中有以 .jpg 结尾的文件。我在主函数中调用了发送。我仍然无法发送邮件。 -- abarnert

标签: python windows python-2.7 email


【解决方案1】:

os.listdir() 只返回文件名,而不是完整路径。因此,除非您在c:\NONE 中运行此程序,或者只是碰巧在当前工作目录中有一个同名文件,否则os.path.isfile(files) 将返回False,因此永远不会调用send()

即使它不是特定于 Python 的——其中的许多具体技巧并不适用——你可能希望阅读 Eric Lippert 的 How To Debug Small Programs。还要记住 Brian Kernighan 的建议:

最有效的调试工具 还是仔细想了想,再加上 明智地放置打印语句。

-- “Unix 初学者”(1979 年)

直接解决方法是将os.path.join() 目录名放在前面;但你也确实需要摆脱全局变量。

import os
import smtplib
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart

fromadd = 'fromadd@gmail.com'
toadd = 'toadd@gmail.com'

def send(pathname, froma, toa):
    msg = MIMEMultipart()

    msg['From'] = froma
    msg['To'] = toa
    msg['Subject'] = 'Photos'

    text = MIMEText('Pics')
    msg.attach(text)

    # Should really close() when done!
    screenshot_data = open(pathname, 'rb').read()
    webcam_data = open(pathname, 'rb').read()

    screenshot_image = MIMEImage(screenshot_data, name=os.path.basename(pathname))
    webcam_image = MIMEImage(webcam_data, name=os.path.basename(pathname))

    msg.attach(screenshot_image)
    msg.attach(webcam_image)

    session = smtplib.SMTP('smtp.gmail.com', '587')
    session.ehlo()
    session.starttls()
    session.ehlo()
    session.login(froma, 'Password')
    session.sendmail(froma, toa, msg.as_string())
    session.quit()

def main():
    for basename in os.listdir(r'C:\NONE'):
        filename = os.path.join([r'C:\NONE', basename])
        # switch order of conditions for minor efficiency hack
        if filename.endswith(".jpg") and os.path.isfile(filename):
            send(filename, fromadd, toadd)
            print('File Sent: ' + filename) 
            os.remove(filename)
        # empty else not required

 if __name__ == '__main__':
     main()

还请注意我如何重命名几个变量以避免在单数实例上使用复数,并希望通过使用公共前缀更好地连接相关变量。

目前还不清楚为什么要为每张图片发送两份副本,或者为什么要在没有任何有用的内容的情况下创建文本部分。您可能还希望根据其文档中的建议避免使用旧的 sendmail 方法。为什么要为每张照片创建单独的消息?将所有照片附加到一封电子邮件肯定会更实用(除非图片绝对巨大,并且邮件对于您的邮件服务器来说太大了;但无论如何,电子邮件肯定是错误的工具)。

从根本上说,您不应该在 2018 年使用 Python 2 编写新代码;顺便说一句,在 3.6+ 中经过大修的 email 库会更直接一些(尽管它仍然是低级和古怪的)。

【讨论】:

  • then email is the wrong tool for this anyway 是什么意思?有没有其他方法可以同时发送大量图片?
  • 将它们上传到文件共享站点并发送链接。
猜你喜欢
  • 2020-01-31
  • 2016-09-16
  • 1970-01-01
  • 2016-04-09
  • 2021-12-05
  • 2017-10-06
  • 2020-01-04
  • 2013-05-01
  • 2014-10-21
相关资源
最近更新 更多