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包,这就不多说了 ...
随机推荐
- 推荐TED演讲:20岁光阴不再来(Why 30 is not the new 20)
缘起 早上起来在电脑上看到"自强不息"群(群号)中骆宏给大家分享的视频."20岁光阴不再来",利用短暂的时间浏览了一下.就像把这个TED视频分享给很多其它的朋友 ...
- linux 跟踪工具
strace工具,进程诊断.排错.跟踪系统调用和信号量 每行输出都是一个系统调用,包括函数和返回值. strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用及它所接收的 ...
- Hive报错:Failed with exception Unable to rename
之前也安装过hive,操作过无数,也没发现什么错误,今天因为之前安装的hadoop不能用了,不知道为什么,老是提示node 0,所以重新安装了hadoop和hive.安装完测试hive创建表也没发现什 ...
- 华为P20无敌拍摄能力开放 如何即刻获得?
在全球专业相机测评机构DXOmark发布的相机评测排行中,华为P20.P20 Pro成功登顶“全球拍照最好智能手机”.P20 Pro综合得分高达109分,P20综合得分102分.“华为并非简单地将第三 ...
- 在PHP中,通过filesize函数可以取得文件的大小,文件大小是以字节数表示的。如果要转换文件大小的单位,可以自己定义函数来实现。
<?php function getsize($size, $format) { $p = 0; if ($format == 'kb') { $p = 1; } elseif ($format ...
- linux下安装go
在centOS下,安装go的环境,如下: 下载压缩包,wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz 解压该文件 ...
- 平滑处理 - cvSmooth() 函数实现
前言 平滑是图像处理中很重要的操作,其主要用途是降噪.Open CV 提供了 5 种不同的平滑方法:简单模糊,简单无缩放变换的模糊,中值模糊,高斯模糊和双边滤波,它们都通过函数 cvSmooth 实现 ...
- FAT12中,如何定位大于一个扇区(512B)的文件内容
[0]README 0.1)本文旨在于 演示在FAT12中, 如何取定位大于 512B 的文件内容,和查看它: 0.2)如何制作FAT12文件系统,以及如何向文件中添加temp.txt文件,参见: { ...
- 九度OJ 1068:球的半径和体积 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5385 解决:1949 题目描述: 输入球的中心点和球上某一点的坐标,计算球的半径和体积 输入: 球的中心点和球上某一点的坐标,以如下形式输 ...
- JavaScript library of crypto standards. 看源码
crypto-js - npm https://www.npmjs.com/package/crypto-js crypto-js/docs/QuickStartGuide.wiki <wiki ...