专栏首页Python爬虫实战用Python推送书籍到Kindle

用Python推送书籍到Kindle

很早以前买了 Kindle,为了省钱在网络上找过不少电子书,它有一点好处就是可以自己导入书籍,更好的是可以通过电子邮件的方式发送到 Kindle 上,本文就来一步步实现一个书籍推送软件。

1、邮件的几种协议介绍

以下科普内容来自:http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html。

POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。

SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。   SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。   增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。

IMAP全称是Internet Mail Access Protocol,即交互式邮件存取协议,它是跟POP3类似邮件访问标准协议之一。不同的是,开启了IMAP后,您在电子邮件客户端收取的邮件仍然保留在服务器上,同时在客户端上的操作都会反馈到服务器上,如:删除邮件,标记已读等,服务器上的邮件也会做相应的动作。所以无论从浏览器登录邮箱或者客户端软件登录邮箱,看到的邮件以及状态都是一致的。

本文采用 SMTP 协议。

2、邮件发送简单测试

Python 的标准库提供了对 SMTP 的支持,可以用来发送纯文本、HTML和带附件的邮件。要想发送邮件需要用到两个库:email(用来构造邮件)smtplib(用来发送邮件)

2.1 纯文本邮件

用以下两行代码构造一个纯文本格式的邮件正文:

from email.mime.text import MIMEText
msg = MIMEText("This is a email test send by python.", 'plain', 'utf-8')

MIMEText 的原型为:

class email.mime.text.MIMEText(_text[, _subtype[, _charset]])

参数说明:

  • _text :文本格式的邮件正文
  • _subtype :MIME 的类型,默认值为 plain,即指定 MIME 的类型为 'text/plain'
  • _charset:正文的编码,默认值为us-ascii,一般指定为 'utf-8'

创建 SMTP 对象语法如下:

import smtplib

server = smtplib.SMTP( [host [, port [, local_hostname]]] )

参数说明:

  • host:SMTP 服务器主机地址,比如126邮箱服务器地址为smtp.126.com, QQ邮箱服务器地址为smtp.qq.com
  • port:如果提供了 host 参数, 需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25
  • local_hostname:如果 SMTP 在本机上,只需要指定服务器地址为 localhost 即可。

Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])

参数说明:

  • from_addr: 邮件发送者地址。
  • to_addrs:字符串列表,邮件发送地址。
  • **msg **:发送消息

下面就是一个完整的纯文本邮件的发送测试程序:

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

def smtp_text():
    """纯文本格式邮件"""
    from_address = "xxxx@126.com"   # 改成自己的邮箱地址
    password = "xxxx"               # 改成自己的邮箱密码

    # smtp 服务器地址
    smtp_address = "smtp.126.com"

    # 目标地址
    to_address = "xxxx@qq.com"    # 改成要发送的目的地址
    try:
        # 邮件内容
        msg = MIMEText("This is a email test send by python.", 'plain', 'utf-8')
        msg['From']= formataddr(["sender",from_address])   #括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To']= formataddr(["receiver",to_address])   #括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject'] = 'Python SMTP 邮件测试' #邮件的主题,也可以说是标题
        server = smtplib.SMTP(smtp_address, 25)
        server.login(from_address, password)
        server.sendmail(from_address, [to_address], msg.as_string())
        server.quit()
        print('邮件发送成功!')
    except Exception as e:
        print("There is a exception:", e)

if __name__ == "__main__":
    smtp_text()

来看一下执行结果:

01_文本邮件测试

2.2 HTML邮件

发送HTML格式的邮件,只需要把 MIMEText 对象的 _subtype 设置为 html 即可。

msg_content = """
<p>Python HTML格式邮件发送测试...</p>
<p><a href="http://www.baidu.com">这是一个指向百度的链接</a></p>
"""
msg = MIMEText(msg_content, 'html', 'utf-8')

发送结果:

02_HTML邮件测试

2.3 带附件的邮件

如果要发送带附件的邮件,我们需要构造一个 MIMEMultipart 对象,然后想该对象中添加其他的 MIME 对象。如下代码即可实现有文本内容和附件的邮件发送:

from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

def smtp_attachment():
    """HTML格式邮件"""
    from_address = "xxxx@126.com"  # 改成自己的邮箱地址
    password = "xxxx"       # 改成自己的邮箱密码

    # smtp 服务器地址
    smtp_address = "smtp.126.com"

    # 目标地址
    to_address = "xxxx@qq.com"    # 改成要发送的目的地址
    try:
        msg = MIMEMultipart()
        msg['From']= formataddr(["sender",from_address])   #括号里的对应发件人邮箱昵称、发件人邮箱账号
        msg['To']= formataddr(["receiver",to_address])   #括号里的对应收件人邮箱昵称、收件人邮箱账号
        msg['Subject'] = 'Python SMTP 邮件测试' #邮件的主题,也可以说是标题

        #邮件正文内容
        msg_text = MIMEText('This is a email test send by python.', 'plain', 'utf-8')
        msg.attach(msg_text)

        # 邮件附件
        msg_attachment = MIMEApplication(open('货币崛起.mobi','rb').read()) 
        msg_attachment.add_header('Content-Disposition', 'attachment', filename='货币崛起.mobi')  
        msg.attach(msg_attachment)

        server = smtplib.SMTP(smtp_address, 25)
        server.login(from_address, password)
        server.sendmail(from_address, [to_address], msg.as_string())
        server.quit()
        print('邮件发送成功!')
    except Exception as e:
        print("There is a exception:", e)

发送结果:

03_带附件的邮件测试

当然,可以构造多个 MIMEApplication 然后添加到 msg 当中,就能够实现发送多个附件的效果了。

3、推送书籍到Kindle

3.1 查看设备收件地址

购买的 Kindle 每个设备都会绑定一个邮箱作为收件地址,格式类似于:xxxx_xx@kindle.cn。可以在 Kindle 中 全部设置->我的账户 的最下面查看该设备的邮件地址:

04_Kindle设备地址查看

3.2 代码实现

为了方便使用,需要做一个带界面的程序,首选 PyQt

3.2.1 PyQt5安装

可以直接使用 pip 指令安装:pip install pyqt5

3.2.2 布局设计

下图中标注了总体的布局和每个部件的类型,没错,就是要做成这样的。

05_软件布局

布局部分代码:

maingrid = QGridLayout()
fromLB = QLabel('邮箱:')
self.fromLnE = QLineEdit()
pwdLB = QLabel('密码:')
self.pwdLnE = QLineEdit()
self.pwdLnE.setEchoMode(QLineEdit.Password)
kdlLB = QLabel('Kindle地址:')
self.kdlLnE = QLineEdit()
self.chooseBtn = QPushButton('选择文件')
self.pushBtn = QPushButton('推送')
self.infoTxt = QTextEdit()
self.infoTxt.setFixedHeight(200)
...
maingrid.addWidget(fromLB, 0, 0)
maingrid.addWidget(self.fromLnE, 0, 1)
maingrid.addWidget(pwdLB, 1, 0)
maingrid.addWidget(self.pwdLnE, 1, 1)
maingrid.addWidget(kdlLB, 2, 0)
maingrid.addWidget(self.kdlLnE, 2, 1)
maingrid.addWidget(self.chooseBtn, 3, 0)
maingrid.addWidget(self.pushBtn, 3, 1)
maingrid.addWidget(self.infoTxt, 4, 0, 1, 2)

来看一下最终的实际效果:

06_最终效果图

3.2.3 文件选择

本软件要实现的是可以一次性发送多个书籍文件,书籍格式为epub或者mobi

def chooseBooks(self):
        self.file = QFileDialog.getOpenFileNames(self, "Open File","D:","books (*.mobi *.epub)")    # 筛选文件后缀;可以多选
        self.infoTxt.append('您选中了{}本书:{}'.format(len(self.file[0]), str(self.file[0])))   # 获取选中文件的

以上两行代码就可以弹出一个文件对话框,我们就可以愉快的选择我们要推送的书籍了。

07_选择文件

最后将上一小节发送带附件邮件的代码加上,整个程序完成。

发送结果示例:

08_发送结果

Kindle端结果:

09_Kindle端结果

4、完整代码获取

有两种方式可以获取到完整代码:

4.1单次获取

扫描下方二维码,进入微店购买,付款成功后,预留的手机号码会收到一条短信,里面有下载链接。

4.2一劳永逸增值版

本公众号的原创文章也会同步发表在付费专栏 《小专栏》中,但是发表在《小专栏》中的文章里包含有完整的代码,不需要再去网盘下载。

专栏链接:https://xiaozhuanlan.com/C_Python

也可以扫描二维码进行订阅:

大家订阅后就可以查看全部的内容,代码也就获取到了:

本文分享自微信公众号 - C与Python实战(CPythonPractice),作者:CPython

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 数字华容道03:首页创建

    整个布局采用 QVBoxLayout (竖型布局)。最上方的“数字华容道”字样是一张图片,采用QLabel进行展示。下面几个选择难度的按钮和排行榜按钮采用 QP...

    王强
  • 看了《最强大脑》,我决定做这个游戏

    今年年初,新一季的《最强大脑》开播了,第一集选拔的时候大家做了一个数字游戏,名叫《数字华容道》,当时何猷君以二十几秒的成绩夺得该项目的冠军,来看一下当时的比赛:

    王强
  • numpy基础操作快速入门

    由于numpy不是python自带库,需要自己下载安装(如果用的是Anaconda,则不需要再去下载numpy库,因为其自带python环境以及许多第三方pyt...

    王强
  • 如何在DataGrid里面产生滚动条而不滚动题头

    我们在开发的时候一定遇到,使用DataGrid的时候由于不想分页(数据没有那么多)但是又显示不在一页里面,此时我们希望在DataGrid里面出现一个滚动条,可以...

    阿新
  • 老牌论坛程序Discuz宣布回归了

    相信这个消息很多朋友已经知道了,官方于11月13日发布通知,我也是最近才知道的,就赶紧给大家分享出来!

    申霖
  • Emlog 熊掌号页面改造

    首先在打开网站模版目录/content/templates/,找到header.php文件,打开后在<head></head>标签内添加如下代码:

    陌涛
  • excel查询数据的技术实现选择 (r7笔记第73天)

    最近有一个高中同学问我一件事情,就是他们目前使用excel需要经常查很多数据,但现在使用excel的筛选功能感觉比较费劲。想问问我有没有什么改进 的方法,对于我...

    jeanron100
  • Python的classmethod修饰符

    classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化...

    于小勇
  • 一种解决启动进程传递参数过长的方法

            工作中,QA同学在测试我们程序的时候,发现在XP下,我们的A进程无法启动我们的B进程。而在Win7 64bit系统下功能正常。RD同学调试后,发...

    方亮
  • CMU 神经网络 NLP 更新 | 第五讲:语句或语言建模的循环神经网络

    AI 研习社获得官方授权,汉化翻译卡耐基梅隆大学的11-747神经网络自然语言处理(2019春季),今天上线第五讲!

    AI研习社

扫码关注云+社区

领取腾讯云代金券