Python实现自动发送邮件 -- 自动抓取博客/网站中留言的邮箱并发送相应邮件
- 背景
- 脚本要解决的问题:
- 实现方法
- 代码及解析
- 1. AutoSendEmailByBlogComments.py
- 2. FileOperation.py
- 3. SendEmail.py
- 备注:邮箱SMTP设置
背景
在各大论坛、博客上,很多User通过留言邮箱获取相关资料,但是留言人数过多了,对于博主来说一个一个发送相关邮件太繁琐了,同时也经常不能及时发现新评论,效率太低。。。我是个懒人, 这当然也不能忍,所以想到通过Python脚本将上述流程自动化。
例如我有一篇博客:嵌入式学习中较好的练手项目和课题整理(附代码资料、学习视频和嵌入式学习规划),里面会分享很多资料,小伙伴们通过留言邮箱来获取资料,通过这个Python脚本自动化将资料发送到各小伙伴们的邮箱中,非常方便,我再也不必要每天刷博客新留言,再手动点开邮箱发送邮件啦。
脚本要解决的问题:
脚本需要自动找到评论区中留言的
新邮箱
留言内容,然后将相关资料整合成一封邮件,通过SMTP发送到对方邮箱。注意是新邮箱,之前发送过的脚本当然不能再给人家发一次啦。
通过Python脚本各类成型的库函数,就可以简单完美的解决这类问题:
实现方法
实现方法大致就是:通过Python抓取我的Blog网页中的评论数据,通过 正则表达式 筛选出网页中的邮箱数据,并将发现的 新邮箱 写入到文件中,然后将资料信息组成一封标准邮件,通过 SMTP 发送。
代码目录结构如下:
其中record.txt就是记录所有新邮件的文件,
最后将脚本打包成一个exe, 并通过Windows系统中的
TaskScheduler
,每天定时的调用该程序一次,那么,每天新留言的小伙伴,就能自动收到资料啦。
代码及解析
1. AutoSendEmailByBlogComments.py
负责抓取数据,筛选出新邮件数据,然后调度发送邮件。。。代码如下:
import
time
import
urllib
.
request
import
re
from
SendEmail
import
SendEmailtoAddr
from
FileOperation
import
RecordEmail
,
isNewEmail
HasNewEmail
=
False
def
handleEmailAddr
(
EmailAddr
)
:
isNew
=
isNewEmail
(
EmailAddr
)
if
isNew
==
True
:
print
(
'Get New Email addr:'
+
EmailAddr
)
isSuccess
=
SendEmailtoAddr
(
EmailAddr
)
if
isSuccess
==
True
:
RecordEmail
(
EmailAddr
)
global
HasNewEmail
HasNewEmail
=
True
print
(
'Send email to '
+
EmailAddr
+
': success!'
)
else
:
print
(
'Send email to '
+
EmailAddr
+
': Failed, Pls. retry...'
)
def
SendEmailByBlogComments
(
url
)
:
rsp
=
urllib
.
request
.
urlopen
(
url
)
html
=
rsp
.
read
(
)
.
decode
(
"utf-8"
)
#以列表的形式返回所有匹配邮箱格式的子串
emailList
=
re
.
findall
(
"\w+@\w+\.\w+"
,
html
)
print
(
'Get Email list from CSDN: '
)
print
(
emailList
)
for
emailFromBlog
in
emailList
:
handleEmailAddr
(
emailFromBlog
)
#我的博客网址
url
=
"https://blog.csdn.net/howiexue/article/details/76696316#comments"
SendEmailByBlogComments
(
url
)
if
HasNewEmail
==
False
:
print
(
"No New email found, do nothing... this window will close after 10s"
)
else
:
print
(
"Done! this window will close after 10s"
)
time
.
sleep
(
10
)
2. FileOperation.py
主要是做一些文件类的操作,RecordEmail() 写入邮箱数据到record.txt、isNewEmail() 读取record.txt判断是否是新的邮箱。
def
RecordEmail
(
EmailAddr
)
:
fileName
=
'record.txt'
with
open
(
fileName
,
'a'
)
as
record
:
record
.
write
(
EmailAddr
+
"\n"
)
def
isNewEmail
(
EmailAddr
)
:
fileName
=
'record.txt'
with
open
(
fileName
)
as
record
:
lines
=
record
.
read
(
)
.
splitlines
(
)
#print(lines)
if
EmailAddr
in
lines
:
return
False
else
:
return
True
3. SendEmail.py
这个文件主要是通过MIME来Build邮件数据,然后通过smtplib 发送
# coding:utf-8
# smtplib模块负责连接服务器和发送邮件
# MIMEText:定义邮件的文字数据
# MIMEImage:定义邮件的图片数据
# MIMEMultipart:负责将文字图片音频组装在一起添加附件
import
smtplib
# 加载smtplib模块
from
email
.
mime
.
text
import
MIMEText
from
email
.
utils
import
formataddr
from
email
.
mime
.
application
import
MIMEApplication
from
email
.
mime
.
image
import
MIMEImage
from
email
.
mime
.
multipart
import
MIMEMultipart
sender
=
'howiexue@163.com'
# 我的邮箱,即发件人邮箱账号
passwd
=
''
#这里填的授权码,注意不是邮箱密码,这么Secret的数据当然隐去啦
mailserver
=
'smtp.163.com'
port
=
'25'
sub
=
'CSDN资料密码 By HowieXue'
#用于邮箱的subject
def
SendEmailtoAddr
(
receive
)
:
try
:
msg
=
MIMEMultipart
(
'related'
)
msg
[
'From'
]
=
formataddr
(
[
"Howie"
,
sender
]
)
# 发件人邮箱昵称、发件人邮箱账号
msg
[
'To'
]
=
formataddr
(
[
"BlogUser:"
+
receive
,
receive
]
)
# 收件人邮箱昵称、收件人邮箱账号
msg
[
'Subject'
]
=
sub
#正文,html格式
body
=
"""
资料密码请查收,谢谢关注我的CSDN博客~
博文地址:https://blog.csdn.net/HowieXue/article/details/76696316
Best Regards,
HowieXue(薛永浩)
send by script of
Python3
...
"""
#链接图片,资料实际内容通过图片显示,这样做为了避免163 Server误判为垃圾邮件,图片上是相关资料的网盘地址和密码
text
=
MIMEText
(
body
,
'html'
,
'utf-8'
)
f
=
open
(
r
'C:\**\password.png'
,
'rb'
)
#所插入的图片
pic
=
MIMEImage
(
f
.
read
(
)
)
f
.
close
(
)
pic
.
add_header
(
'Content-ID'
,
'
'
)
msg
.
attach
(
text
)
msg
.
attach
(
pic
)
rew
=
open
(
r
'C:\**\reward.png'
,
'rb'
)
rewPic
=
MIMEImage
(
rew
.
read
(
)
)
rew
.
close
(
)
rewPic
.
add_header
(
'Content-ID'
,
'
'
)
msg
.
attach
(
rewPic
)
server
=
smtplib
.
SMTP
(
mailserver
,
port
)
# 发件人邮箱中的SMTP服务器,端口是25
server
.
login
(
sender
,
passwd
)
# 发件人邮箱账号、邮箱密码
server
.
sendmail
(
sender
,
receive
,
msg
.
as_string
(
)
)
# 发件人邮箱账号、收件人邮箱账号、发送邮件
server
.
quit
(
)
return
True
except
Exception
as
e
:
print
(
e
)
return
False
备注:邮箱SMTP设置
要开启邮箱的SMTP服务,才能通过第三方Client发送邮件,一般邮箱默认是关闭该服务的,需要打开,并设置授权码。
针对·163邮箱,通过设置中修改: