Python 发送邮件时 TypeError: 预期字符串或缓冲区

6 投票
2 回答
9349 浏览
提问于 2025-04-17 11:56

大家好,我在网上找了很久,还是没找到答案。我试过很多建议,但就是无法让它工作。我想用Python(smtplib和email模块)通过Gmail发送一封邮件。以下是我导入的包:

import time, math, urllib2, urllib, os, shutil, zipfile, smtplib, sys
from email.mime.text import MIMEText

这是我用来发送邮件的函数定义:

def sendmessage():
print('== You are now sending an email to Hoxie. Please write your username below. ==')
mcusername = str(raw_input('>> Username: '))
print('>> Now your message.')
message = str(raw_input('>> Message: '))
print('>> Attempting connection to email host...')
fromaddr = 'x@gmail.com'
toaddrs = 'xx@gmail.com'
username = 'x@gmail.com'
password = '1013513403'
server = smtplib.SMTP('smtp.gmail.com:587')
subject = 'Email from',mcusername
content = message
msg = MIMEText(content)
msg['From'] = fromaddr
msg['To'] = toaddrs
msg['Subject'] = subject
try:
    server.ehlo()
    server.starttls()
    server.ehlo()
except:
    print('!! Could not connect to email host! Check internet connection! !!')
    os.system('pause')
    main()
else:
    print('>> Connected to email host! Attempting secure login via SMTP...')
    try:
        server.login(username,password)
    except:
        print('!! Could not secure connection! Stopping! !!')
        os.system('pause')
        main()
    else:
        print('>> Login succeeded! Attempting to send message...')
        try:
            server.sendmail(fromaddr, toaddrs, msg)
        except TypeError as e:
            print e
            print('Error!:', sys.exc_info()[0])
            print('!! Could not send message! Check internet connection! !!')
            os.system('pause')
            main()
        else:
            server.quit()
            print('>> Message successfully sent! I will respond as soon as possible!')
            os.system('pause')
            main()

我已经尽力调试,结果是这样的:

>> Login succeeded! Attempting to send message...
TypeError: expected string or buffer

这意味着我成功登录了,但在尝试发送消息时就停下来了。让我困惑的是,它没有指出具体哪里出错。另外,我的代码可能写得不太好,所以请不要网络暴力。

任何帮助都会非常感激!谢谢。

2 个回答

7

出错的那一行是

server.sendmail(fromaddr, toaddrs, msg)

你给它传了两个字符串和一个MIMEText实例,但它想要的是一个字符串格式的消息。[我觉得它还想要地址以列表的形式传入,不过它对一个字符串有特殊处理。] 比如,你可以看看文档中的例子

s = smtplib.SMTP('localhost')
s.sendmail(me, [you], msg.as_string())
s.quit()

你需要把MIMEText转换成字符串,这样sendmail才能正常工作。在修复了@jdi提到的主题错误(这个错误会产生“AttributeError: 'tuple' object has no attribute 'lstrip'”的提示)并把msg改成msg.as_string()后,你的代码就能正常运行了。

3

我猜问题出在这一行:

subject = 'Email from',mcusername

如果你想把subject创建为一个字符串,但实际上它被变成了一个元组,因为你传入了两个值。你可能想做的是:

subject = 'Email from %s' % mcusername

另外,关于调试的部分……你把所有的异常都包裹起来,只打印异常信息,这样就丢掉了有用的错误追踪信息(如果有的话)。你有没有试过在你真正知道要处理的具体异常之前,不要把所有的内容都包裹起来?这样笼统地处理异常会让调试变得更困难,尤其是当你有语法错误的时候。

撰写回答