件制作不同于其他的页面制作,所以有些规范您还是得考虑的。
1.模板编码语言选择
模板编码设定与使用的发送软件有关,一般来说,utf-8为较常用的选择,错误 的编码会造成用户浏览的时候出现乱码。
2.对于HTML格式邮件的要求
包括空格在内,邮件标题的字符最好控制在35个字符。 文件大小(HTML和图片)最好控制在500KB以下。 电子邮件推荐宽度为850像素以内。鉴于现的浏览器普遍偏大,可根据设计的显 示效果自定义宽度,建议不要超过750像素。 不推荐使用最新的HTML版本,因为目前常用的浏览器有些是不支持最新的HTML 标签的,为了给用户更好的浏览效果,采用“老版本”HTML3.2、HTML4.0即可。
1.不要使用div,使用table定位
Div+css是近几年新兴的web2.0定位方式,这种 方式不适合在邮件模板切割中使用,不同邮件客 户端或在线浏览器对css模型解释不尽相同,甚 至部分ISP会直接屏蔽部分css样式,造成错位或 布局混乱等问题。
2.使用table布局时,不可重复多次colspan
不要使用单一table重复多次colspan,可能会被 邮件客户端判断为结构过于复杂,归类为垃圾邮 件;同时也容易被打乱布局而影响用户浏览。
<table> <tr>
<td><table> <tr>
<td> </td>
<td> </td> </tr>
</table></td> </tr>
<tr>
<td><table> <tr>
<td> </td> <td> </td> <td> </td>
</tr> </table></td>
</tr> <tr>
<td><table> <tr>
<td> </td>
<td> </td> </tr>
</table></td> </tr>
</table>
1.模板尽量不要使用背景图片
背景图片在某些邮件客户端或web界面(如 Gmail、OutLook) 中默认不显示,所以模板最好不要使用背景图片,建议使用 背景颜色。但邮件中是可以使用背景颜色的,大部分的邮件 客户端都是支持的。
2.每张图都要指定width宽度
每张图都要指定width宽度、height高度,在图片被拦截的时 候,不会因图片大小无法读 取而被打乱布局。
3.每张图都要指定alt属性
每张图都要指定alt属性,可以在图片被拦截的时候显示图片 的内容;这样客户打开邮件在没有点击下载图片的时候先是 可以看到文字的表述,知道此封邮件大概的内容,而提升用 户对此封邮件的体验,从而提高邮件的点击率并非像上图中 ,显示为空白,给用户带来不必要的困扰。
1. 图片链接不要使用<map>标签,因为部分邮件运营商 会屏蔽<map>标签,而导致图片无法点击。
2. 请使用英文字符对图片名称命名,不要使用中文、非法 字符来命名图片,否则会导致图片无法显示。
3. 在切割模板的时候,要注意限制图片的大小和数量,不要为 了效果使图片过大,会使邮件接收者打开过于缓慢,甚至直 接关闭邮件。
4.纯图片邮件图片于图片之前出现断行 ,目前很多公司的邮件都是使用大图片切图这种不规则的 ,经常出现下面的问题
解决方法:
<img src=http: // blog.54575.com/logo.gif” width=297′′ height=160′′ alt=”情人节特供” style="display:block;" />。
在每张图片后添加 style="display:block;" 此CSS即可。
1.不要使用外部样式表引用,将样式表 写入模板内部,因为大部分的ISP会 屏蔽css样式表 如:
2.padding和margin标签
table中,某些邮件客户端或web界面 (如Gmail), 对浮动的标签(padding 、margin等)支持很差,所以尽量不 要使用。
3.尽量不要使用<h2>、<ul>、<li>、 <p>、<ol>等有默认样式的标签。 防止style不被ISP正确解析时页面布 局混乱。
1. 可以使用简单的gif动画来表达某些需要明显突出的要素,但要控制gif文件的大 小,不要影响整封邮件的下载浏览速度; 但gif动画在OutLook 里是失效的。
2. 不要使用Flash、Java、Javascript、Frames,I-Frames、ActiveX、dynamic HTML等,前些年邮件病毒泛滥,大部分邮件运营商都已经屏蔽了这些元素
1
发送邮件
发送邮件使用SMTP协议【Simple Mail Transfer Protocol简单的邮件传输协议】,SMTP协议是SMTP客户端与SMTP服务器之间的通信协议。
python中发送邮件使用的模块有smtplib和email:
1.使用smtplib模块进行发送邮件;
2.使用email模块来添加发送的邮件内容。
导入模块:import smtplib
smtplib.SMTP
和smtplib.SMTP_SSL
:均可以用来创建SMTP对象;
smtplib.SMTP_SSL
:使用安全加密的SSL协议连接到SMTP服务器;
smtplib.SMTP
:没有进行安全加密。
故若待测试邮箱不允许使用非SSL和非TLS频道通信时,则无法使用smtp.SMTP方式来创建客户端对象。
【查看邮箱的通信方式:邮箱设置菜单中,查看邮箱的接收服务器和发送服务器信息。】
如:腾讯企业邮箱
接收服务器:
imap.exmail.qq.com(使用SSL,端口号993)
发送服务器:
smtp.exmail.qq.com(使用SSL,端口号465)
smtplib.SMTP(host,port,local_hostname,timeout,source_address)
smtplib.SMTP_SSL(host, port, local_hostname, keyfile, certfile, timeout, source_address, context)
创建SMTP对象。
host:SMTP发送服务器主机
port:SMTP服务器端口号
login(user, password, *, initial_response_ok=True)
SMTP对象登录
user:授权登录的用户名
password:授权登录的密码
sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])
SMTP对象发送邮件
from_addr:发件人地址,字符串类型。
to_addr:收件人地址,包括收件人和抄送人。
多个收件人时to_addr参数为列表,单个收件人时to_addr参数可以为列表或字符串。
msg:要发送的信息
quite终止SMTP会话
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import os
class EmailContent:
def __init__(self, senderAdr, emailSubject, toReceivers, ccReceivers):
# 邮件对象
self.msg = MIMEMultipart
# 添加发件人头
self.msg['From'] = Header("测试" + "<" + senderAdr + ">", 'utf-8')
# 添加收件人
if isinstance(toReceivers, str):
self.msg["To"] = toReceivers
elif isinstance(toReceivers, list):
self.msg['To'] = ";".join(toReceivers)
# 添加抄送人
if isinstance(ccReceivers, str):
self.msg["Cc"] = ccReceivers
elif isinstance(ccReceivers, list):
self.msg["Cc"] = ";".join(ccReceivers)
# 添加邮件主题
self.msg['Subject'] = Header(emailSubject, "utf-8")
def addBody(self, bodyType):
"""
添加不同的邮件正文的实例
1. body为字符串:(如)"这是一个邮件正文内容"
2. body为html格式的字符串:(如)"<div><p>第一段</p><p> 第二段</p></div>"
3. body正文中包含有图片:
"""
if bodyType == "string":
body = "这是一个邮件正文内容"
mimeText = MIMEText(body, "plain", "utf-8")
self.msg.attach(mimeText)
elif bodyType == "html":
body = "<div><p>第一段</p><p> 第二段</p></div>"
mimeText = MIMEText(body, "html", "utf-8")
self.msg.attach(mimeText)
elif "image" in bodyType:
imageFile = "E://log//test.png"
imageId = os.path.split(imageFile)[1]
# 添加内容
body = '''
<p>测试图片为:</p>
<p><img src="cid:{imageId}"></p>
'''.format(imageId=imageId)
mimeText = MIMEText(body, "html", "utf-8")
self.msg.attach(mimeText)
# 读取图片,并设置图片id用于邮件正文引用
with open(imageFile, "rb") as fp:
mimeImage = MIMEImage(fp.read)
mimeImage.add_header("Content-ID", imageId)
self.msg.attach(mimeImage)
def addAttachment(self, attachmentName):
"""
添加附件
:return:
"""
file = "E://log//test.txt"
# file = "E://log//test.zip"
# file = "E://log//test.png"
filePath, fileName = os.path.split(file)
print("fileName =", fileName)
enclosure = MIMEText(open(file, 'rb').read, 'base64', 'utf-8')
enclosure['Content-Type'] = 'application/octet-stream'
if attachmentName == "英文":
enclosure['Content-Disposition'] = 'attachment; filename="%s"' % fileName
elif attachmentName == "中文":
enclosure.add_header("Content-Disposition", "attachment", filename=("gbk", "", fileName))
self.msg.attach(enclosure)
import smtplib
def SendEmail:
"""发送邮件"""
# SMTP的服务器信息
smtpHost = "smtp.exmail.qq.com"
sslPort = 465
senderAdr = "xx@xx.cn"
senderPwd = "XXXX"
# 创建SMTP对象
smtpServer = smtplib.SMTP_SSL(smtpHost, sslPort)
# # 设置debug模块
# smtpServer.set_debuglevel(True)
# 登录
smtpServer.login(senderAdr, senderPwd)
# 添加邮件内容
toReceivers = ["a@xx.cn", "b@xx.cn"]
ccReceivers = ["d@xx.cn", "e@xx.cn"]
toAddrs = toReceivers + ccReceivers
emailSubject = "这是个编程技术圈自动发送的邮件"
emailContent = EmailContent(senderAdr, emailSubject, toReceivers, ccReceivers)
emailContent.addBody("html")
emailContent.addAttachment("英文")
message = emailContent.msg
# 发送
smtpServer.sendmail(senderAdr, toAddrs, message.as_string)
# 终止SMTP会话
smtpServer.quit
SendEmail
02
读取邮件
收取邮件使用POP3协议;
解析邮件:需要将收取的邮件转化为email.message.Message对象,再使用email模块解析内容。
import poplib
from email.parser import Parser
"""POP的服务器信息"""
popHost = "pop.exmail.qq.com"
userAdr = "xx@xx.cn"
userPwd = "xxxxx"
""" 创建POP3对象,添加用户名和密码"""
pop3Server = poplib.POP3(popHost)
pop3Server.user(userAdr)
pop3Server.pass_(userPwd)
"""获取邮件数量和占用空间"""
messageCount, mailboxSize = pop3Server.stat
"""获取邮件请求返回状态码、每封邮件的字节大小(b'第几封邮件 此邮件字节大小')、"""
response, msgNumOctets, octets = pop3Server.list
""" 获取任意一封邮件的邮件对象【第一封邮件的编号为1,而不是0】"""
msgIndex = random.randint(1,messageCount)
print(msgIndex)
# 获取第msgIndex封邮件的信息
response, msgLines, octets = pop3Server.retr(msgIndex)
# msgLines中为该邮件的每行数据,先将内容连接成字符串,再转化为email.message.Message对象
msgLinesToStr = b"\r\n".join(msgLines).decode("utf8", "ignore")
messageObject = Parser.parsestr(msgLinesToStr)
print(messageObject)
""" 终止POP3服务"""
pop3Server.quit
1.2. 解析邮件对象
1.2.1. 获取邮件日期
msgDate = messageObject["date"]
print(msgDate)
1.2.2. 获取邮件发件人实名、邮箱地址
获取邮件实名时,名称一般是加密的,此时就需要对头文件进行解码才可获取它的实际内容
from email.header import decode_header
def decodeMsgHeader(header):
"""
解码头文件
:param header: 需解码的内容
:return:
"""
value, charset = decode_header(header)[0]
if charset:
value = value.decode(charset)
return value
from email.utils import parseaddr
senderContent = messageObject["From"]
# parseaddr函数返回的是一个元组(realname, emailAddress)
senderRealName, senderAdr = parseaddr(senderContent)
# 将加密的名称进行解码
senderRealName = decodeMsgHeader(senderRealName)
print(senderRealName)
print(senderAdr)
1.2.3. 获取邮件主题
获取的邮件的主题也是加密的,此时就需要对头文件进行解码才可获取它的实际内容
msgHeader = messageObject["Subject"]
# 对头文件进行解码
msgHeader = decodeMsgHeader(msgHeader )
print(msgHeader)
1.2.4. 获取邮件正文
一封邮件的正文内容,可能是由几部分构成,每部分的格式不同。
"""获取邮件正文内容"""
msgBodyContents =
if messageObject.is_multipart: # 判断邮件是否由多个部分构成
messageParts = messageObject.get_payload # 获取邮件附载部分
for messagePart in messageParts:
bodyContent = decodeBody(messagePart)
if bodyContent:
msgBodyContents.append(bodyContent)
else:
bodyContent = decodeBody(messageObject)
if bodyContent:
messageBodyContents.append(bodyContent)
print(msgBodyContents)
def decodeBody(msgPart):
"""
解码内容
:param msgPart: 邮件某部分
"""
contentType = msgPart.get_content_type # 判断邮件内容的类型,text/html
textContent = ""
if contentType == 'text/plain' or contentType == 'text/html':
content = msgPart.get_payload(decode=True)
charset = msgPart.get_charset
if charset is None:
contentType = msgPart.get('Content-Type', '').lower
position = contentType.find('charset=')
if position >= 0:
charset = contentType[position + 8:].strip
if charset:
textContent = content.decode(charset)
return textContent
1.2.5. 获取邮件附件
邮件附件名为中文时,需借助头文件解码方式进行解码,否则会为乱码。
messageAttachments =
if messageObject.is_multipart: # 判断邮件是否由多个部分构成
messageParts = messageObject.get_payload # 获取邮件附载部分
for messagePart in messageParts:
name = messagePart.get_param("name") # 名字存在,则表示此部分为附件
if name:
fileName = decodeMsgHeader(name) # 解码
messageAttachments.append(fileName)
else:
name = messageObject.get_param("name")
if name:
fileName = decodeMsgHeader(name) # 解码
messageAttachments.append(fileName)
print(messageAttachments)
2. 读取邮件时遇到的问题
2.1. 提示“poplib.error_proto: line too long”
File "XXX/EmailInfo.py", line 22, in getMessageObject
return parser.Parser.parsestr(b"\n".join(self.popServer.retr(i)[1]).decode("utf8", "ignore"))
File "/usr/local/lib/python3.6/poplib.py", line 248, in retr
return self._longcmd('RETR %s' % which)
File "/usr/local/lib/python3.6/poplib.py", line 183, in _longcmd
return self._getlongresp
File "/usr/local/lib/python3.6/poplib.py", line 168, in _getlongresp
line, o = self._getline
File "/usr/local/lib/python3.6/poplib.py", line 130, in _getline
raise error_proto('line too long')
poplib.error_proto: line too long
POP3对行长度做了限制,默认为_MAXLINE = 2048,故若是邮件超过此长度就会提示“poplib.error_proto: line too long”。
解决方案:在读取邮件代码中重新定义最大行长度,即给poplib._MAXLINE设置新值。
import poplib
poplib._MAXLINE=20480
- end -
文专家:马国凯
1987年9月14日21时07分,北京计算机应用技术研究所发出了我国第一封电子邮件,邮件是发往德国卡尔斯鲁厄大学的,内容为“越过长城,走向世界”。那么电子邮件会不会失窃呢?
今天就让我们谈谈电子邮件会不会失窃呢?
我们发纸质信件的时候,有时会担心信件被别人偷走或信件内容被别人看到。通信是一件涉及隐私的事情,因此保密性很重要。那么瞬间就发到对方信箱的电子邮件也会被别人偷看吗?
电子邮件是在互联网上传输的一小段信息,互联网上传输的一切信息都存在被人偷看的可能,所以电子邮件并不是百分之百安全的。
想偷看他人邮件有两种方法,一是冒充他人的身份登录邮件服务器,查看邮件内容;二是通过侦听网络的方式截获传输中的电子邮件,得到电子邮件的副本。
针对第一种方法,你只需要保护好用户名和密码,不要让他人知道,就能避免别人冒充身份连接到邮件服务器,得到邮件内容。而第二种方法和邮件服务器的安全性有关,如果邮件服务器采取明文传输,窃听者就能通过监听服务器传输数据的方法破译出邮件内容;而如果邮件服务器采取密文传输,窃听者就无法通过破译得到邮件内容。
传输邮件的安全性就只有通过邮件服务器来保证了吗?
并非如此。你可以将要说的话保存在文件里,再通过加密软件将邮件内容加密,将加密后的邮件内容作为附件邮寄给收件人。只要通过其他方式告诉收件人密码,就可以保证邮件的安全性了,其他人无论用什么方法得到你的邮件,都只能看到一堆乱码,什么有效信息也得不到。
*请认真填写需求信息,我们会在24小时内与您取得联系。