最近入手一部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实现自主文件发送的更多相关文章

  1. Redis学习笔记~conf自主集群模式

    回到目录 Redis自主提供了集群模式,当然也只是比较简单的读写分离模式,或者叫主从模式,它在各个redis服务端自己做数据同步机制,当然就是将主服务端的信息同步到各个slave服务器上,在客户端集成 ...

  2. WebApi系列~自主宿主HttpSelfHost的实现

    回到目录 宿主一词我们不会陌生,它可以看作是一个基础设施,它为一些服务和功能提供最底层的支持,如你的web应用程序可以运行在iis或者apache上,而这两个东西就是web应用程序的宿主,而今天说的自 ...

  3. 极客DIY:制作一个可以面部、自主规划路径及语音识别的无人机

    引言 现在大部分无人机厂商都会为第三方开发者提供无人机API接口,让他们更容易地开发无人机飞行控制应用程序,让无人机想怎么玩就怎么玩.有的API接口可以帮助开发者开发基于Web版的APP.手机APP甚 ...

  4. 热烈庆祝华清远见成功自主研发Farsight TV 智能机顶盒

    近日,华清远见研发中心再传喜讯:Farsight TV 智能机顶盒研发成功并投入教学!这是华清远见研发中心继开源平板电脑.智能医疗终端.智能家居终端后独立成功研发的又一智能硬件!至此,开创了华清远见自 ...

  5. Windows 系统下json 格式的日志文件发送到elasticsearch

    Windows 系统下json 格式的日志文件发送到elasticsearch配置 Nxlog-->logstash-->ElasticSearch Logstash https://ww ...

  6. 再谈自主开发与企业IT管理

    前两天写<自主开发与带兵打仗>分析了一下自主开发的利与弊,得到了园内不少朋友的反馈,但我觉得还有很多东西没有交待清楚,可能有很多朋友也跟我一样在公司的IT部门,有自己的研发团队也有很多外购 ...

  7. 《黄聪:手机移动站SEO优化教程》4、如何实现手机移动网站和PC站点的自主适配

    视频地址:http://www.tudou.com/programs/view/v4Hur5vjav4/ 1.自主适配 A:站点自己做好PC与手机之间的适配,以及手机站各个版式之间的适配.当手机用户通 ...

  8. asp天猫自主发码的请求

    这几天在做天猫自主发码.实现了通知和核销部门.其他的部分待后续实现. 值得注意的是consume回调中,要加入sign_method=md5

  9. 揭秘淘宝自主研发的文件系统:TFS

    目前,国内自主研发的文件系统可谓凤毛麟角.淘宝在这一领域做了有效的探索和实践,Taobao File System(TFS)作为淘宝内部使用的分布式文件系统,针对海量小文件的随机读写访问性能做了特殊优 ...

随机推荐

  1. 介绍几个python的音频处理库

    一.eyeD3 直接在google上搜索python mp3 process ,推荐比较多的就是这个第三方库了.先来看看官方介绍吧. About eyeD3 is a Python tool for ...

  2. Java IO详解(一)------File 类

    File 类:文件和目录路径名的抽象表示. 注意:File 类只能操作文件的属性,文件的内容是不能操作的. 1.File 类的字段 我们知道,各个平台之间的路径分隔符是不一样的. ①.对于UNIX平台 ...

  3. jqPaginator 项目中做分页的应用技巧

    最近做后台管理系统,分页用到的不少,项目中其实已经有分页功能的组件但是不够高度自定义,于是就找到了 jqPaginator 高度自定义的Html结构 初始化引用如下: $("#paginat ...

  4. 计算facebook sdk需要的key hashes

    1. 下载openssl,在C盘创建openssl文件夹,解压下载的zip到openssl文件夹. 2. 找到debug.keystore. windows下在C:\Users\用户名\.androi ...

  5. 小程序的1024KB

    1024kb 只是一个目前编译后代码可上传最大限制,至于后期会不会更改,不得而知.个人只是想借 1024kb 来和大家一起交流一下,如何在限制下,挥舞大刀- 微信官方回答了,为什么有 1024kb 的 ...

  6. Java基础知识二次学习--第六章 常用类

    第六章 常用类   时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ...

  7. 关于QT按键信号槽的总结(原创)

    QT界面按钮一般是必填的: 每个按钮都要 Go to slot 下面有几个都是常用的,先说一下 clicked:pressed:releaed的区别 字面意思看:click是点击一下,pressed是 ...

  8. 地理位置 API

    js获取地理位置的接口navigator.geolocation geolocation对象有三个方法 1.getCurrentPosition 2.watchPosition 3.clearWatc ...

  9. 一、Openstack_Ocata环境部署准备

    OpenStack Ocata环境搭建准备 1.workstation下配置3个虚拟交换机 点击编辑-->虚拟网络编辑器 名称 IP地址 作用 VMnet1 10.1.1.0 Openstack ...

  10. 一篇%3CDIV%20style%3D%22FONT-SIZE%

    %3CDIV%20style%3D%22FONT-SIZE%3A%2016px%22%3E1%EF%BC%8C%E6%88%91%E4%BB%A5%E4%B8%BA%E7%BB%88%E6%9C%89 ...