前言
随着年龄的增长,朋友在增多的同时,记性也在逐渐衰退,任何人都逃不过忘记朋友生日的尴尬,这也是导致友谊的小船侧翻的罪魁祸首。今天这篇文章,将带大家使用 crontab + python 定期给朋友发送生日祝福邮件,解放大脑,解放双手。
(注:读懂本篇文章需要有用 python 跑 Hello World 的技术能力)
步骤
邮箱
本文使用 qq 邮箱发送邮件,使用 python 发送 qq 邮箱的邮件时,是需要使用授权码而非密码的,使用 iphone 的小伙伴如果在系统的邮箱 app 绑定过 qq 邮箱应该知道授权码这个东西。
获取授权码的方式请按照如下步骤:
登录 qq 邮箱,点击左上角“设置”
点击“账号”栏
往下拉,如果服务未开启需要开启,然后点击“继续获取授权码”,将提示扫码发送短信,发送成功后就会弹出很长一串的授权码啦!保存好这个授权码,一会粘贴到 python 脚本里。
python
为使邮件不那么单调,我下载了一张生日图片(后来才发现不是 DAY 是 GAY……慎用):
并且保存为 /Users/liaozhiheng/Documents/python/HappyBirthday/HappyBirthday.jpg,执行 Python 脚本时会将这个图片附带到正文下方。
接下来直接放代码,只需要改一下收发人的邮箱,授权码即可。当然邮件内容也是可以自定义的哩!
(这个脚本我保存为 /Users/liaozhiheng/Documents/python/HappyBirthday/friend.py,后面配置定时任务要用到这个路径)
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from datetime import datetime
from email.utils import formataddr
import os
# 用来输出日志,后面使用 crontab 定时发送时,我们可以观察那一刻的邮件是否发送成功
time = datetime.today().strftime('%Y%m%d %H%M%S')
# 收发人设置
smtp_server = 'smtp.qq.com'
port = 465 # SSL 端口
sender_name = '你的名字' # 以防朋友不知道是谁发的
sender_email = '你的邮箱@qq.com'
receiver_email = '朋友的邮箱@qq.com' # 其他邮箱类型也可以,这个脚本只需要保证发件人使用的是qq邮箱
password = '授权码,粘贴到这里'
# 邮件内容
message = MIMEMultipart()
message['From'] = formataddr((sender_name, sender_email))
message['To'] = receiver_email
message['Subject'] = 'Happy Birthday!' # 这是邮箱主题
# 邮件正文
body = '新的一岁要快高长大哟!'
message.attach(MIMEText(body, 'plain'))
# 添加邮件正文
html = f'''
<html>
<body>
<p>{body}</p>
<img src="cid:image1">
</body>
</html>
'''
message.attach(MIMEText(html, 'html'))
# 添加嵌入的图片
with open('/Users/liaozhiheng/Documents/python/HappyBirthday/HappyBirthday.jpg', 'rb') as img:
msg_image = MIMEImage(img.read())
msg_image.add_header('Content-ID', '<image1>')
message.attach(msg_image)
# 发送邮件
try:
server = smtplib.SMTP_SSL(smtp_server, port)
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message.as_string())
server.quit()
print(f"{time}给xxx的祝福发送成功")
except Exception as e:
print(f"{time}给xxx的祝福发送失败: {e}")
先用自己的邮箱执行一下看看有没有问题,如果缺了对应的包,请用 pip install 来安装。
效果如下:
脚本已经准备好了,接下来配置定时任务。
crontab
crontab 是执行定时任务的命令,如果你使用的是 macOS 或 Linux 系统,就可以使用这个命令配置定时任务了。在这里跟 Windows 用户说声抱歉,Windows 可以使用系统的“任务计划程序”进行配置,只需要点点点就行啦,很简单,大家可自行百度。
进入正题,打开 macbook 的终端,执行 which python,查看当前激活的 python 解释器的路径,一会配置时加上解释器路径,可以省去很多麻烦。
执行 crontab -e(e是指 edit),如果你是第一次配置定时任务,是一个空白文件,按照以下格式添加一行(如果不会在命令行编辑文件,请看附录):
0 0 23 8 * /Users/liaozhiheng/mambaforge2/bin/python /Users/liaozhiheng/Documents/python/HappyBirthday/friend.py >> /Users/liaozhiheng/Documents/python/HappyBirthday/EmailSend.log 2>&1
这个命令分为 4 部分,下面一一解释。
命令的第一部分
第一部分是:0 0 23 8 *
crontab 使用由五个字段组成的格式来指定命令的执行时间。这些字段分别表示分钟、小时、日期、月份和星期几。格式如下:
* * * * *
- - - - -
| | | | |
| | | | ---- 星期几 (0-7, 0或7是星期天,1是星期一,依此类推)
| | | ------ 月份 (1-12)
| | -------- 日期 (1-31)
| ---------- 小时 (0-23)
------------ 分钟 (0-59)
字段解释
• 分钟:0-59 之间的一个整数。
• 小时:0-23 之间的一个整数。
• 日期:1-31 之间的一个整数,表示某个月的第几天。
• 月份:1-12 之间的一个整数,或者是月份的英文缩写(如 Jan 表示一月)。
• 星期几:0-7 之间的一个整数,其中 0 或 7 都表示星期天,1 表示星期一,依此类推。也可以使用英文缩写(如 Sun 表示星期天)。
特殊符号
• *:表示任何可能的值,即 “每个” 的意思。
• ,:用于分隔列表中的多个值。例如,1,15 表示第 1 和第 15 分钟。
• -:表示范围。例如,1-5 表示从第 1 到第 5 分钟。
• /:表示步长。例如,*/5 表示每隔 5 分钟。
crontab 时间设置示例
• 每分钟:* * * * *
• 每天凌晨 0 点:0 0 * * *
• 每小时的第 30 分钟:30 * * * *
• 每天下午 2 点:0 14 * * *
• 每周一上午 7 点:0 7 * * 1
• 每年 8 月 23 日 0 点整:0 0 23 8 *
一开始可以配成五个*,表示每分钟都执行,方便观察配置是否正常。
命令的第二部分
第二部分是:/Users/liaozhiheng/mambaforge2/bin/python
这是前文提到的用 which python 命令获取到的当前激活的 python 解释器路径,表示要用这个解释器来执行 python 脚本。
命令的第三部分
第三部分是:/Users/liaozhiheng/Documents/python/HappyBirthday/friend.py
就是 python 脚本的保存路径。
命令的第四部分
第四部分是:>> /Users/liaozhiheng/Documents/python/HappyBirthday/EmailSend.log 2>&1
表示把脚本的执行结果输出到 EmailSend.log 中,这个文件不需要自己创建,定时任务第一次执行脚本后会自动创建。2>&1 的意思是把报错信息也记录到文件中。
输出效果:
至此,所有工作都准备完毕,有了它,即使自己意外嗝屁,只要电脑还开着机,你的朋友依然能每年都收到你的生日祝福,尸体都感觉暖暖的呢!
附录:编辑 crontab
在开始终端的文件编辑之前,请忘了你有鼠标这件事,终端编辑文件是用不了鼠标的。
我使用的文本编辑器是 vim,不是 mac 默认的 nano(因为我不会)。所以,这里只教大家怎么用 vim 编辑 crontab。
macbook 的默认编辑器是 nano,在终端执行 export EDITOR=vim 即可将默认编辑器改为 vim。
改好后,执行 crontab -e 时,显示如下(截图是我自己的定时任务配置,这里已经有两个配置了,第一个红框由于开头有“#”,表示注释,因此不生效。如果是第一次编辑,是啥玩楞也没有的,不用担心,这是正常现象):
此时你会发现还是无法自由地输入文字,因为此时处于 vim 的命令模式。敲一下键盘上的 i 键,进入插入模式,左下角显示 -- INSERT --
这时候就可以正常输入字母了,用方向键控制光标,Home 光标移到行首,End 光标移到行尾,Enter 换行等基本操作都能使用。第一次使用肯定是不熟练的,建议把配置行先在其他地方写好,复制之后就能直接粘贴到这里了。
编辑完成之后,按键盘左上角的 Esc 键,返回到命令模式,然后输入“:wq”,注意是英文冒号,它表示保存并退出编辑,然后回车,文件就编辑好啦!并且系统会输出如下信息: