【Python】微信号推送不想用?为何不试试邮箱推送呢

邮箱推送是什么?

见名知意,就是通过邮箱来推送消息到另一个邮箱。因为微信公众号推送测试号的提醒貌似以及不再提醒了(不排除是手机系统问题),所以想着回归最淳朴的邮件推送。邮件推送主要用户发送定时执行的网络爬虫产生的数据,数据展示爬虫的运行情况,例如是否成功签到等等。


有什么意义呢?

意义嘛,看个人怎么应用罢了,我罗列一下我的应用场景吧。

  • Python 自动签到结果反馈
  • Python 爬虫出错提醒(大量、长时间的爬取数据)
  • 程序执行结果反馈(大学毕设选题使用的 Python 自动抢课题,把抢到的课题反馈到邮箱)
  • 实时监控数据变化(奥运会得奖牌通知并播报)
  • …………

说真的,应用场景很多很多好吧,只要是你想让程序通知你知道的情况都可以使用邮箱推送。人可能会忘了一件事没来得及通知你,但程序不会,只要条件符合,它就会触发并且通知你。


实现原理是什么?

其实就是登录邮箱并且使用该邮箱给指定的邮箱发邮件,就这么简单,只是把平时人工操作的步骤交给代码来执行了罢了。


准备邮箱

首先需要准备一个邮箱用来发送邮件,并且为邮箱开通 IMAP/SMTP 登录功能

6E8CD7353956135BB764EEB8578695C3

397C2EE8D0504FD977ADBABFE0D6D3B4


在开启 IMAP/SMTP 登录功能后,需要为邮箱添加一个登录授权码,相当于邮箱的密码。

B615A31B493011E824E45B2721E5EF8A


在获取到授权码后,需要查看该邮箱的 SMTP 服务器地址,例如网易的 163 邮箱为 smtp.163.com

21D991DDC2B5CB57495BDC99EC095B30


代码实现

Python 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import datetime
import uuid
import os
from email.header import Header
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from smtplib import SMTP_SSL

# SMTP服务器地址
host_server = '你的SMTP服务器地址'
# 需要登录的邮箱
sender = '用来发送邮件的邮箱'
# 登录邮箱的授权码
pwd = '发送邮件的邮箱授权码'
# 接受邮件的地址
receiver = '需要接收邮件的邮箱地址'


def run(mail_title, mail_content, mail_file_path):
try:
msg = MIMEMultipart()
msg["Subject"] = Header(mail_title, 'utf-8')
msg["From"] = sender
msg["To"] = Header(receiver, 'utf-8')
msg.attach(MIMEText(mail_content, 'plain', 'utf-8'))
for filenames in mail_file_path:
if os.path.exists(filenames):
file = MIMEApplication(open(filenames, 'rb').read())
filename = str(uuid.uuid4()).replace('-', '') + os.path.splitext(filenames)[-1]
file.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(file)
smtp = SMTP_SSL(host_server)
smtp.login(sender, pwd)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
except Exception as e:
print(e, datetime.datetime.now())


if __name__ == '__main__':
file_path = ["C:/img/1.jpg",
"C:/img/2.jpg",
"C:/img/3.jpg"]
title = "这是标题"
content = "这是正文"
run(title, content, file_path)

Java 版本

Maven 依赖
1
2
3
4
5
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* 使用SMTP协议发送电子邮件
*/
public class sendEmailUtils {
// 邮件发送协议
private final static String PROTOCOL = "smtp";
// SMTP邮件服务器
private final static String HOST = "smtp.163.com";
// SMTP邮件服务器默认端口
private final static String PORT = "25";
// 是否要求身份认证
private final static String IS_AUTH = "true";
// 是否启用调试模式(启用调试模式可打印客户端与服务器交互过程时一问一答的响应消息)
private final static String IS_ENABLED_DEBUG_MOD = "true";
//发件人邮箱授权码
private final static String AUTHORIZATION_CODE = "发送邮箱的授权码";
// 发件人
private static final String from = "发送邮件的邮箱";
// 收件人
private static final String to = "接收邮件的邮箱";
// 初始化连接邮件服务器的会话信息
private static final Properties props;
private static Transport transport = null;
static {
props = new Properties();
props.setProperty("mail.transport.protocol", PROTOCOL);
props.setProperty("mail.smtp.host", HOST);
props.setProperty("mail.smtp.port", PORT);
props.setProperty("mail.smtp.auth", IS_AUTH);
props.setProperty("mail.debug",IS_ENABLED_DEBUG_MOD);
Session session = Session.getInstance(props, new MyAuthenticator());

try {
// 获得Transport实例对象
transport = session.getTransport();
// 打开连接
transport.connect(from, AUTHORIZATION_CODE);
} catch (MessagingException e) {
e.printStackTrace();
}

}
/**
* 发送简单的文本邮件
*/
public static void sendTextEmail(String to, String title, String content, List<String> filePathList){
try {
// 创建Session实例对象
// Session session1 = Session.getDefaultInstance(props);
Session session1 = Session.getInstance(props, new MyAuthenticator());
// 创建MimeMessage实例对象
MimeMessage message = new MimeMessage(session1);
// 设置发件人
message.setFrom(new InternetAddress(from));
// 设置邮件主题
message.setSubject(title);
// 设置收件人
message.setRecipient(RecipientType.TO, new InternetAddress(to));
// 设置发送时间
message.setSentDate(new Date());
// 设置纯文本内容为邮件正文
message.setText(content);
MimeMultipart mailContent = new MimeMultipart("mixed");
message.setContent(mailContent);
if(!filePathList.isEmpty()){
for (int i = 0; i < filePathList.size(); i++) {
// 新建附件
MimeBodyPart mimeBodyPart = new MimeBodyPart();
// 将附件添加到邮件中
mailContent.addBodyPart(mimeBodyPart);
// 添加内容
FileDataSource source = new FileDataSource(filePathList.get(i));
DataHandler dataHandler = new DataHandler(source);
// 生成UUID
String uuid = UUID.randomUUID().toString().replace("-", "");
// 设置文件名
mimeBodyPart.setFileName(uuid+ source.getName().lastIndexOf("."));
mimeBodyPart.setDataHandler(dataHandler);
}
}
// 保存并生成最终的邮件内容
message.saveChanges();

// 将message对象传递给transport对象,将邮件发送出去
transport.sendMessage(message, message.getAllRecipients());
// 关闭连接
transport.close();
} catch (Exception e) {
e.printStackTrace();
}
}



/**
* 向邮件服务器提交认证信息
*/
static class MyAuthenticator extends Authenticator {

public MyAuthenticator() {
super();
}

@Override
protected PasswordAuthentication getPasswordAuthentication() {

return new PasswordAuthentication(from, AUTHORIZATION_CODE);
}
}

public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("C:\\img\\1.jpg");
arrayList.add("C:\\img\\1.jpg");
arrayList.add("C:\\img\\1.jpg");
sendTextEmail(to,"1","2", arrayList);
}
}

效果展示

9B6025B904CC4145BFDEAD5416C8A506