最近学习了利用python爬虫,甚是有趣。所以写了个试用的小程序分享出来。
学院的相关通知都会放在网站的信息公告上,但每天打开电脑->打开浏览器->打开学院网站,就为了看个信息公告,挺麻烦还容易忘记。但害怕错过重要通知,又不得不看。
所以,我就想,能不能让我的云服务器自动爬取学院网站的信息公告,把信息公告做HTML格式的e-mail,然后每天早上9点钟定时自动给我发一封邮件呢。在这封邮件里面,我可以看到最近发布的通知,点击通知能够直接链接到通知详情页面。
说干就干,代码其实也就几十行而已。
首先介绍下代码中用到的一些python库:
from bs4 import BeautifulSoup
import requests
import codecs
import smtplib
from email.mime.text import MIMEText
import time
其中,BeautifulSoup是爬虫库,用来解析HTML网页;requests库用于向学校网站发送请求,GET下来网页;codecs是个编码库,可以用'utf-8'编码格式打开文件;stmplib是发送邮件用的;time用于定时。
【步骤1】锁定信息公告在HTML的位置
class GrabNews():def __init__(self):self.NewsList = []def getNews(self):url = 'http://eis.whu.edu.cn/index.shtml'r = requests.get(url)soup = BeautifulSoup(r.text, "html.parser")newsTitle = soup.find(text="信息公开")newsList = newsTitle.parent.next_sibling.next_sibling.find_all('a')for news in newsList:for string in news.stripped_strings:newsUrl = 'http://eis.whu.edu.cn/' + news['href']self.NewsList.append({string:newsUrl})
首先,我们要在浏览器中打开学院含有信息公告的网页,按F12去看信息公告到底在HTML文件的什么位置。 通过Beautifulsoup可以很轻松定位到信息公告。
【步骤2】拿到通知的标题和链接,写入HTML本地文件中
def getNews():grabNews = GrabNews()grabNews.getNews()fp = codecs.open('news.html', 'w', 'utf-8')for news in grabNews.NewsList:for key in news.keys(): # key:value. key是新闻标题,value是新闻链接#fp.write(key+'\n')#fp.write(news[key]+'\n')fp.write('<a href=%s>%s</a>' % (news[key], '*'+key))fp.write('<hr />')fp.close()
这里面实例化了一个GrabNews类,从这个类中可以获取通知的标题和链接,存放在“news.html”中。每个通知做成链接形式,用水平线<hr />隔开。
【3】发送HTML格式的邮件
def sendNews():# 第三方 SMTP 服务mail_host = 'smtp.sina.com' # SMTP服务器mail_user = 'your_username@sina.com' # 用户名mail_pass = 'your_password'# 收发方地址sender = 'your_username@sina.com' # 发件人邮箱receivers = ['reciver_username@qq.com'] # 接收邮件# 从HTML文件中读取发送邮件的内容fp = open('news.html')message = MIMEText(fp.read(), 'html', 'utf-8') #内容, 格式, 编码fp.close()# 补全消息头部信息message['Subject'] = '电信院信息公告'message['From'] = "{}".format(sender)message['To'] = ",".join(receivers)try:smtpObj = smtplib.SMTP(mail_host, 25) # SMTP协议默认端口是25smtpObj.login(mail_user, mail_pass) # 登录验证smtpObj.sendmail(sender, receivers, message.as_string()) # 发送print('mail has been send successfully.')except smtplib.SMTPException as e:print(e)
我这里是通过SMTP协议,从我的新浪邮箱,发送到我的qq邮箱。 注意需要先登录,再发送,消息头部信息‘Subject', 'From', 'To'不要忘记。
这里需要注意的是,如果你填写的邮箱用户名和密码都是正确的,但发现登录失败。 那么最大的可能,就是你的邮箱为开通SMTP服务,这是后你可以通过浏览器登录邮箱,在“设置”中开启SMTP服务,这时候你会得到一个授权码。再返回代码中,将邮箱密码替换为授权码即可成功登录。
【4】程序入口,定时发送
if __name__ == '__main__':while(True):if('09:00'==time.strftime('%H:%M')):getNews()sendNews()time.sleep(61) # 等待一分钟以上else:time.sleep(30) # 每30秒查询一次系统时间
通过time.strftime获取当前系统时间,每天早上’09:00“准时发送邮件。 这里time.sleep(61)如果去掉的话,你在这一分钟内就会不停地收到同一封邮件。哈哈
上个图: