PHP调用Python快速发送高并发邮件
1 简介
在PHP中发送邮件,通常都是封装一个php的smtp邮件类来发送邮件。但是PHP底层的socket编程相对于Python来说效率是非常低的。CleverCode同时写过用python写的爬虫抓取网页,和用php写的爬虫抓取网页。发现虽然用了php的curl抓取网页,但是涉及到超时,多线程同时抓取等等。不得不说python在网络编程的效率要比PHP好的多。
PHP在发送邮件时候,自己写的smtp类,发送的效率和速度都比较低。特别是并发发送大量带有附件报表的邮件的时候。php的效率很低。建议可以使用php调用python的方式来发送邮件。
2 程序
2.1 python程序
php的程序和python的文件必须是相同的编码。如都是gbk编号,或者同时utf-8编码,否则容易出现乱码。python发送邮件主要使用了email模块。这里python文件和php文件都是gbk编码,发送的邮件标题内容与正文内容也是gbk编码。
- #!/usr/bin/python
- # -*- coding:gbk -*-
- """
- 邮件发送类
- """
- # mail.py
- #
- # Copyright (c) 2014 by http://blog.csdn.net/CleverCode
- #
- # modification history:
- # --------------------
- # 2014/8/15, by CleverCode, Create
- import threading
- import time
- import random
- from email.MIMEText import MIMEText
- from email.MIMEMultipart import MIMEMultipart
- from email.MIMEBase import MIMEBase
- from email import Utils, Encoders
- import mimetypes
- import sys
- import smtplib
- import socket
- import getopt
- import os
- class SendMail:
- def __init__(self,smtpServer,username,password):
- """
- smtpServer:smtp服务器,
- username:登录名,
- password:登录密码
- """
- self.smtpServer = smtpServer
- self.username = username
- self.password = password
- def genMsgInfo(self,fromAddress,toAddress,subject,content,fileList,\
- subtype = 'plain',charset = 'gb2312'):
- """
- 组合消息发送包
- fromAddress:发件人,
- toAddress:收件人,
- subject:标题,
- content:正文,
- fileList:附件,
- subtype:plain或者html
- charset:编码
- """
- msg = MIMEMultipart()
- msg['From'] = fromAddress
- msg['To'] = toAddress
- msg['Date'] = Utils.formatdate(localtime=1)
- msg['Message-ID'] = Utils.make_msgid()
- #标题
- if subject:
- msg['Subject'] = subject
- #内容
- if content:
- body = MIMEText(content,subtype,charset)
- msg.attach(body)
- #附件
- if fileList:
- listArr = fileList.split(',')
- for item in listArr:
- #文件是否存在
- if os.path.isfile(item) == False:
- continue
- att = MIMEText(open(item).read(), 'base64', 'gb2312')
- att["Content-Type"] = 'application/octet-stream'
- #这里的filename邮件中显示什么名字
- filename = os.path.basename(item)
- att["Content-Disposition"] = 'attachment; filename=' + filename
- msg.attach(att)
- return msg.as_string()
- def send(self,fromAddress,toAddress,subject = None,content = None,fileList = None,\
- subtype = 'plain',charset = 'gb2312'):
- """
- 邮件发送函数
- fromAddress:发件人,
- toAddress:收件人,
- subject:标题
- content:正文
- fileList:附件列表
- subtype:plain或者html
- charset:编码
- """
- try:
- server = smtplib.SMTP(self.smtpServer)
- #登录
- try:
- server.login(self.username,self.password)
- except smtplib.SMTPException,e:
- return "ERROR:Authentication failed:",e
- #发送邮件
- server.sendmail(fromAddress,toAddress.split(',') \
- ,self.genMsgInfo(fromAddress,toAddress,subject,content,fileList,subtype,charset))
- #退出
- server.quit()
- except (socket.gaierror,socket.error,socket.herror,smtplib.SMTPException),e:
- return "ERROR:Your mail send failed!",e
- return 'OK'
- def usage():
- """
- 使用帮助
- """
- print """Useage:%s [-h] -s <smtpServer> -u <username> -p <password> -f <fromAddress> -t <toAddress> [-S <subject> -c
- <content> -F <fileList>]
- Mandatory arguments to long options are mandatory for short options too.
- -s, --smtpServer= smpt.xxx.com.
- -u, --username= Login SMTP server username.
- -p, --password= Login SMTP server password.
- -f, --fromAddress= Sets the name of the "from" person (i.e., the envelope sender of the mail).
- -t, --toAddress= Addressee's address. -t "test@test.com,test1@test.com".
- -S, --subject= Mail subject.
- -c, --content= Mail message.-c "content, ......."
- -F, --fileList= Attachment file name.
- -h, --help Help documen.
- """ %sys.argv[0]
- def start():
- """
- """
- try:
- options,args = getopt.getopt(sys.argv[1:],"hs:u:p:f:t:S:c:F:","--help --smtpServer= --username= --password= --fromAddress= --toAddress= --subject= --content= --fileList=",)
- except getopt.GetoptError:
- usage()
- sys.exit(2)
- return
- smtpServer = None
- username = None
- password = None
- fromAddress = None
- toAddress = None
- subject = None
- content = None
- fileList = None
- #获取参数
- for name,value in options:
- if name in ("-h","--help"):
- usage()
- return
- if name in ("-s","--smtpServer"):
- smtpServer = value
- if name in ("-u","--username"):
- username = value
- if name in ("-p","--password"):
- password = value
- if name in ("-f","--fromAddress"):
- fromAddress = value
- if name in ("-t","--toAddress"):
- toAddress = value
- if name in ("-S","--subject"):
- subject = value
- if name in ("-c","--content"):
- content = value
- if name in ("-F","--fileList"):
- fileList = value
- if smtpServer == None or username == None or password == None:
- print 'smtpServer or username or password can not be empty!'
- sys.exit(3)
- mail = SendMail(smtpServer,username,password)
- ret = mail.send(fromAddress,toAddress,subject,content,fileList)
- if ret != 'OK':
- print ret
- sys.exit(4)
- print 'OK'
- return 'OK'
- if __name__ == '__main__':
- start()
2.2 python程序使用帮助
2.3 php程序
- <?php
- /**
- * SendMail.php
- *
- * 发送邮件类
- *
- * Copyright (c) 2015 by http://blog.csdn.net/CleverCode
- *
- * modification history:
- * --------------------
- * 2015/5/18, by CleverCode, Create
- *
- */
- class SendMail{
- /**
- * 发送邮件方法
- *
- * @param string $fromAddress 发件人,'clevercode@qq.com' 或者修改发件人名 'CleverCode<clevercode@qq.com>'
- * @param string $toAddress 收件人,多个收件人逗号分隔,'test1@qq.com,test2@qq.com,test3@qq.com....', 或者 'test1<test1@qq.com>,test2<test2@qq.com>,....'
- * @param string $subject 标题
- * @param string $content 正文
- * @param string $fileList 附件,附件必须是绝对路径,多个附件逗号分隔。'/data/test1.txt,/data/test2.tar.gz,...'
- * @return string 成功返回'OK',失败返回错误信息
- */
- public static function send($fromAddress, $toAddress, $subject = NULL, $content = NULL, $fileList = NULL){
- if (strlen($fromAddress) < 1 || strlen($toAddress) < 1) {
- return '$fromAddress or $toAddress can not be empty!';
- }
- // smtp服务器
- $smtpServer = 'smtp.qq.com';
- // 登录用户
- $username = 'clevercode@qq.com';
- // 登录密码
- $password = '123456';
- // 拼接命令字符串,实际是调用了/home/CleverCode/mail.py
- $cmd = "LANG=C && /usr/bin/python /home/CleverCode/mail.py";
- $cmd .= " -s '$smtpServer'";
- $cmd .= " -u '$username'";
- $cmd .= " -p '$password'";
- $cmd .= " -f '$fromAddress'";
- $cmd .= " -t '$toAddress'";
- if (isset($subject) && $subject != NULL) {
- $cmd .= " -S '$subject'";
- }
- if (isset($content) && $content != NULL) {
- $cmd .= " -c '$content'";
- }
- if (isset($fileList) && $fileList != NULL) {
- $cmd .= " -F '$fileList'";
- }
- // 执行命令
- exec($cmd, $out, $status);
- if ($status == 0) {
- return 'OK';
- } else {
- return "Error,Send Mail,$fromAddress,$toAddress,$subject,$content,$fileList ";
- }
- return 'OK';
- }
- }
2.3 使用样例
- <?php
- /**
- * test.php
- *
- * 压缩excel成附件,发送邮件
- *
- * Copyright (c) 2015 http://blog.csdn.net/CleverCode
- *
- * modification history:
- * --------------------
- * 2015/5/14, by CleverCode, Create
- *
- */
- include_once ('SendMail.php');
- /*
- * 客户端类
- * 让客户端和业务逻辑尽可能的分离,降低页面逻辑和业务逻辑算法的耦合,
- * 使业务逻辑的算法更具有可移植性
- */
- class Client{
- public function main(){
- // 发送者
- $fromAddress = 'CleverCode<clevercode@qq.com>';
- // 接收者
- $toAddress = 'all@qq.com';
- // 标题
- $subject = '这里是标题!';
- // 正文
- $content = "您好:\r\n";
- $content .= " 这里是正文\r\n ";
- // excel路径
- $filePath = dirname(__FILE__) . '/excel';
- $sdate = date('Y-m-d');
- $PreName = 'CleverCode_' . $sdate;
- // 文件名
- $fileName = $filePath . '/' . $PreName . '.xls';
- // 压缩excel文件
- $cmd = "cd $filePath && zip $PreName.zip $PreName.xls";
- exec($cmd, $out, $status);
- $fileList = $filePath . '/' . $PreName . '.zip';
- // 发送邮件(附件为压缩后的文件)
- $ret = SendMail::send($fromAddress, $toAddress, $subject, $content, $fileList);
- if ($ret != 'OK') {
- return $ret;
- }
- return 'OK';
- }
- }
- /**
- * 程序入口
- */
- function start(){
- $client = new Client();
- $client->main();
- }
- start();
- ?>

2.4 程序源码下载
PHP调用Python快速发送高并发邮件的更多相关文章
- python导出zabbix数据并发邮件脚本
Zabbix没有报表导出的功能,于是通过编写脚本导出zabbix数据并发邮件.效果如下: 下面是脚本,可根据自己的具体情况修改: #!/usr/bin/python #coding:utf-8 imp ...
- Python Tornado搭建高并发Restful API接口服务
Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快能实现高并发.得利于其 非阻塞的方式和对epoll的运用,Torn ...
- python 快速发送大量邮件
因为公司需求,需要发送千万封级别邮件. # coding:utf-8 import csv import smtplib from email.mime.text import MIMEText im ...
- 用Python控制摄像头拍照并发邮件
概述前言 工具 思路 安装及导入包 设置参数 实现拍照 构造邮件内容 发送邮件 判断网络连接 开机自启 后记 o1 前言为什么会有写这个程序的想法呢? 最初的想法是写一个可以用电脑前置摄像头拍照的程序 ...
- Python 实现发送、抄送邮件功能
发送邮件 问题 在web.py中,如何发送邮件? 解法 在web.py中使用web.sendmail()发送邮件. web.sendmail('cookbook@webpy.org', 'user@e ...
- Mac怎么快速创建便签和发送附件的邮件
1.如何快速创建便签 在Mac的任意界面选中文字:shift+command+y 就能创建便签2.如何快速发送附件的邮件(网页界面) 在Safari网页界面 command ...
- Python3+smtplib+poplib+imaplib实现发送和收取邮件(以qq邮箱为例)
一.说明 1.1 程序说明 (1)smtp是邮件发送协议:pop和imap都是邮件接收协议,两者的区别通常的说法是imap的操作会同步到邮箱服务器而pop不会,表现上我也不是很清楚 (2)本程序实现使 ...
- [记录]Python高并发编程
========== ==多进程== ========== 要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识. Unix/Linux操作系统提供了一个fo ...
- java调用html模板发送html内容的邮件
在项目需要发送邮件,普通内容的邮件觉得太单调.太丑,没逼格,所以说直接把用到的邮件内容做成一个html模板,发送之前将对应参数替换掉,发送html内容的高逼格邮件. 首先需要引用jar包,这就不多说了 ...
随机推荐
- HTML5开发移动web应用——SAP UI5篇(8)
本次对之前学习的SAP UI5框架知识进行简单小结.以及重点部分知识的梳理. 1.在UI5使用过程中,命名空间的概念非常重要. 2.一般的sap组件引用格式例如以下: sap.ui.define([ ...
- HDFS源码分析数据块复制之PendingReplicationBlocks
PendingReplicationBlocks实现了所有正在复制的数据块的记账工作.它实现以下三个主要功能: 1.记录此时正在复制的块: 2.一种对复制请求进行跟踪的粗粒度计时器: 3.一个定期识别 ...
- zeroMQ研究(转)
偶尔一个机会,了解了下zeroMQ消息队列. 1 ZeroMQ概述 ZeroMQ是一种基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接 ...
- zoj 2068 - Chopsticks
题目:非常多人在一起吃饭.有两组单支的筷子,定义badness为一对筷子长度差的平方,求最小的badness和. 分析:dp,最大公共子序列类似物. 这里利用数学关系找到一个结论: a < b ...
- 【EDAS问题】轻量级EDAS部署hsf服务出现找不到类的解决方案
本地运行轻量级EDAS调用服务的时候报错如下: 2018-01-08 13:16:58.029 WARN [http-bio-8090-exec-8:t.hsf] [RPC Protocol call ...
- python 基础 6.0 异常的常用形式
一. 异常 异常既是一个时间,该事件会在程序执行过程中发生,影响了程序的正常执行.一般情况下,在python无法正常处理程序时就会发生一个异常.异常是python对象,表示一个错误.当python ...
- php标准库DirectoryIterator类的操作说明
<?php $dir = new DirectoryIterator(dirname(__FILE__)); foreach ($dir as $fileInfo) { if ($fileInf ...
- 如何使用doctrine:migrations:migrate
doctrine:migrations:migrate: 可以生成数据库表 当新建完实体之后需要执行 doctrine:migrations:diff 更新差异到db 然后就ok了,这时候你的app/ ...
- python3用pdfminer3k在线读取pdf文件
import importlib import sys import random from urllib.request import urlopen from urllib.request imp ...
- Cocoapods的安装以及使用
在网上看博客,看了好多次,都没有学会cocoapods,今天上午浪费了一上午的时间,终于算是学会了.其实也是很简单的. iOS 新版 CocoaPods 安装流程 1.换掉现有Ruby默认源(由于好多 ...