使用kindlegen实现自主文件发送
最近入手一部kindle,本着努力学习的想法,想通过它来提高自己的英文阅读水平,不过,入手之后,发现用来看杂文的时间远大于看英文文章的时间,时间罪过,为了减轻自己的负罪感,决定要用它来实现最初的作用, 用来阅读一些文献,可是放眼望去,现在网上大部分的kindle推送功能一般不会有这方面的内容,大部分的是为了吸引读者,放一些网络小说上来,最可恶的还有的要收费,按月付,按周付各种付费方法,只有你想不到,没有他想不到的,于是想自己做一个推送,毕竟这年头流行私人定制吗。
说干就干,首先要理清一下思路,第一,我需要了解推送的原理,第二,我需要构建推送的文章。好了,先来解决第一部:推送原理
经百度大叔的指导发现:每部kindle都有一个自己的@kindle.com的邮箱,这个一般放在【设置】-【全部设置】-【我的账户】-【发送至Kindle】电子邮件地址,我的是paperwhite,是在这个位置,可能其他型号的不住这位置,不过应该很好找,好了,这个邮箱就是用来当作被发送的邮箱,就是说你只要往这个邮箱里面发生kindle可以识别格式的文件,那么他就会下载到你的kindle里面,但是不可能什么人都可以发送对吧,不然你的kindle会变成垃圾箱,因此首先要登录亚马逊邮箱,打开【我的账户】列表里面【管理我的设备和内容】,选择【设置】,找到如【以认可的发件人邮箱地址】,添加即可如同
所以这第一步就算完成一半了,为什么是一半,因为要编程自主实现啊!
好了,第二个问题,构建推送的文章,这是我需要的文章地址:http://www.tandfonline.com/toc/ilab20/54/3?nav=tocList,我需要最新的文章,那么简单的说,就是每次有最新的文章我都要会自动发送到我的kindle,但是这个杂志两个月才发一次刊,所以基本上我可以手动来操作,没必要再去自动实现。因此我准备只写一个小工具来抓取这个内容,融合可以自动发送到kindle邮箱。
要想实现自动抓取,也就是爬虫,我选择比较熟悉的selenium+phantomJS框架来实现,其实一开始我使用的pyqt5.qtwebKitengine来实现,可是速度太慢,特别着急,所以就改用这个组合。phantomjs是一个无界面浏览器,selenium是一个自动化测试框架,基于python实现的。好了,直接上代码,简简单单几行就搞定:
首先建立虚拟环境,然后在虚拟环境里面操作,导入webdriver和etree两个子模块
通过webdriver.PhantomJS()来建立浏览器驱动,也可以利用本机电脑上的火狐和谷歌浏览器,形如webdriver.Chrome()或者webdriver.Firefox()
接着通过get方法来连接目标网址,通pageg_source属性来获取整个html代码,这个方法比较适合动态网页的获取,一些常用ajax方法处理的动态网页很难获取实际的标签里面的内容,但是通过这种加载到浏览器引擎里面之后就可以全部实现ajax代码的完全运行。不过要提的是这个属于国外网站,国外网站的访问速度,四个字苦不堪言,呜呜
接下来就是解析里面我要的内容:
通过lxml模块来解析成树模型,然后通过xpath来解析:
如图,解析出了文献的题目和相对地址,然后接着做成绝对地址访问截取其中的文献内容就行。
那么解析出来的文章怎么做成kindlegen识别的格式mobi格式呢
这是网上的图片,说的是mobi格式包含的文件,其实还可以有自定义的css,kindlegen这个工具是亚马逊推出的命令行生成mobi工具,目标文件为opf文件,加入手上有paper.html,paper.opf,toc.html,toc.ncx,另外附加图片,css等文件,只要执行kindlegen paper.opf就可以生成mobi文件,因此我们需要构建paper.html,paper.opf,toc.html,toc.ncx文件,这里大家请参考:http://www.cnblogs.com/buptzym/p/5249662.html这篇文章,我同样选用的是jinja2模块,如果没有安装,可以通过pip install jinja2安装,因为我之前一直在看flaskweb编程,flask使用的就是jinja2模块,所以有些选用这个模块
- <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="BookId">
- <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
- <dc:title>{{ title }}</dc:title>
- <dc:language>en-us</dc:language>
- </metadata>
- <manifest>
- <!-- table of contents [mandatory] -->
- <item id="toc" media-type="application/x-dtbncx+xml" href="toc.ncx"/>
- <item id="tochtml" media-type="application/xhtml+xml" href="toc.html"/>
- {% for item in navigation %}
- <item id="{{ item.id }}" media-type="application/xhtml+xml" href="{{ item.href }}"/>
- {% endfor %}
- {% for item in media %}
- <item id="{{ item.id }}" media-type="image/{{ item.format}}" href="{{ item.href}}"/>
- {% endfor %}
- </manifest>
- <spine toc="{{ title }}">
- <!-- the spine defines the linear reading order of the book -->
- <itemref idref="toc"/>
- <itemref idref="tochtml"/>
- {% for item in navigation %}
- <itemref idref="{{ item.id }}"/>
- {% endfor %}
- </spine>
- <guide>
- <reference type="toc" title="Table of Contents" href="toc.html"></reference>
- <reference type="text" title="Welcome" href="toc.html"></reference>
- </guide>
- </package>
这里我直接复制的上述网址大神的代码,因为我只要把item这个变量变成paper就可以了,所以对于我来说,这个代码可以直接拿来用.
那现在只要写个bat文件将"kindlegen.exe paper.opf"写入进去,前提,kindlegen直接写路径或者设置环境变量就可以生成目标mobi文件
那么文件生成了,怎样将其发送到指定的邮箱呢:我选用smtplib模块,先构建一个smtp类,再传入paper参数,如图
- import smtplib
- import email.MIMEMultipart
- import email.MIMEText
- import email.MIMEBase
- from email.utils import parseaddr, formataddr
- import os.path
- class smtp:
- def __init__(self,paper):
- self.paper=paper
- self.From='你的邮箱'
- self.To='你的kindle邮箱'
- self.server = smtplib.SMTP("smtp.126.com")
- def mimneMultipart(self):
- # 构造MIMEMultipart对象做为根容器
- main_msg = email.MIMEMultipart.MIMEMultipart()
- # 构造MIMEText对象做为邮件显示内容并附加到根容器
- text_msg = email.MIMEText.MIMEText("kindle sendding machine")
- main_msg.attach(text_msg)
- # 构造MIMEBase对象做为文件附件内容并附加到根容器
- contype = 'application/octet-stream'
- maintype, subtype = contype.split('/', 1)
- ## 读入文件内容并格式化
- data = open(self.paper, 'rb')
- file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
- file_msg.set_payload(data.read( ))
- data.close( )
- email.Encoders.encode_base64(file_msg)
- ## 设置附件头
- basename = os.path.basename(file_name)
- file_msg.add_header('Content-Disposition','attachment', filename = basename)
- main_msg.attach(file_msg)
- # 设置根容器属性
- main_msg['From'] = self.From
- main_msg['To'] = self.To
- main_msg['Subject'] = "convert"
- main_msg['Date'] = email.Utils.formatdate( )
- # 得到格式化后的完整文本
- fullText = main_msg.as_string( )
- # 用smtp发送邮件
- try:
- self.server.sendmail(self.From, self.To, fullText)
- finally:
- self.server.quit()
这样就基本实现自己的kindle文章的定制,以上代码参考了大量网上大神的,因为我不喜欢重复造轮子,嘿嘿!
使用kindlegen实现自主文件发送的更多相关文章
- Redis学习笔记~conf自主集群模式
回到目录 Redis自主提供了集群模式,当然也只是比较简单的读写分离模式,或者叫主从模式,它在各个redis服务端自己做数据同步机制,当然就是将主服务端的信息同步到各个slave服务器上,在客户端集成 ...
- WebApi系列~自主宿主HttpSelfHost的实现
回到目录 宿主一词我们不会陌生,它可以看作是一个基础设施,它为一些服务和功能提供最底层的支持,如你的web应用程序可以运行在iis或者apache上,而这两个东西就是web应用程序的宿主,而今天说的自 ...
- 极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机
引言 现在大部分无人机厂商都会为第三方开发者提供无人机API接口,让他们更容易地开发无人机飞行控制应用程序,让无人机想怎么玩就怎么玩.有的API接口可以帮助开发者开发基于Web版的APP.手机APP甚 ...
- 热烈庆祝华清远见成功自主研发Farsight TV 智能机顶盒
近日,华清远见研发中心再传喜讯:Farsight TV 智能机顶盒研发成功并投入教学!这是华清远见研发中心继开源平板电脑.智能医疗终端.智能家居终端后独立成功研发的又一智能硬件!至此,开创了华清远见自 ...
- Windows 系统下json 格式的日志文件发送到elasticsearch
Windows 系统下json 格式的日志文件发送到elasticsearch配置 Nxlog-->logstash-->ElasticSearch Logstash https://ww ...
- 再谈自主开发与企业IT管理
前两天写<自主开发与带兵打仗>分析了一下自主开发的利与弊,得到了园内不少朋友的反馈,但我觉得还有很多东西没有交待清楚,可能有很多朋友也跟我一样在公司的IT部门,有自己的研发团队也有很多外购 ...
- 《黄聪:手机移动站SEO优化教程》4、如何实现手机移动网站和PC站点的自主适配
视频地址:http://www.tudou.com/programs/view/v4Hur5vjav4/ 1.自主适配 A:站点自己做好PC与手机之间的适配,以及手机站各个版式之间的适配.当手机用户通 ...
- asp天猫自主发码的请求
这几天在做天猫自主发码.实现了通知和核销部门.其他的部分待后续实现. 值得注意的是consume回调中,要加入sign_method=md5
- 揭秘淘宝自主研发的文件系统:TFS
目前,国内自主研发的文件系统可谓凤毛麟角.淘宝在这一领域做了有效的探索和实践,Taobao File System(TFS)作为淘宝内部使用的分布式文件系统,针对海量小文件的随机读写访问性能做了特殊优 ...
随机推荐
- Gulp和webpack的区别,是一种工具吗?
疑问:gulp和webpack 什么关系,是一种东西吗?可以只用gulp,不用webpack吗 或者反过来? 它们的区别和概念 ------------------------------------ ...
- vim - manual -个人笔记
##vim配置 ###normal > 输入命令:w 写入保存 > > 粘贴 :p(向下粘贴) P(大写向上粘贴) > > 复制 :yy 复制一行 > > 删 ...
- MySQL ProxySQL读写分离实践
目的 在上一篇文章MySQL ProxySQL读写分离使用初探里初步介绍了ProxySQL的使用,本文继续介绍它的一些特点和DBProxy的性能差异.深入一些去了解ProxySQL,通过测试来说明Pr ...
- CSS之BFC及其应用
BFC是Block Formatting Context的缩写,直译过来就是"块级格式化上下文".先不管它到底是什么,看一个例子: .parent{ border: 1px sol ...
- sublime text3 支持终端打开文件
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl
- iOS crash日志分析
iOS crash日志分析 一. 寻找crash文件:手机崩溃后的ips或者crash文件(ips文件可以直接修改成crash文件,直接改后缀名就可以了),这里说下如何拿到crash文件 1. 把运行 ...
- mongo - 升级步骤
升级步骤1. 关闭balancer登陆mongos,执行sh.stopBalancer(),或者 连接到mongos>use config>db.settings.update( { _i ...
- MySQL定时逻辑备份
当项目数据量不大时,备份可以采用逻辑备份. 数据库可以搭建一主一从,从库每天凌晨三点全量逻辑备份. 然后同时记录二进制文件,用来进行基于时间点的数据恢复. 其他备份方案详见我的思维导图:MySQL备份 ...
- 刨根究底字符编码之七——ANSI编码与代码页(Code Page)
ANSI编码与代码页(Code Page) 一.ANSI编码 1. 如前所述,在全世界所有国家和民族的文字符号统一编码的Unicode编码方案问世之前,各个国家.民族为了用计算机记录并显示自己的字符, ...
- Weka算法介绍
RWeka (http://cran.r-project.org/web/packages/RWeka/index.html) : 1) 数据输入和输出 WOW():查看Weka函数的参数. Weka ...