基于python发送邮件的乱码问题的解决办法


Posted in PHP onApril 25, 2013

公司项目中需要通过后台发送邮件,邮件内容包括图片附件。如果通过PHPmailer发送,由于邮件服务器可能存在延迟现象,通过PHPmailer发送邮件,需要等待邮件发送成功后才能返回结果,这在实践中证明,有时发送邮件无法即时返回结果,影响用户体验。

于是我通过python发送邮件,PHP通过调用脚本方式来调用,这样执行脚本成功后立即返回,而无需判断邮件是否发送成功。只要成功执行脚本文件即向客户端返回成功标志。这样极大的提高了邮件发送速度,保证良好的用户体验效果。

但是,在通过python发送邮件,却遇到了乱码的问题。在调试过程中出现了以下现象:

1、中文与英文字母结合出现乱码。

2、回复邮件人的姓名两个汉字正常、但三个汉字就乱码。这个问题隐藏性强,我到今天才发现这个问题,害的在老板面前两次犯同样错误。因为我测试OK啊(我姓名两个字),就是没有测试三个字的情况,也没想到问题会出在这里。

3、邮件主题乱码

4、一切正常,但点击邮件“回复”时,出现的内容部分乱码。

5、内容问题解决后,发现回复的姓名也乱码。而且QQ邮箱正常、foxmail正常、163正常、gmail正常,但outlook乱码。

调用环境:

1、我在PHP中将回复人,回复邮箱,发送邮箱,文件名等做为脚本的参数,调用cmd命令的方便执行。而做为参数,有些字符是特殊字符。比如&符,单引号,双引号等问题。另外还有一个问题是每个参数间不能有空格。如果有空格,那么参数的顺序就打乱了。

总之,乱码问题一直无法完美解决。最后没有办法,采用下面方式,终于解决乱码问题。

在PHP中将发送邮件的内容,比如主题、回复姓名、邮箱、内容等等,写到配置文件中去,这个配置文件名是随机的,文件目录是在PHP的临时目录。确保多人使用的情况。然后在PHP中调用python脚本时传递配置文件名(含路径也可以),在python中通过读取该配置文件来处理。在这种情况下,主题和回复人,也就是涉及汉字部分在163中是乱码(目前内容部分没测,已经确定主题及回复人涉及汉字在163邮箱中出现乱码,但在QQ邮箱中没有乱码,一切正常),解决办法是通过Header("xxxx","utf-8")方式转为utf8后都正常。

下面分享一下相关代码:

PHP调用python脚本

//生成ini配置文件
$sampleData = array(
  'mail' => array(
    'subject' =>'hello,亲,你朋友给你发送的邮件-xxx有限公司转发',
    'ReplyToName' =>$send_name,
    'ReplyToMail' =>$send_email,
    'To' =>$receive_email,
    'file_name' =>realpath($target_path),
  )
);
$filename=getUnique().'.ini';
write_ini_file($sampleData,'D:/PHP/Php/tmp/'.$filename, true);
$cmd='start mmail.py '.$filename;
$r=exec($cmd,$out,$status);
if(!$status)
  echo 'ok'
else
  echo 'fail'

python发送邮件脚本
# -*- coding: utf-8 -*-
import smtplib
import email.MIMEMultipart# import MIMEMultipart
import email.MIMEText# import MIMEText
import email.MIMEBase# import MIMEBase
import os.path
import sys
from email.header import Header
import mimetypes
import email.MIMEImage# import MIMEImage
import ConfigParser
import string
inifile=u'D:/PHP/Php/tmp/' + sys.argv[1]
config=ConfigParser.ConfigParser()
config.read(inifile)
os.remove(inifile)
subject=Header(config.get("mail","subject"),"utf-8")
ReplyToName=config.get("mail","ReplyToName")
ReplyToMail=config.get("mail","ReplyToMail")
To=config.get("mail","To")
file_name=config.get("mail","file_name")
From = "%s<xxxxx@xxx.com>" % Header("xx科技","utf-8")
server = smtplib.SMTP("smtp.exmail.qq.com",25)
server.login("xxxx_business@5186.me","itop202") #仅smtp服务器需要验证时
# 构造MIMEMultipart对象做为根容器
main_msg = email.MIMEMultipart.MIMEMultipart()
# 构造MIMEText对象做为邮件显示内容并附加到根容器
text_msg = email.MIMEText.MIMEText("xxx帮你转发的邮件",_charset="utf-8")
main_msg.attach(text_msg)
# 构造MIMEBase对象做为文件附件内容并附加到根容器
ctype,encoding = mimetypes.guess_type(file_name)
if ctype is None or encoding is not None:
    ctype='application/octet-stream'
maintype,subtype = ctype.split('/',1)
file_msg=email.MIMEImage.MIMEImage(open(file_name,'rb').read(),subtype)
## 设置附件头
basename = os.path.basename(file_name)
file_msg.add_header('Content-Disposition','attachment', filename = basename)#修改邮件头
main_msg.attach(file_msg)
# 设置根容器属性
main_msg['From'] = From
if ReplyToMail!='none':
    main_msg['Reply-to'] = "%s<%s>" % (Header(ReplyToName,"utf-8"),ReplyToMail)
#main_msg['To'] = To
main_msg['Subject'] = subject
main_msg['Date'] = email.Utils.formatdate()
#main_msg['Bcc'] = To
# 得到格式化后的完整文本
fullText = main_msg.as_string()
# 用smtp发送邮件
try:
    server.sendmail(From, To.split(';'), fullText)
finally:
    server.quit()
    os.remove(file_name)

发送纯文本
text_msg = email.MIMEText.MIMEText("xxxx帮你转发的邮件",_charset="utf-8")
main_msg.attach(text_msg)

或者
content=config.get("mail","content")
content=Header(content,"utf-8")#如果加上这一句,邮件发不出去。其实下面这句已经对内容进行了编码处理。这一句就不要了。
text_msg = email.MIMEText.MIMEText(content,_charset="utf-8")
main_msg.attach(text_msg)

因此,对于主题、回复人涉及汉字的,要用Header("xxxx","utf-8")方式进行编码转换。至于内容,就不要用Header("xxxx","utf-8")重复转换了,否则会出现错误。
PHP 相关文章推荐
PHP编实现程动态图像的创建代码
Sep 28 PHP
mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
Apr 24 PHP
PHP HTML代码串 截取实现代码
Jun 29 PHP
PHP获取服务器端信息的方法
Nov 28 PHP
Laravel实现用户注册和登录
Jan 23 PHP
如何使用php等比例缩放图片
Oct 12 PHP
完美解决phpexcel导出到xls文件出现乱码的问题
Oct 29 PHP
Zend Framework入门教程之Zend_Config组件用法详解
Dec 09 PHP
在IIS下安装PHP扩展的方法(超简单)
Apr 10 PHP
PHP session垃圾回收机制实例分析
Jun 28 PHP
关于laravel-admin ueditor 集成并解决刷新的问题
Oct 21 PHP
实例化php类时传参的方法分析
Jun 05 PHP
关于php正则匹配汉字的方法介绍
Apr 25 #PHP
PHP中如何调用webservice的实例参考
Apr 25 #PHP
Php中用PDO查询Mysql来避免SQL注入风险的方法
Apr 25 #PHP
php中防止SQL注入的最佳解决方法
Apr 25 #PHP
Apache下禁止php文件被直接访问的解决方案
Apr 25 #PHP
PHP笔记之:日期函数的使用介绍
Apr 24 #PHP
php笔记之:AOP的应用
Apr 24 #PHP
You might like
php access 数据连接与读取保存编辑数据的实现代码
2010/05/12 PHP
PHP文件读写操作相关函数总结
2014/11/18 PHP
laravel 解决后端无法获取到前端Post过来的值问题
2019/10/22 PHP
yii框架结合charjs实现统计30天数据的方法
2020/04/04 PHP
javascript静态的url如何传递
2007/05/03 Javascript
jQuery的实现原理的模拟代码 -3 事件处理
2010/08/03 Javascript
javascript中onclick(this)用法介绍
2013/04/19 Javascript
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
浅谈JavaScript数据类型
2015/03/03 Javascript
Jquery1.9.1源码分析系列(十五)动画处理之外篇
2015/12/04 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
2016/11/22 Javascript
JS实现的二叉树算法完整实例
2017/04/06 Javascript
angular动态表单制作
2018/02/23 Javascript
NodeJS实现自定义流的方法
2018/08/01 NodeJs
整理 node-sass 安装失败的原因及解决办法(小结)
2020/02/19 Javascript
JavaScript进阶(三)闭包原理与用法详解
2020/05/09 Javascript
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
用python写asp详细讲解
2013/12/16 Python
Python基于time模块求程序运行时间的方法
2017/09/18 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
用pycharm开发django项目示例代码
2019/06/13 Python
基于python实现文件加密功能
2020/01/06 Python
Python环境管理virtualenv&amp;virtualenvwrapper的配置详解
2020/07/01 Python
HTML5的Geolocation地理位置定位API使用教程
2016/05/12 HTML / CSS
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
乐高奥地利官方商店:LEGO Shop AT
2019/07/16 全球购物
校长先进事迹材料
2014/02/01 职场文书
节能减耗标语
2014/06/21 职场文书
五四演讲稿范文
2014/09/03 职场文书
卖车协议书范例
2014/09/16 职场文书
拖欠货款起诉状
2015/05/20 职场文书
初中团委工作总结
2015/08/13 职场文书
子女赡养老人协议书
2016/03/23 职场文书
postgreSQL数据库基础知识介绍
2022/04/12 PostgreSQL