定时发邮件 [爬虫专题(6)]

本文介绍了如何使用Python内置的smtplib模块发送邮件,特别关注QQ邮箱的SMTP设置,包括端口、加密方式。通过实例展示了开启SMTP服务、获取授权码的过程,并提醒了发送邮件的注意事项。此外,还探讨了定时发送邮件的可能性,提到了schedule模块作为实现定时功能的工具。
摘要由CSDN通过智能技术生成
  • smtplib 模块发邮件

  • QQ邮箱端口、加密

  • QQ邮件经历、改变

  •  定时功能实现

我加入一些QQ群之后,QQ邮箱因为加入Q群就经常收到没境界的邮件,偶尔是打广告的。

这个就很无奈,那我们不发广告。学编程发邮件干嘛 ??会发邮件?是没什么,可是如果和生活挂钩,那就可以提高生活质量。

  • 如果您是一位股票(或比特币)的持有者,您希望及时爬取股票(或比特币)每日的价格数据,方便你能及时卖出或买入,那每天都去启动一遍爬虫程序是极其不高效的。如果您的爬虫程序有定时和发送邮件功能,能自动爬取每天的数据,并且只有当价格达到某个设置的价位时,才通知您可以有所行动了,平时都不打扰您,是不是很爽?
  • 如果您是喜欢做饭,只要您的爬虫有定时和发送邮件的功能,每周定时把新品菜发到邮件里。那么每周吃饭菜都是十分丰盛多彩大大方方请亲朋好友来品尝,我喜欢素食。

如此种种,都只需要定时和发邮件俩个功能。今天我们讲发邮件,定时也许下个礼拜更新出来。

start...

那么 Python 发邮件咋弄呢 ,我们百度一下 Python 发邮件

看了几个网页介绍后,便知道 Python 内置的模块 smtplib 就可发邮件 ~

接着我们去找这个模块的资料,有俩种方式

  • 一篇一篇的博客看,看别人的代码和说明再把案例迁移到自己的项目里面。不过博客只是一家之言,并不系统;
  • 看 smtplib 模块的官方文档。可官方文档对小白一点都不友好,但简练读懂后就觉得字字真言,不过就是读不懂;

这里看情况,如果您是 Python 小白,那看看别人家的博客再把案例迁移过来就好;如果对 Python 实现理解目前逻辑清晰,十分推荐看官方文档节约时间。

官方文档 : Search — Python 3.10.1 documentation

 或 浏览器搜索关键词  "smtplib python"

发现并没有中文,只支持:英文,法文,日文,韩文,可以用 Google浏览器 自带的翻译,语言框右边的框框是说 这是基于python 3.7.2版本的 smtplib 模块介绍,版本看按项目需求就好~

还记得,中学时老师总会让课代表写好每节课的学习目标,考试也是按照这些目标点考。

那么为了提高学习效率,我们也要有 3个 学习目标

  1. smtplib模块能够有哪些函数可用 ??
  2. smtplib模块需要我输入什么 ??
  3. smtplib模块有哪些属性和方法可用 ??

学习目标刚刚立,课代表们就直言啦:

爱丽丝说,smtplib模块能够做的事:连接服务器,登录邮箱,发送邮件,退出服务器以及其他……可以发送纯文本邮件、HTML邮件以及带附件的邮件。

伊芙说,官方文档告诉我们,要输入给 smtplib模块 两个参数:一个是电子邮箱的服务器域名,一个则是端口。

smtp是什么东西:这和我们平时浏览网页的逻辑是类似的。我们浏览网页使用的是http(超文本传输)或者https(超文本传输安全)协议;下载文件(比如下载电影)使用了ftp(文件传输)协议;发送邮件也有一个专属的协议,就是smtp(简单邮件传输协议)。网络协议是通信计算机双方必须共同遵从的一组约定。比如怎么样建立连接、怎么样互相识别。 只有遵守这个约定,计算机之间才能相互通信交流。

所有邮箱里面,我们选用 QQ邮箱,不过我会把这个过程告诉您。如果您能举一反三那么其 ta 邮箱也是一样一样的。

step-0 : 打开浏览器。搜索 "QQ邮箱 smtp设置"

点进去,可以看到 SMTP服务器地址是:smtp.qq.com,端口是 465 或 587,至此  smtplib模块 俩个参数都找到了。

如果现在就傻傻的跑去写代码,那肯定是没预习功课。类似这种网络交流,都是加密的所以我们查查,这个端口使用哪种加密标准,一般来说会是 TLS 或 SSL 。

step-1 : 浏览器搜索 "QQ邮箱 smtp加密",找到相应的网页点进去看看

               或   看标题下面的字也知道是 SSL加密 啦。

得出一个结论:QQ邮箱是用的SSL加密,那么现在可以写这部分代码啦!

import smtplib

qqmail = smtplib.SMTP('服务器地址',端口)
#如果端口是用TLS加密,请这样写代码。其中qqmail是变量名。
qqmail = smtplib.SMTP_SSL('服务器地址',端口)
#如果端口是用SSL加密,请这样写代码。其中qqmail是变量名。

两个函数:一个是SMTP,用于TLS加密的情况;一个是SMTP_SSL,用于SSL加密的情况。它们都会返回给你一个smtp对象,这对象有方法和属性可供你调用,去实现发送邮件的操作。

前面我们已经说过,QQ邮箱使用的SMTP服务器地址是:smtp.qq.com,端口是465或587,加密方式是SSL。所以怎么写代码,你心里是有数的吧?

import smtplib

qqmail = smtplib.SMTP_SSL('smtp.qq.com',587)
#如果出现编码错误UnicodeDecodeError,你可以这样写:qqmail = smtplib.SMTP_SSL('smtp.qq.com',587,'utf-8')


  编译器里面运行出来,居然报错

  不要慌,小场面。在学习Python的过程当中,我们难免会遇到这种报错,这并非坏事,有报错才有成长。当出现报错的时候, 我们去阅读报错,读不懂就去搜索。ta告诉我们了报错信息,wrong 翻译 错误,version number 翻译 版本号,合起来是版本号错误,可这里哪有版本号这个东西。只要服务器地址和端口这俩个参数,对头。会不会是端口呢,我们把端口从587,改为465。

改完后运行,发现没有报错了。emmm... 好吧,一时间不知道该说什么! 

这里,就需要指出一个发邮件的坑出来 ~ 

腾讯大概是出于安全方面考虑,QQ邮箱一般默认关闭smtp服务,我们得先去开启它。

step-2 : 打开https://mail.qq.com/,登录你的邮箱。然后点击位于顶部的【设置】按钮,选择【账户】,下拉到 [账户安全] 位置。

就像上面的一样,把服务都打开。QQ邮箱会提供给你一个授权码,在你使用SMTP服务登录邮箱时,要输入这个授权码作为密码登录,大概这个独立密码是出于安全考虑。

配置一次密码可以用很久直到下次配置,这个事先说明。万一,您以为独立密码出于安全考虑,申请的密码是一次性的,以后还要重新配置。如果在设置和开启服务的过程中有遇到不可逾越的障碍……比如记不清密保手机,那么欢迎你……重新注册个QQ换个邮箱试试看。如果换邮箱要重新查找服务器地址,端口和加密方式。

step-3 : 接着是把代码合起来。

# 连接服务器 + 账号、密码登录
import smtplib
qqmail = smtplib.SMTP_SSL('smtp.qq.com',465)
#如果出现编码错误UnicodeDecodeError,你可以这样写:qqmail = smtplib.SMTP_SSL('smtp.qq.com',465,'utf-8')
account = input('请输入你的邮箱账号:')
password = input('请输入你的邮箱密码:')
#如果是QQ邮箱,你需要输入授权码,或者是独立密码。
qqmail.login(account,password)
recipient = input('请输入收件人邮箱,有多个邮箱请用空格分开:')
#输入收件人
recipient = recipient.split()
#将上面输入的字符串,用空格做切分,转换成列表
theme = 'Subject:'+input('请输入邮件主题:')
#输入邮件主题,主题要用Subject标记。请用英文来写这封邮件,晚点再告诉你原因。
text = '\n\n'+input('请输入邮件正文:')
#输入邮件正文,正文和主题之间要用两个换行。请用英文来写这封邮件,晚点再告诉你原因。
qqmail.sendmail(account,recipient,theme+text)
#发送邮件需要三个参数:发件人,收件人,邮件内容——包含主题和正文。
qqmail.quit()
#断开服务器连接

sendmail( )方法 会返回一个字典,字典里面是发送失败的邮箱。所以如果你有需要的话,可以尝试把qqmail.sendmail(account,recipient,theme+text)给print出来。

收件人如果是一个邮箱,那你可以直接输入这个邮箱地址。如果收件人是好多人,那么你就要输入一个列表,列表里的每一个元素就是一个人的邮箱。所以代码使用split()的方法,把你输入的字符串,转换成列表。转化规则是用空格来切分字符串。当然你也可以用split(','),这样就变成使用英文的逗号来切分(多人 : 把recipient这个变量改为列表,里面的元素是一个个的邮箱字符串, 遍历出来是一个列表。p.s. 您老悠着点,一次性发送不能超过49封信。频数千万不要太多,小心被封,到时候别找我呀,我事先声明呐!!)

邮件正文,它由两个部分组成,主题和正文。主题和正文之间要加两个换行\n\n来区分。

qqmail.sendmail('Debroon@qq.com',['xiaoming@qq.com','xiaobai@qq.com'],'Subject:hi, I 'm Debroon.\n\nDear friend:\n nice to meet you\n,Debroon')
# 发件人:Debroon,收件人:小明和小白(邮箱拼音),主题:嗨,我叫 Debroon,正文:亲爱的朋友:很高兴认识你。Debroon。

发送完毕,断开与服务器的连接。

qqmail.quit()
#断开与服务器的连接

我们跑去别人的博客里面,会看到已经写好了的代码,如:

import smtplib

from email.mime.text import MIMEText
from email.header import Header

qqmail = smtplib.SMTP_SSL('smtp.qq.com',465)
#以上,登录服务器
account = input('请输入你的QQ邮箱:')
password = input('请输入你的邮箱密码:')
qqmail.login(account,password)
#以上,是登录邮箱
theme = input('请输入邮件标题:')
text = input('请输入邮件正文,使用<br>换行:')
recipient = input('请输入收件人邮箱,多个发件人使用空格隔开:')
recipient = recipient.split()
sender = input('请输入发件人昵称(可跳过):')
#以上,是输入内容

message = MIMEText(text,'plain','utf-8')
message['Subject'] = Header(theme,'utf-8')
message['From'] = Header(sender,'utf-8')
#以上,是一波转换操作
try:
    qqmail.sendmail(account,recipient,message.as_string())

except:
    print('对不起,发送失败请重试!')
#以上,是发送
qqmail.quit()
#以上,是退出

认真阅读上面的代码,你会发现里面只有7行代码是你没见过的。它们是:

from email.mime.text import MIMEText
from email.header import Header

message = MIMEText(text,'plain','utf-8')
message['Subject'] = Header(theme,'utf-8')
message['From'] = Header(sender,'utf-8')
try:
    qqmail.sendmail(account,recipient,message.as_string())

那么,我们试着根据全文 给这7行写注释,类似于考试里的补全对话~

from email.mime.text import MIMEText
#调用MIMEText

from email.header import Header
#调用Header

message = MIMEText(text,'plain','utf-8')
#使用MIMEText创建一个对象
#创建对象需要输入三个参数:第1个是我之前写入的邮件正文,第3个是编码表,第2个还不懂
#这个对象能做什么,还不懂

message['Subject'] = Header(theme,'utf-8')
#使用Header创建一个对象
#创建对象需要两个参数:第1个是我之前写入的邮件主题,第2个是编码表
#创建来的对象,赋值给message['Subject']

message['From'] = Header(sender,'utf-8')
#使用Header模块创建一个对象
#创建对象需要两个参数:第1个是我之前写入的发件人,第2个是编码表
#创建来的对象,赋值给message['from']
try:
#尝试执行:
    qqmail.sendmail(account,recipient,message.as_string())
    #发送邮件,这个我懂
    #只是发送邮件的第2个参数,本来是邮件内容,现在变成message.as_string()
    #根据之前的代码,我知道message这个对象里,至少包含:邮件内容,邮件主题,发件人这三个数据。
    #显然我知道as_string()是message的一个方法

对话补的差不多,不过这个阅读理解稍稍的有那么一丢丢的难度。啊呀!出去吹风,赶紧百度一下。

这个就看你搜索技术啦,如果不是很懂,可以看我的另外一篇博客 --- Google食用指南

  • as_string()MIMEText对象变成str
  • MIMEText第二个参数是MIME的subtype,传入'plain',最终的MIME就是'text/plain
  • plain是文本格式

如果还想理解更多,去搜索它们,找到我上面的学习目标,改一下模块名字就好。从实用性上来说,单纯地懂得使用python发邮件并没有什么了不起。但它是一块砖,它能和别的砖组合在一起,构建成摩天大厦。


在上个世纪有一位年轻人,也写了类似这样一个发邮件的小程序,就像今天的您一样。

后来,他把这个功能做了好多升级:不能只发邮件啊,还得收邮件,存储邮件,日历提醒系统,订阅系统……最后,他把这些功能打包成一个电子邮件客户端。

因为这个电子邮件客户端(foxmail)太好用,后来这个软件被一家大公司(博大公司)以1200万的价格收购。

因为这个电子邮件客户端太好用,后来这个软件被一家更大的公司(腾讯)收购。这个年轻人,此时已经三十多岁,他也一并加入这家公司,负责这家公司的邮箱业务。

时过境迁,来到2010年,移动互联网时代刚刚拉开帷幕。做久邮箱业务的他,敏锐地感知到:在新的时代,人们使用的通讯方式也会迎来新的变革。而这种新的通讯方式,在许多地方和邮件都有着相通之处……

后来的故事,大家都知道了。他的名字叫做张小龙,他做出来的新产品,名字叫微信。

而这一切,最开始都是从一行类似于'qqmail.sendmail()'的代码开始的。这和你今天所做的事情,并没有本质区别。再加一些存储功能、收邮件功能……借助一个图形界面的模块,你也能写出一个最原始版本的foxmail。

早期的QQ邮箱,运行笨重而缓慢。2006年底,张小龙率领团队用精简、轻便的思路设计新版本。2007年,新版的QQ邮箱上线,张小龙带领团队也开发了许多创新应用,将QQ邮箱打造为简洁易用、安全稳定的邮箱。2008年,QQ邮箱在腾讯公司获得“七星级产品奖”,张小龙的团队也获得腾讯的年度创新大奖,受到广大用户的欢迎。直至今天,它在中国依然是使用人数最多的邮箱产品。


定时 : schedule模块,它的用法非常简洁,官方文档里是这样讲述:

代码解析 : 

import schedule
import time
# 引入schedule和time

def job():
    print("I'm working...")
# 定义一个叫job的函数,函数的功能是打印'I'm working...'

schedule.every(10).minutes.do(job)       # 部署每10分钟执行一次job()函数的任务
schedule.every().hour.do(job)            # 部署每×小时执行一次job()函数的任务
schedule.every().day.at("10:30").do(job) # 部署在每天的10:30执行job()函数的任务
schedule.every().monday.do(job)          # 部署每个星期一执行job()函数的任务
schedule.every().wednesday.at("13:15").do(job) # 部署每周三的13:15执行函数的任务

while True:
    schedule.run_pending()
    time.sleep(1)    
#1 3-15都是检查部署的情况,如果任务准备就绪,就开始执行任务。    

把 job 函数换成发邮件函数就好了。

如果想实现生活上的定时功能,只能保持程序一直运行的状态,和电脑在一直开机的状态。因为如果程序结束或者电脑关机了的话,就不会定时工作了。

事实上,在程序员真实的开发环境中,程序一般都会挂在远端服务器,因为远端服务器24小时都不会关机,就能保证定时功能的有效性了。如果您也想让程序挂在远端服务器的话,需要自己去做一些额外的学习。


发送邮件的流程
1连接服务器
2登录(邮箱+密码)
3收件人邮箱
4邮件主题
5邮件内容
6发送邮件(测试是否发送成功, QQ邮箱一次不要超过5封, 下一次发送隔15s)
7退出服务器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值