TA的每日心情 | 慵懒 2018-3-29 13:14 |
---|
签到天数: 20 天 连续签到: 1 天 [LV.4]偶尔看看III
|
十分感谢e络盟提供的比赛赞助基金。
一、项目名称:
基于树莓派+Kindle的RSS阅读器
1.原理介绍
本系统通过python编程读取rss源中的内容,首先利用正则表达式提取rss源发布时间,并将rss源中的时间与当前时间进行对比,当在一天以内时则认为是最新数据,将其解析完成后转换为html文件,在利用kindle提供的邮箱推送文档的功能,使用python将生成的html的文件以邮件的方式发送至kindle对应的邮箱,完成rss内容的推送。
2.系统版本
RASPBIAN STRETCH LITE
最新版本下载地址
https://downloads.raspberrypi.org/raspbian_lite_latest
3. 应用源代码:
本系统使用python3.5.3进行编程,首先我们需要安装第三方库feedparser,这里直接使用pip进行安装:包安装完成后,就开始了正式的编程之旅了,首先我们要能解析出rss内容并转换为html文件,这里创建一个类RssParser,代码如下- # -*- coding:utf-8 -*-
- import feedparser
- import date_cmp
- class RssParser:
- def __init__(self, rss_url):
- self.rss = feedparser.parse(rss_url)
- def get_feed_title(self):
- return self.rss.feed.title
- def get_item_cnt(self):
- return len(self.rss.entries)
- def get_item_date(self, index):
- return self.rss.entries[index].updated
- def get_item_title(self, index):
- return self.rss.entries[index].title
- def get_itme_content(self, index):
- return self.rss.entries[index].summary
- def get_item_url(self, index):
- return self.rss.entries[index].link
- def generate_html(self):
- html_template = """
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- </head>
- <body>
- {content}
- </body>
- </html>
- """
- file_name = self.get_feed_title() + '.html'
- html_content = ''
- dateCmp = date_cmp.DateCmp()
- for i in range(self.get_item_cnt()):
- if dateCmp.IsLastest(self.get_item_date(i)):
- item_title = self.get_item_title(i)
- item_content = self.get_itme_content(i)
- item_url = self.get_item_url(i)
- html_content = html_content + '<h2>' + '<a href="' + item_url + '">' + item_title + '</a></h2>\r\n'
- html_content = html_content + '<div class="summary">\r\n' + item_content + '\r\n</div>\r\n'
- if 0 != len(html_content):
- html = html_template.format(content=html_content)
- html = html.encode("utf-8")
- f = open(file_name, 'wb')
- f.write(html)
- f.close()
- return file_name
- else:
- return '\0'
复制代码 如上面代码所示中,feedparser是我们安装的第三方类,date_cmp是自己编写的用于从字符串中解析出时间并与当前时间进行对比的包,当字符串显示的时间与当前时间在一天以内时,则接口函数IsLastest返回True,否则返回False,其代码如下:- # -*- coding:utf-8 -*-
- import re
- import datetime
- class DateCmp:
- def __init__(self):
- self.month_map = {
- 'Jan':'01',
- 'Feb':'02',
- 'Mar':'03',
- 'Apr':'04',
- 'May':'05',
- 'Jun':'06',
- 'Jul':'07',
- 'Aug':'08',
- 'Sep':'09',
- 'Oct':'10',
- 'Nov':'11',
- 'Dec':'12'
- }
- self.date_patton0 = \
- r'(20\d{2})[-/]?((?:[0-9]?|[1-9])[0-9])[-/]?((?:[0-9]?|[1-9])[0-9])?'
- self.date_patton1 = \
- r'([A-Za-z]{3,4}),[ |\t]?((?:[0-9]?|[1-9])[0-9])[ |\t]?([A-Za-z]{3,4})[ |\t]?(20\d{2})'
- self.time_patton = \
- r'((?:[0-9]?|[1-9]])[0-9]):((?:[0-9]?|[1-9]])[0-9]):((?:[0-9]?|[1-9]])[0-9])'
- def Str2Date(self, str):
- year = 0
- month = 0
- day = 0
- hour = 0
- minute = 0
- second = 0
- m = re.findall(self.date_patton0, str) #xxxx-xx-xx xx:xx:xx
- if 0 == len(m):
- m = re.findall(self.date_patton1, str) #aaa, xx aaa xxxx xx:xx:xx
- if 0 == len(m):
- return None
- else:
- year = int(m[0][3])
- month = int(self.month_map[m[0][2]])
- day = int(m[0][1])
- else:
- year = int(m[0][0])
- month = int(m[0][1])
- day = int(m[0][2])
- m = re.findall(self.time_patton, str)
- if 0 != len(m):
- hour = int(m[0][0])
- minute = int(m[0][1])
- second = int(m[0][2])
- else:
- return None
- try:
- b = datetime.datetime(year, month, day, hour, minute, second)
- except ValueError:
- b = None
- return b
- def IsLastest(self, str):
- date_get = self.Str2Date(str)
- if None == date_get:
- return True
- else:
- date_now = datetime.datetime.now()
- date_diff = date_now - date_get
- if date_diff.days < 1:
- return True
- else:
- return False
复制代码 当html文件可以正常生成了,接下来就是使用邮箱发送文件了,python代码如下所示:- # -*- coding:utf-8 -*-
- import smtplib
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- from email.mime.application import MIMEApplication
- class EmailSend:
- def __init__(self):
- self.msg = MIMEMultipart()
- def Login(self, server, user, pwd):
- self.smtp = smtplib.SMTP(server, timeout = 30)
- self.smtp.login(user, pwd)
- self.User = user
- self.Pwd = pwd
- def AddText(self, text):
- part = MIMEText(text)
- self.msg.attach(part)
- def AddAppendix(self, file_name):
- part = MIMEApplication(open(file_name,'rb').read())
- part.add_header('Content-Disposition', 'attachment', filename=file_name)
- self.msg.attach(part)
- def SendEmail(self, to):
- self.msg['Subject'] = 'Convert'
- self.msg['From'] = self.User
- self.msg['To'] = to
- self.smtp.sendmail(self.User, to, self.msg.as_string())
- pass
- def Logout(self):
- self.smtp.close()
复制代码 在上述过程中软件界面如果什么都不显示,会十分单调,这里添加几行python代码,就可以获得树莓派的温度,如下- # -*- coding:utf-8 -*-
- import os
- class RaspberryInfo:
- # Get CPU temperature as a character string
- def GetCpuTemperature(self):
- res = os.popen('vcgencmd measure_temp').readline()
- self.CpuTemperature = res.replace("temp=","").replace("'C\n","")
复制代码 OK,代码都已编写完成了,接下来就是编写一个主程序对上述功能进行调用了,在调用之前,我们先要配置发送邮箱的服务器、用户名和密码、kindle接收邮箱的地址,rss源读取的时间,rss源地址,这些内容分别保存在user_email.txt文件、kindle_email.txt、timer.txt、urls.txt四个文件中,如下所示:
user_email.txt文件- smtp.126.com
- xxxxxx@126.com
- password
复制代码 kindle_email.txt文件timer.txt文件urls.txt文件- http://feed.cnblogs.com/blog/sitehome/rss
复制代码 最后附上主函数实现整个系统的功能- # -*- coding:utf-8 -*-
- from mail_send import EmailSend
- from rss_reader import RssParser
- from get_raspberry_info import RaspberryInfo
- import time
- import datetime
- import sys
- import os
- print('正在启动,请稍后...')
- #读取发送邮箱的用户名和密码
- f = open('user_email.txt', 'rt')
- [server, user, pwd] = f.readlines();
- server = server.strip('\n')
- user = user.strip('\n')
- pwd = pwd.strip('\n')
- f.close();
- #读取发送的kindle邮箱
- f = open('kindle_email.txt', 'rt')
- kindle_email = f.readline()
- kindle_email = kindle_email.strip('\n')
- f.close()
- #读取发送时间
- f = open('timer.txt', 'rt')
- send_time = f.readline()
- send_time = send_time.strip('\n')
- [hour, minute] = send_time.split(':')
- send_hour = int(hour)
- send_minute = int(minute)
- f.close()
- #登录邮箱
- email_send = EmailSend()
- email_send.Login(server,user,pwd);
- #获取rss内容并转换成网页
- f = open('urls.txt', 'rt')
- urls = f.readlines()
- #获取当前时间,当到达发送时间时,则读取rss内容,转换为html并发送至kindle邮箱
- while True:
- now_time = datetime.datetime.now()
- #达到发送时间
- if now_time.hour == send_hour and now_time.minute == send_minute:
- for url in urls:
- url = url.strip('\n')
- rss = RssParser(url)
- file_name = rss.generate_html()
- if file_name != '\0':
- email_send.AddAppendix(file_name)
- email_send.SendEmail(kindle_email)
- print('send email success ')
- time.sleep(90)
-
- else:
- #显示树莓派信息
- rsp_info = RaspberryInfo()
- rsp_info.GetCpuTemperature()
- info = 'CPU 温度:' + rsp_info.CpuTemperature
- time_info = ' 当前时间:%d:%d:%d \r ' % (now_time.hour, now_time.minute, now_time.second)
- sys.stdout.writelines(' \r')
- sys.stdout.writelines(info + time_info)
- time.sleep(1)
复制代码 4. 硬件连线图
本系统只需要一块树莓派即可,真的要连的话就用网线把树莓派和路由器连起来好了!
5. 演示视频
由于从采集完成到发送邮件到kindle接收,是一段比较长的时间,且中间过程没有任何可以演示的地方,因此这里就发几张截图好了,一样可以看出效果哦。
图一:等待过程中,显示树莓派CPU温度和当前的时间
图一
图二:为了防止作假,我们先看看kindle里面可是只有几本电子书哦
图二
图三:rss获取时间到了,邮件发送完成后会有一条提示信息:send email success
图三
图四:kindle已经收到推送了,好开心!
图四
图五:迫不及待的打开看看里面的内容
图五
图六:唯一不太方便的就是,rss源里的内容只是一些概要,要想看详细内容,需要理由kindle的浏览器
图六
|
|