用python发送email问题
我懒得在你的代码里面找bug了
你看看我的吧,只是贴进百度空间的时候格式没有了,你稍微调整一下
http://hibaiducom/linuxbird/blog/item/a931ff60b74a224cebf8f8fchtml
可以明确的说Python的邮件模块没有问题,也不需要自己修改什么。
Python 邮件列表里面上次有人发了一个多线程的邮件群发脚本,也很不错。有兴趣可以搜索一下。
引用头文件
#!/usr/bin/env python
#--coding:utf-8--
import smtplib
import os
from emailmimetext import MIMEText
from emailmimemultipart import MIMEMultipart
from emailmimebase import MIMEBase
from email import encoders
创建“连接邮件服务器”函数
def smtp_connect( smtp_server, account, password, target ):
global smtp
global e_smtpserver
global e_account
global e_password
global e_target
global msg
e_smtpserver = smtp_server
e_account = account
e_password = password
e_target = target
try:
smtp = smtplibSMTP()
smtpconnect(e_smtpserver)
smtplogin(e_account, e_password)
except Exception, e:
print 'Mail connect failed: %s' % e
exit( -1 )
msg = MIMEMultipart('related')
创建“写邮件内容”函数
def smtp_set_content( subject, main_body ):
global msg
msg['Subject'] = subject
body = MIMEText( main_body, 'plain', 'utf-8' )
msgattach( body )
创建“添加附件”函数
def smtp_set_attachment( file_path ):
global msg
part = MIMEBase( 'application', 'octet-stream' )
partset_payload( open(file_path,'rb')read() )
encodersencode_base64(part)
partadd_header( 'Content-Disposition', 'attachment; filename=%s' % file_pathsplit('/')[-1] )
msgattach(part)
创建“发送邮件”函数
def smtp_send():
global smtp
global e_smtpserver
global e_account
global e_password
global e_target
global msg
try:
smtpsendmail( e_account, e_target, msgas_string() )
except Exception, e:
print 'Mail send Failed: %s' % e
exit( -1 )
使用示例
if __name__ == '__main__':
smtp_connect( 'smtpxxxxcomcn', 'xxxx@xxxxcomcn', 'password',
'xxxx@xxxxcomcn' )
smtp_set_content( 'Test subject', 'Test_content' )
smtp_set_attachment( osgetcwd() + '/mailpy' )
smtp_send()
python发送邮件的介绍比较多,都是需要登录某个邮件服务商,有密码修改和频繁发送被限制的问题。这里介绍一下,调用本机linux自身sendmail服务发送邮件。不需要登录,发送邮件名可以是任意名字,没有限制。
1 安装:
#yum install -y sendmail
2 启动服务:
#service sendmail start
检查服务是否加入自启行列
#chkconfig --list |grep sendmail
3 python代码:
from emailmimetext import MIMEText
from subprocess import Popen, PIPE
import commands
def send_mail(sender, recevier, subject, html_content):
msg = MIMEText(html_content, 'html', 'utf-8')
msg["From"] = sender
msg["To"] = recevier
msg["Subject"] = subject
p = Popen(["/usr/sbin/sendmail", "-t"], stdin=PIPE)
pcommunicate(msgas_string())
send_mail("sender@xxxxcom","receive1@xxxxcom,receive2@xxxxcom","title", “mail_text”)
sender@xxxcom可以是任意邮箱名
receive1@xxxxcom是收邮件的邮箱
title是邮件标题
mail_text是邮件内容
可以结合其他介绍python发邮件的资料,发出更复杂的邮件
原创:
失败原因可能有如下:1、主机与邮件服务器网络不通;2、邮件发送账号密码未设置或者设置不正确;3、python语法不正确
解决办法:1、主机与邮件服务器网络不通:需要保证主机可以正常访问外网,这样就可以访问到邮件服务器了。2、邮件账号密码未设置或者不正确:首先通过其他浏览器进行邮箱登陆验证,若可以正常登录说明邮箱账号正确,再根据你自己设置的邮箱账号配置文件的格式要求进行修改即可。3、python语法不正确,脚本编写完成之后可以执行如下命令进行语法校验:pyhton -c sendmailpy 这样就可以校验你的sendmailpy脚本的语法是否有问题,若有问题只需要根据提示定位到相应的行进行修正即可。
生成excel表格可以用pyExcelerator模块
类似
from pyExcelerator import
wb = Workbook()
ws = wbadd_sheet('Sheet1')
wswrite(0,0,'host')
wswrite(0,1,'asker')
wswrite(0,2,'head')
wswrite(0,3,'main')
wswrite(0,4,'time')
发送邮件可以用email模块,需要加附件
类似
from emailmimetext import MIMEText
from emailMIMEMultipart import MIMEMultipart
import emailMIMEText
import emailMIMEBase
sender = '307212@qqcom'#发件人地址
receiver = 'zhengla@cyccom'#收件人地址
smtpserver = 'smtpqqcom'#邮件服务器
username = '307212178'#用户名
password = 'aaaaaa111111'#密码
smtp = smtplibSMTP()
def send_email(msg,file_name):
msgRoot = MIMEMultipart()
msgRoot['Subject'] = 'DO not see it!!!!!'#邮件标题,这里我把标题设成了你所发的附件名
msgText = MIMEText('%s'%msg,'html','utf-8')#你所发的文字信息将以html形式呈现
msgRootattach(msgText)
att = MIMEText(open('%s'%file_name, 'rb')read(), 'base64', 'utf-8')#添加附件
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="%s"'%file_name
msgRootattach(att)
while 1:#持续尝试发送,直到发送成功
try:
smtpsendmail(sender, receiver, msgRootas_string())#发送邮件
break
except:
try:
smtpconnect(smtpserver)#连接至邮件服务器
smtplogin(username, password)#登录邮件服务器
except:
print "failed to login to smtp server"#登录失败
if __name__ == "__main__":
MSG="表格"#要发送的文字
FILE="C:\\Users\1txt"#要发送的文件
send_email(MSG,FILE)
里面的内容有删减,你可以自己添加删减
python互联网协议是什么?以下就是互联网访问协议的相关内容:
有许多模块可用于互联网访问协议和处理互联网协议。其中两个最简单的 urllibrequest 用于从URL检索数据,以及 smtplib 用于发送邮件:
>>>>>> from urllibrequest import urlopen
>>> with urlopen('http://tychousnonavymil/cgi-bin/timerpl') as response:
for line in response:
line = linedecode('utf-8') # Decoding the binary data to text
if 'EST' in line or 'EDT' in line: # look for Eastern Time
print(line)
Nov 25, 09:43:32 PM EST
>>> import smtplib
>>> server = smtplibSMTP('localhost')
>>> serversendmail('soothsayer@exampleorg', 'jcaesar@exampleorg',
"""To: jcaesar@exampleorg
From: soothsayer@exampleorg
Beware the Ides of March
""")
>>> serverquit()
python互联网协议是什么?(请注意,第二个示例需要在localhost上运行的邮件服务器。)
以上就是《python互联网协议是什么?掌握这个才算是会用python》的全部内容,Python是一种动态解释的、强类型定义语言:编写它时不需要定义变量类型,运行时变量类型被强制固定,如果你想知道更多的python的相关方法,可以点击本站的其他文章进行学习。
这篇文章主要介绍了在Python的Flask框架下收发电子邮件的教程,主要用到了Flask中的Flask-mail工具,需要的朋友可以参考下
在大多数此类教程中都会不遗余力的介绍如何使用数据库。今天我们对数据库暂且不表,而是来关注另一个在web应用中很重要的特性:如何推送邮件给用户。
在某个轻量级应用中我们可能会添加一个如下的邮件服务功能:当用户有了新的粉丝后,我们发送一封邮件通知用户。有很多方法可以实现这个特性,而我们希望提供出一种可复用的通用框架来处理。
Flask-Mail介绍
对于我们来说是幸运的,现在已经有很多外部插件来处理邮件,虽说不能百分百按照我们的想法去处理,但已经相当接近了。
在虚拟环境中安装 Flask-Mail是相当简单的。Windows以外的用户可以利用以下命令来安装:
1
flask/bin/pip install flask-mail
Windows用户的安装稍有不同,因为Flask-Mail所使用的一些模块不能再Windows系统上运行,你可以使用以下命令:
1
flaskScriptspip install --no-deps lamson chardet flask-mail
配置:
回想一下前文中单元测试部分的案例,我们通过添加配置支持了一个这样的功能:当应用的某个版本测试出错时可以邮件通知我们。从这个例子就可以看出如何配置使用邮件支持。
再次提醒大家,我们需要设置两个方面的内容:
邮件服务器信息
用户邮箱地址
如下正是前文中所用到的配置
# email server
MAIL_SERVER =
MAIL_PORT = 25
MAIL_USE_TLS = False
MAIL_USE_SSL = False
MAIL_USERNAME = you
MAIL_PASSWORD = your-password
# administrator list
ADMINS = [you@examplecom]
其中并没有设置切实可用的邮件服务器和邮箱。现在我们通过一个例子来看如何使用gmail邮箱账户来发送邮件:
# email server
MAIL_SERVER =
MAIL_PORT = 465
MAIL_USE_TLS = False
MAIL_USE_SSL = True
MAIL_USERNAME = your-gmail-username
MAIL_PASSWORD = your-gmail-password
# administrator list
ADMINS = [your-gmail-username@gmailcom]
另外我们也可以初始化一个Mail对象来连接SMTP邮件服务器,发送邮件:
1
2
from flaskextmail import Mail
mail = Mail(app)
发个邮件试试!
为了了解flask-mail如何工作的,我们可以从命令行发一封邮件看看。进入python shell并执行如下的脚本:
7
from flaskextmail import Message
from app import mail
from config import ADMINS
msg = Message(test subject, sender = ADMINS[0], recipients = ADMINS)
msgbody = text body
msghtml = bHTML/b body
mailsend(msg)
上面这段代码会根据inconfigpy中配置的邮箱地址列表,以首个邮箱作为发件人给所有邮箱发送一封邮件。邮件内容会以文本和html两种格式呈现,而你能看到哪种格式取决于你的邮件客户端。
多么简单小巧!你完全可以现在就把它集成到你的应用中。
邮件框架
我们现在可以编写一个帮助函数来发送邮件。这是以上测试中一个通用版的测试。我们把这个函数放进一个新的原文件中用作邮件支持(fileapp/emailspy):
7
8
from flaskextmail import Message
from app import mail
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender, recipients)
msgbody = text_body
msghtml = html_body
mailsend(msg)
Flask-Mail的邮件支持超出了我们目前的使用范围,像密件抄送和附件的功能并不会在此应用中得以使用。
Follower 提醒
现在,我们已经有了发邮件的基本框架,我们可以写发送follower提醒的函数了 (fileapp/emailspy):
11
from flask import render_template
from config import ADMINS
def follower_notification(followed, follower):
send_email([microblog] %s is now following you! % followernickname,
ADMINS[0],
[followedemail],
render_template(follower_emailtxt,
user = followed, follower = follower),
render_template(follower_emailhtml,
user = followed, follower = follower))
你在这里找到任何惊喜了吗我们的老朋友render_template函数有一次出现了。
如果你还记得,我们使用这个函数在views渲染模版 就像在views里写html不好一样,使用邮件模版是理想的选择。我们要可能的将逻辑和表现分开,所以email模版也会和其它试图模版一起放到在模版文件夹里
所以,我们需要为follower提醒邮件写纯文本和网页版的邮件模版,下面这个是纯文本的版本 (fileapp/templates/follower_emailtxt):
7
8
9
Dear {{usernickname}},
{{followernickname}} is now a follower Click on the following link to visit {{followernickname}}s profile page:
{{url_for(user, nickname = followernickname, _external = True)}}
Regards,
The microblog admin
下面这个是网页版的邮件,效果会更好(fileapp/templates/follower_emailhtml):
11
12
13
pDear {{usernickname}},/p
pa href={{url_for(user, nickname = followernickname, _external = True)}}{{followernickname}}/a is now a follower/p
table
tr valign=top
tdimg src={{followeravatar(50)}}/td
td
a href={{url_for(user, nickname = followernickname, _external = True)}}{{followernickname}}/abr /
{{followerabout_me}}
/td
/tr
/table
pRegards,/p
pThe codemicroblog/code admin/p
注解:模版中的url_for函数的 _external = True 参数的意义默认情况下,url_for 函数生成url是相对我们的域名的。例如,url_for(index)函数返回值是/index, 但是,发邮件是我们想要
最后一步是处理“follow”过程,即触发邮件提醒时的视图函数,(fileapp/viewspy):
7
8
9
from emails import follower_notification
@approute(/follow/nickname)
@login_required
def follow(nickname):
user = Userqueryfilter_by(nickname = nickname)first()
#
follower_notification(user, guser)
return redirect(url_for(user, nickname = nickname))
现在你可以创建两个用户(如果还没有用户的话)尝试着用让一个用户follow另一个用户,理解邮件提醒是怎样工作的。
就是这样吗我们做完了吗
我们可能心底里很兴奋完成了这项工作并且把邮件提醒功能同未完成列表里删除。
但是,如果你现在测试下应用,你会发现当你单击follow链接的时候,页面会2到3秒才会响应,浏览器才会刷新,这在之前是没有的。
发生了什么
问题是,Flask-Mail 使用同步模式发送电子邮件。 从电子邮件发送开始,直到电子邮件交付后,给浏览器发回其响应,在整个过程中,Web服务器会一直阻塞。如果我们试图发送电子邮件到一个服务器是缓慢的,甚至更糟糕的,暂时处于脱机状态,你能想象会发生什么吗很不好。
这是一个可怕的限制,发送电子邮件应该是后台任务且不会干扰Web服务器,让我们看看我们如何能够解决这个问题。
Python中执行异步调用
我们想send_email 函数发完邮件后立即返回,需要让发邮件移动到后台进程来异步执行。
事实上python已经对异步任务提供了支持,但实际上,还可以用其他的方式,比如线程和多进程模块也可以实现异步任务。
每当我们需要发邮件的时候,启动一个线程来处理,比启动一个全新的进程节省资源。所以,让我们将mailsend(msg)调用放到另一个线程中。(fileapp/emailspy):
11
from threading import Thread
def send_async_email(msg):
mailsend(msg)
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender = sender, recipients = recipients)
msgbody = text_body
msghtml = html_body
thr = threadingThread(target = send_async_email, args = [msg])
thrstart()
如果你测试‘follow‘函数,现在你会发现浏览器在发送邮件之前会刷新。
所以,我们已经实现了异步发送,但是,如果未来在别的需要异步功能的地方难道我们还需要在实现一遍吗
过程都是一样的,这样就会在每一种情况下都有重复代码,这样非常不好。
我们可以通过 decorator改进代码。使用装饰器的代码是这样的:
11
from decorators import async
@async
def send_async_email(msg):
mailsend(msg)
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender = sender, recipients = recipients)
msgbody = text_body
msghtml = html_body
send_async_email(msg)
更好了,对不对
实现这种方式的代码实际上很简单,创建一个新源文件(fileapp/decoratorspy):
7
from threading import Thread
def async(f):
def wrapper(args, kwargs):
thr = Thread(target = f, args = args, kwargs = kwargs)
thrstart()
return wrapper
现在我们对异步任务创建了个有用的框架(framework), 我们可以说已经完成了!
仅仅作为一个练习,让我们思考一下为什么这个方法会看上去使用了进程而不是线程。我们并不想每当我们需要发送一封邮件时就有一个进程被启动,所以我们能够使用thePoolclass而不用themultiprocessingmodule。这个类会创建指定数量的进程(这些都是主进程的子进程),并且这些子进程会通过theapply_asyncmethod送到进程池,等待接受任务去工作。这可能对于一个繁忙的网站会是一个有趣的途径,但是我们目前仍将维持现在线程的方式。
0条评论