跳至工具栏

Python3 SMTP发送邮件

Python3 SMTP发送邮件

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。

Python创建 SMTP 对象语法如下:

import smtplib  smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] ) 

参数说明:

  • host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:w3cschool.cn,这个是可选参数。
  • port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下SMTP端口号为25。
  • local_hostname: 如果SMTP在你的本机上,你只需要指定服务器地址为 localhost 即可。

Python SMTP对象使用sendmail方法发送邮件,语法如下:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options] 

参数说明:

  • from_addr: 邮件发送者地址。
  • to_addrs: 字符串列表,邮件发送地址。
  • msg: 发送消息

这里要注意一下第三个参数,msg是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意msg的格式。这个格式就是smtp协议中定义的格式。

实例

以下是一个使用Python发送邮件简单的实例:

#!/usr/bin/python3
import smtplib from email.mime.text
import MIMEText from email.header
import Header  sender = 'from@w3cschool.cn' receivers = ['429240967@qq.com'] 
# 接收邮件,可设置为你的QQ邮箱或者其他邮箱 
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码 message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8') message['From'] = Header("W3Cschool教程", 'utf-8') message['To'] =  Header("测试", 'utf-8')  subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8')   try:
     smtpObj = smtplib.SMTP('localhost')
     smtpObj.sendmail(sender, receivers, message.as_string())
     
print ("邮件发送成功") except smtplib.SMTPException:
     
print ("Error: 无法发送邮件") 

我们使用三个引号来设置邮件信息,标准邮件需要三个头部信息: From, To, 和 Subject ,每个信息直接使用空行分割。

我们通过实例化 smtplib 模块的 SMTP 对象 smtpObj 来连接到 SMTP 访问,并使用 sendmail 方法来发送信息。

执行以上程序,如果你本机安装sendmail,就会输出:

$ python3 test.py
  邮件发送成功 

查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

Python3 SMTP发送邮件

如果我们本机没有 sendmail 访问,也可以使用其他服务商的 SMTP 访问(QQ、网易、Google等)。

#!/usr/bin/python3
import smtplib from email.mime.text
import MIMEText from email.header
import Header 
# 第三方 SMTP 服务 mail_host="smtp.XXX.com" 
#设置服务器 mail_user="XXXX"
   
#用户名 mail_pass="XXXXXX"  
#口令
    sender = 'from@w3cschool.cn' receivers = ['429240967@qq.com'] 
# 接收邮件,可设置为你的QQ邮箱或者其他邮箱  message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8') message['From'] = Header("W3Cschool教程", 'utf-8') message['To'] =  Header("测试", 'utf-8')  subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8')   try:
     smtpObj = smtplib.SMTP()
      smtpObj.connect(mail_host, 25)
   
# 25 为 SMTP 端口号
     smtpObj.login(mail_user,mail_pass)
     smtpObj.sendmail(sender, receivers, message.as_string())
     
print ("邮件发送成功") except smtplib.SMTPException:
     
print ("Error: 无法发送邮件") 

使用Python发送HTML格式的邮件

Python发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html。具体代码如下:

#!/usr/bin/python3
import smtplib from email.mime.text
import MIMEText from email.header
import Header  sender = 'from@w3cschool.cn' receivers = ['429240967@qq.com'] 
# 接收邮件,可设置为你的QQ邮箱或者其他邮箱  mail_msg = """ <p>Python 邮件发送测试...</p>
<p>
<a href="http://www.soxitoday.com">这是一个链接</a>
</p>""" message = MIMEText(mail_msg, 'html', 'utf-8') message['From'] = Header("W3Cschool教程", 'utf-8') message['To'] =  Header("测试", 'utf-8')  subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8')   try:
     smtpObj = smtplib.SMTP('localhost')
     smtpObj.sendmail(sender, receivers, message.as_string())
     
print ("邮件发送成功") except smtplib.SMTPException:
     
print ("Error: 无法发送邮件") 

执行以上程序,如果你本机安装sendmail,就会输出:

$ python3 test.py
  邮件发送成功 

查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

Python3 SMTP发送邮件


Python 发送带附件的邮件

发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。

#!/usr/bin/python3
import smtplib from email.mime.text
import MIMEText from email.mime.multipart
import MIMEMultipart from email.header
import Header  sender = 'from@w3cschool.cn' receivers = ['429240967@qq.com'] 
# 接收邮件,可设置为你的QQ邮箱或者其他邮箱 
#创建一个带附件的实例 message = MIMEMultipart() message['From'] = Header("W3Cschool教程", 'utf-8') message['To'] =  Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' message['Subject'] = Header(subject, 'utf-8') 
#邮件正文内容 message.attach(MIMEText('这是W3Cschool教程Python 邮件发送测试……', 'plain', 'utf-8')) 
# 构造附件1,传送当前目录下的 test.txt 文件 att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字 att1["Content-Disposition"] = 'attachment;


filename="test.txt"' message.attach(att1) 
# 构造附件2,传送当前目录下的 w3cschool.txt 文件 att2 = MIMEText(open('w3cschool.txt', 'rb').read(), 'base64', 'utf-8') att2["Content-Type"] = 'application/octet-stream' att2["Content-Disposition"] = 'attachment;


filename="w3cschool.txt"' message.attach(att2)  try:
     smtpObj = smtplib.SMTP('localhost')
     smtpObj.sendmail(sender, receivers, message.as_string())
     
print ("邮件发送成功") except smtplib.SMTPException:
     
print ("Error: 无法发送邮件") 
$ python3 test.py
  邮件发送成功 

查看我们的收件箱(一般在垃圾箱),就可以查看到邮件信息:

Python3 SMTP发送邮件


在 HTML 文本中添加图片

邮件的 HTML 文本中一般邮件服务商添加外链是无效的,正确添加突破的实例如下所示:

#!/usr/bin/python3
import smtplib from email.mime.image
import MIMEImage from email.mime.multipart
import MIMEMultipart from email.mime.text
import MIMEText from email.header
import Header  sender = 'from@w3cschool.cn' receivers = ['429240967@qq.com'] 
# 接收邮件,可设置为你的QQ邮箱或者其他邮箱  msgRoot = MIMEMultipart('related') msgRoot['From'] = Header("W3Cschool教程", 'utf-8') msgRoot['To'] =  Header("测试", 'utf-8') subject = 'Python SMTP 邮件测试' msgRoot['Subject'] = Header(subject, 'utf-8')  msgAlternative = MIMEMultipart('alternative') msgRoot.attach(msgAlternative)   mail_msg = """ <p>Python 邮件发送测试...</p>
<p>
<a href="http://www.soxitoday.com">W3Cschool教程链接</a>
</p>
<p>图片演示:</p>
<p>
<img src="cid:image1">
</p>""" msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8')) 
# 指定图片为当前目录 fp = open('test.png', 'rb') msgImage = MIMEImage(fp.read()) fp.close() 
# 定义图片 ID,在 HTML 文本中引用 msgImage.add_header('Content-ID', '<image1>') msgRoot.attach(msgImage)  try:
     smtpObj = smtplib.SMTP('localhost')
     smtpObj.sendmail(sender, receivers, msgRoot.as_string())
     
print ("邮件发送成功") except smtplib.SMTPException:
     
print ("Error: 无法发送邮件") 
$ python3 test.py
  邮件发送成功 

查看我们的收件箱(如果在垃圾箱可能需要移动到收件箱才可正常显示),就可以查看到邮件信息:

Python3 SMTP发送邮件

更多内容请参阅:https://docs.py
thon.org/3/library/email-examples.html。

第十六回、PHP基础教程,PHP与mySQL的连接

mySQL的连接

建议按以下将信息赋值给变量的形式,以后用到时,可以直接用变量。

$sqlServerName=”localhost/127.0.0.1/自己的IP地址”;

$userName=”登录数据库的用户名”;

$userPass=”登录数据库的密码”;

$sqlDataBase=”数据库的路径”;

$sql=”sql语句”;

//mySql数据库连接的语法:

$conn=mysql_connect($sqlServerName,$userName,$userPass);

mysql_select_db($sqlDataBase,$conn);

$queryResult=@ mysql_query($sql,$conn) or die(mysql_error());

$row=mysql_fetch_row($queryResult);

或$row=mysql_fetch_array($queryResult);

//说明:mysql_fetch_row($queryResult);

与mysql_fetch_array($queryResult);

的区别是,使用前者生成的数组$row只能使用下标来显示其每个元素的值——即每条记录中字段的值,而用后者则既可以用下标也可以使用数据表中的字段名来显示每个元素的值。

//下面是输出查询结果中每个字段的名称,按行输出

for($i=0;

$i<=mysql_num_fields($queryResult)-1;

$i++)

{

echo mysql_field_name($queryResult,$i).”&

nbsp;

&

nbsp”;

//输出查询结果中每个字段的名称

}

mysql_data_seek($queryResult,0);

//将记录指针移动到查询结果中指定的记录行上,行号从0开始,取值范围是0到(mysql_num_rows-1)

//下面是输出查询的每个记录

while($row=mysql_fetch_row($queryResult))//从结果集中取得一行作为枚举数组,返回根据所取得的行生成的数组,如果没有更多行则返回 FALSE。它会将记录指针自动移动到下一条

{

for($i=0;

$i<mysql_num_fields($queryResult);

$i++)

{

echo $row[$i].”&

nbsp;

&

nbsp;

“;

}

echo “<br>”;

}

mysql_free_result($queryResult);

//释放查询结果

PHP中有关数据查询的常用函数:

$myConnect=mysql_connect: 开启 MySQL 链接,建立PHP与MYSQL的连接

$mysql_select_db: 打开一个数据库,与MYSQL建立连接后,就可以打开一个数据库了

@ 和 or die(“错误信息”):在PHP中把@放在某语句的前面,就可以隐藏这条语句运行时出现的错误;把“or die”放在某条语句的后面,当这条语句在运行时出现错误时就可以显示指定的错误信息

说明:

mysql_connect(“主机”, “用户名”, “密码”) //说明:主机名可以是localhost或IP地址

mysql_select_db(“需打开的数据库名”,连接标识符);

mysql_query(“set names ‘GBK'”);

如果数据表中涵有中文,则在SQL查询前加入之可解决中文乱码

mysql_num_rows;

用于计算查询结果中所得行的数目

mysql_insert_id;

传回最后一次使用 INSERT 指令的 ID。

mysql_tablename;

取得数据库名称

mysql_error;

返回错误信息

mysql_free_result($queryResult);

//释放查询结果

mysql_clos;

关闭 MySQL 链接

htmlspecialchars(string,quotestyle,character-set);

// 主要功能是将HTML格式化,防止在输出html时被浏览器执行;string必要参数,指定需要解码的字符串对象;quotestyle可选参数,定义如何对单引号和双引号进行编码;character-set可选参数,指定使用什么样的字符串设置。详细说明见PHP5手册。

mysql_create_db(“webjx”);

//创建一个名称为webjx的新数据库

SQL语句中limit的用法(MYSQL的这个功能很好,可以比较容易的来实现分页操作):

Select * from table where 条件 limit 开始位置,操作记录数 //开始位置从0开始

Select * from table where 条件 limit 0,20//从满足条件的第1条记录开始,取20条满足条件的记录

Select * from table where 条件 limit 10,20//从满足条件的第11条刻录开始,取20条满足条件的记录

PHP无法向MYSQL保存中文文字或输出MYSQL中的中文文字出现乱码的解决:

PHP操作MYSQL,汉字出现乱码或无法将汉字插入到数据库中,究其原因是字符集设置不当。当数据库中的字符集采取的是UTF-8时,就在mysql_connect后面加一句SET NAMES UTF8,即可使得UTF8的数据库消除乱码;对于GBK的数据库则使用SET NAMES GBK,示例代码如下:

$mysql_mylink = mysql_connect($mysql_host, $mysql_user, $mysql_pass);

mysql_query(“SET NAMES ‘GBK'”);

parse_url()解析URL函数:

parse_url() 是将URL解析成有固定键值的数组的函数

第十六回、PHP基础教程,PHP与mySQL的连接

子网划分

ip地址的结构和分类

根据tcp/ip协议,连接在internet上的每个设备都必须有一个ip地址,他是一个32位二进制数,也可以用点分十进制表示,每八位一组,用一个十进制表示即0~255,每组用”.”分隔开,例如172.16.45.10
ip地址表示
子网划分
将ip地址中的网络位和主机位固定下来后,ip地址被分成了不同的积累:A类,B类,C类,D类,E类
子网划分
子网划分

 

特殊ip地址

  1. 网络地址:用于表示网络本身,具有正常的网络号部分,而主机号部分全部为0的ip地址称之为网络地址,如172.16.45.0就是一个B类网络地址
  2. 广播地址:用于向网络中的所有的设备进行广播。具有正常的网络号部分,而主机号部分全为1(即255)的ip地址称之为广播地址,如172.16.45.255就是一个B类的网络地址
  3. 有限广播地址:指的是32位全位1(即255.255.255.255)的ip地址,用于本网广播
  4. 回送地址:网络地址不能以十进制的127作为开头,在地址中数字127保留给系统作为诊断用,称为欢送地址,如127.0.0.1用于回路测试
  5. 私有地址:只能在局域网内使用,不能在internet上使用的ip地址称为私有ip地址,私有ip地址有:

    1. 10.0.0.0~10.255.255.255,表示一个A类地址
    2. 172.16.0.0~172.31.255.255,表示16个B类地址
    3. 192.168.0.0~192.168.255.255,表示256个C类地址
  6. 0.0.0.0:指已经不是真正意义上的ip地址,它表示的是所有不清楚主机和目的网络,这里的不清楚指的是在本机路由表里没有特定条目指明如何到达

 

子网掩码

子网掩码用于识别ip地址中的网络地址和主机地址。
子网掩码用于识别ip地址中的网络地址和主机地址。
子网掩码也是32位二进制数字,在子网掩码中,对应于网络地址部分全用1表示,主机部分全用0表示
还可以用网络前缀表示子网掩码,即”/<网络地址位数>”,如172.16.45.0/24表示B类网络172.16.45.0的子网掩码为255.255.255.0
子网划分

 

ip地址申请

https://www.processon.com/mindmap/57fdad47e4b08d4fe9b3d7e2
子网划分子网划分概念
子网划分是通过借用ip地址的若干位主机位来充当子网地址的从而将原来的网络分为若干个彼此隔离的子网实现的
子网划分
注意:
arp协议通过ip地址获取目标主机的mac地址这一过程使用的是广播的方式,这个广播地址就是通过子网地址于子网掩码计算而来的,只有计算出的这一子网内的主机才能收到这个arp广播包
子网划分与vlan都可以做到隔离广播域,只是子网划分是三层隔离,二vlan是二层
子网划分

c类子网划分初探

子网划分
 

子网划分步骤

  • 确定要划分的子网数以及每个子网的主机数
  • 求出子网数目对应的二进制的位数N及主机数目对应的二进制数的位数M
  • 对该ip地址的原子网掩码,将其主机地址部分的前N位置1(其余全部置0)或后M位置0(其余全置1)即得出该ip地址划分子网后的子网掩码

 

子网划分案例

给C类网络211.168.10.0划分5个子网
2**2-2<5<2**3-2所以需要3位网络号,主机号为8-3=5
子网掩码为255.255.255.224
每个子网可容纳2**5-2=30台主机
子网划分
 

 划分子网注意事项

  1. 在子网划分时不仅需要考虑目前需要,还应该了解将来需要多说子网和主机。子网掩码使用较多的主机位,可以得到更多子网,节约了ip地址资源,若将来需要更多的子网时,不用再重新分配ip地址,但每个子网的主机数量有限;反之,子网掩码使用较少的主机位,每个子网的主机数允许有更大的增长,但可用子网数有限
  2. 一般来说,一个网络中的节点数太多,网络会因为广播通信而饱和,所以网络中的主机数量的增长是有限的,也就是说,在条件允许的情况下,应将更多的主机位用于子网位

 

为什么要子网划分:

Internet组织机构定义了五种IP地址,用于主机的有A、B、C三类地址。其中A类网络有126个,每个A类网络可能有16,777,214台主机,它们处于同一广播域。而在同一广播域中有这么多结点是不可能的,网络会因为广播通信而饱和,结果造成16,777,214个地址大部分没有分配出去,形成了浪费。而另一方面,随着互连网应用的不断扩大,IP地址资源越来越少。为了实现更小的广播域并更好地利用主机地址中的每一位,可以把基于类的IP网络进一步分成更小的网络,每个子网由路由器界定并分配一个新的子网网络地址,子网地址是借用基于类的网络地址的主机部分创建的。划分子网后,通过使用掩码,把子网隐藏起来,使得从外部看网络没有变化,这就是子网掩码。
很简单的说   就是,一个公司不可能使用254个公网地址,A公司想用6个地址,B公司也想用6个地址,如果把这两个公司的地址都放在一个大网段里面,这两个公司的地址就能够直接互通
 

子网划分优点

  • 减少网络流量
  • 提高网络性能
  • 简化管理
  • 易于扩大地理范围