python使用smtp库发送邮件

来源:互联网 发布:linux桌面进入命令行 编辑:程序博客网 时间:2024/06/05 02:46

python smtp发邮件

开发一个日志扫描工具,用于扫描报错日志,并打包成邮件,发送到邮箱。
例子:

#!/usr/bin/env python  # coding=utf-8  from smtplib import SMTP  from email import MIMEText  from email import Header  from os.path import getsize  from sys import exit  from re import compile, IGNORECASE  #定义主机 帐号 密码 收件人 邮件主题  smtpserver = '10.0.10.191'  user = 'cxyblog'  password = '*******'  sender = 'cxyblog@163.com'  receiver = ('xiaozi@163.com','收件人',)  subject = u'Web服务器Tomcat日志错误信息'  From = u'xxx Web服务器'  To = u'服务器管理员'    #发送邮件函数  def send_mail(error):      #定义邮件的头部信息      header = Header.Header      msg = MIMEText.MIMEText(error,'plain','utf-8')      msg['From'] = header(From)      msg['To'] = header(To)      msg['Subject'] = header(subject+'')      #连接SMTP服务器,然后发送信息      smtp = SMTP(smtpserver)      smtp.login(user, password)      smtp.sendmail(sender, receiver, msg.as_string())      smtp.close()        send_mail("hi hello")  

代码使用说明:
1,user和password在调用163等邮箱时,user是自己的邮箱,senser也是自己的邮箱。
2,在公司内部邮件系统中,这个login的user,可能是其他的账户。sender,才是你自己的邮箱。

 

这段程序测试是通不过的,不过下面这个程序貌似更好.

  1. #!/usr/bin/env python   
  2. # coding:utf-8   
  3. import email   
  4. import smtplib   
  5. class Mailer:   
  6.     def __init__(self, smtp_host, smtp_user, smtp_passwd, smtp_port = 25) :   
  7.         self.smtp_host = smtp_host   
  8.         self.smtp_user = smtp_user   
  9.         self.smtp_passwd = smtp_passwd   
  10.         self.smtp_port = smtp_port   
  11.         self.mail = email.MIMEMultipart.MIMEMultipart('related')   
  12.         self.alter = email.MIMEMultipart.MIMEMultipart('alternative')   
  13.         self.mail.attach(self.alter)   
  14.         self.attachments = []   
  15.     def mailfrom(self, mail_from) :   
  16.         self._from = mail_from   
  17.         self.mail['from'] = mail_from   
  18.     def mailto(self, mail_to) :   
  19.         """  
  20.         mail_to : comma separated emails  
  21.         """  
  22.         self._to = mail_to   
  23.         if type(mail_to) == list:   
  24.             self.mail['to'] = ','.join(mail_to)   
  25.         elif type(mail_to) == str :   
  26.             self.mail['to'] = mail_to   
  27.         else :   
  28.             raise Exception('invalid mail to')   
  29.     def mailsubject(self, mail_subject) :   
  30.         self.mail['subject'] = mail_subject   
  31.     def text_body(self, body, encoding = 'utf-8') :   
  32.         self.alter.attach(email.MIMEText.MIMEText(body, 'plain', encoding))   
  33.     def html_body(self, body, encoding = 'utf-8') :   
  34.         self.alter.attach(email.MIMEText.MIMEText(body, 'html', encoding))   
  35.     def addattach(self, filepath, mime_type = 'octect-stream', rename = None) :   
  36.         import os   
  37.         f = open(filepath, 'rb')   
  38.         filecontent = f.read()   
  39.         f.close()   
  40.         mb = email.MIMEBase.MIMEBase('application', mime_type)   
  41.         mb.set_payload(filecontent)   
  42.         email.Encoders.encode_base64(mb)   
  43.         fn = os.path.basename(filepath)   
  44.         mb.add_header('Content-Disposition''attachment', filename = rename or fn)   
  45.         self.mail.attach(mb)   
  46.     def send(self):   
  47.         self.mail['Date'] = email.Utils.formatdate( )   
  48.         smtp = False  
  49.         try:   
  50.             smtp = smtplib.SMTP()   
  51.             smtp.set_debuglevel(1)   
  52.             smtp.connect(self.smtp_host, self.smtp_port)   
  53.             smtp.login(self.smtp_user, self.smtp_passwd)   
  54.             smtp.sendmail(self._from, self._to, self.mail.as_string())   
  55.             return  True  
  56.         except Exception, e:   
  57.             import traceback   
  58.             print traceback.format_exc()   
  59.             return False  
  60.         #finally :   
  61.         smtp and smtp.quit()   
  62. def get_mailer() :   
  63.     mailer = Mailer(, , )#smtp,user,pwd   
  64.     mailer.mailfrom('')#from email  
  65.     return mailer   
  66. if __name__ == '__main__':   
  67.     mailer = get_mailer()   
  68.        
  69.     import sys   
  70.     #mailto = sys.argv[1]   
  71.     #subject = sys.argv[2]   
  72.     #body = sys.stdin.read()   
  73.     #mailer.mailto(mailto)   
  74.     #mailer.mailsubject(subject)   
  75.     #mailer.html_body(body)   
  76.     #if len(sys.argv) == 4 :   
  77.     #    mailer.addattach(sys.argv[3])   
  78.     #mailer.send()   
  79.        
  80.     mailto = 'so@gmail.com'  
  81.     subject = 'Daily Report'  
  82.     body = 'Hello'  
  83.     mailer.mailto(mailto)   
  84.     mailer.mailsubject(subject)   
  85.     mailer.html_body(body)   
  86.     #if len(sys.argv) == 4 :   
  87.     mailer.addattach('318110214911a041c0ed077f0.xls')   
  88.     mailer.send()  



这部分程序在发送向126,gmail的时候是成功的。但是公司连接的是国外的VPN,再连接的smtp

一下是debug的内容
connect: (************, 25)-----hostname
connect: (***********, 25)------ip
reply: '220 *********************************************************\r\n'
reply: retcode (220); Msg: *********************************************************
connect: *********************************************************
send: 'ehlo [**********]\r\n'
reply: '250-************ Hello [*********]\r\n'
reply: '250-SIZE 29360128\r\n'
reply: '250-PIPELINING\r\n'
reply: '250-DSN\r\n'
reply: '250-ENHANCEDSTATUSCODES\r\n'
reply: '250-XXXXXXXA\r\n'
reply: '250-AUTH\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-BINARYMIME\r\n'
reply: '250 XXXXXXXB\r\n'
reply: retcode (250); Msg: ************************
SIZE 29360128
PIPELINING
DSN
ENHANCEDSTATUSCODES
XXXXXXXA
AUTH
8BITMIME
BINARYMIME
XXXXXXXB
Traceback (most recent call last):
  File "C:\Users\Desktop\Send_6lisa.py", line 53, in send
    smtp.login(self.smtp_user, self.smtp_passwd)
  File "F:\Python25\lib\smtplib.py", line 587, in login
    if code == 334:
SMTPException: No suitable authentication method found.

参考网址:http://u.cxyblog.com/14/article-aid-304.html

按照网上说的方法对smtplib.py进行了修改,如下

       AUTH_PLAIN = "PLAIN"  
  1.         AUTH_CRAM_MD5 = "CRAM-MD5"  
  2.         AUTH_LOGIN = "LOGIN"  
  3.   
  4.         if self.helo_resp is None and self.ehlo_resp is None:   
  5.             if not (200 <= self.ehlo()[0] <= 299):   
  6.                 (code, resp) = self.helo()   
  7.                 if not (200 <= code <= 299):   
  8.                     raise SMTPHeloError(code, resp)   
  9.   
  10.         if not self.has_extn("auth"):   
  11.             raise SMTPException("SMTP AUTH extension not supported by server.")   
  12.   
  13.         # Authentication methods the server supports:  
  14.         authlist = self.esmtp_features["auth"].split()   
  15.   
  16.         # List of authentication methods we support: from preferred to  
  17.         # less preferred methods. Except for the purpose of testing the weaker  
  18.         # ones, we prefer stronger methods like CRAM-MD5:  
  19.         #preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN]  
  20.         preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]# add LOGIN   
  21.         #preferred_auths = [AUTH_PLAIN, AUTH_CRAM_MD5]  
  22.   
  23.         # Determine the authentication method we'll use  
  24.         authmethod = None  
  25.         for method in preferred_auths:   
  26.             if method in authlist:   
  27.                 authmethod = method   
  28.                 break  
  29. [color=red]            if '='+method in authlist:   
  30.                     authmethod = method   
  31.                     break # 本来这个部分不用加,但是我那个邮件服务器返回的是 auth=LOGIN,多了一个'=',所以我就加了这一段[/color]  
  32.         if self.debuglevel > 0:   
  33.             print "AuthMethod:", authmethod   
  34.         if authmethod == AUTH_CRAM_MD5:   
  35.             (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)   
  36.             if code == 503:   
  37.                 # 503 == 'Error: already authenticated'  
  38.                 return (code, resp)   
  39.             (code, resp) = self.docmd(encode_cram_md5(resp, user, password))   
  40.         elif authmethod == AUTH_PLAIN:   
  41.             (code, resp) = self.docmd("AUTH",   
  42.                 AUTH_PLAIN + " " + encode_plain(user, password))   
  43.          
  44. # 主要就是下面这一段了             
  45. [color=red]       elif authmethod == AUTH_LOGIN:   
  46.             (code, resp) = self.docmd("AUTH", AUTH_LOGIN)   
  47.             if code == 334:   
  48.                 (code, resp) = self.docmd(base64.encodestring(user)[:-1])   
  49.                 if code == 334:   
  50.                     (code, resp) = self.docmd(base64.encodestring(password)[:-1])   [/color]       
  51.        elif authmethod == None:   
  52.             raise SMTPException("No suitable authentication method found.")   
  53.         if code not in [235503]:   
  54.             # 235 == 'Authentication successful'  
  55.             # 503 == 'Error: already authenticated'  
  56.             raise SMTPAuthenticationError(code, resp)   
  57.         return (code, resp)  



但是还是报的同样的错误。我同时也把发成功的debug打印的出来,发现是在AUTH的时候gmail,和126都会有一个AUTH_type=LOGIN
但是国外的邮件server却返回的是NONE

我就是不清楚这个auth_type在server端是怎么配置的,还有什么其他的方法可以发邮件的吗?谢谢!

 

参考网址:http://www.iteye.com/problems/50919

0 0
原创粉丝点击