网页转换为EPUB/PDF电子书

2017-07-06|Categories: Web app|Tags: , |

目的

如今的互联网充斥着广告和吸引用户眼球的内容,这些对用户而言绝大多数都是噪音,想要在互联网上心无旁骛的阅读学习越来越难。如果能够去除噪音,把网页正文作为电子书下载下来,配合其它专门为了阅读学习而设计的工具,绝对是一件有价值的事。

目前最流行的电子书格式是pdf、epub,相关的标准最为成熟,工具非常丰富。虽然Amazon Kindle用户众多,但标准和工具还是相形见绌。

对于把网页转换为电子书,不同人有不同需求,最基本的需求是保证转换后的内容完整即可,而我要转换的内容通常包含大量代码,因此还必须确保代码格式完整。

简单方案

如果只需要简单的提取正文、去除噪音,这里有两个开箱即用的简单方案,都是Chrome浏览器插件(需要翻墙):

以下是功能对比:

对比项目 dotEPUB EpubPress Save As eBook
可转换格式 epub, mobi epub, mobi epub
是否由服务器转换
是否转换整个网页 服务器自动判断注1 ,仅转换正文 服务器自动判断注1 ,仅转换正文 注2
是否允许屏蔽图片
允许转换图片数量 <=10张注3 总数量:<=30张
总容量:每篇文章<=1M
所有
单次转换网页数量 1 50 上限未知
多网页转换便利度 N/A ★★★★★注7 ★★★★
转换内容完整度 ★★★★ ★★注4 ★★★★★
转换格式美观度 ★★★★★ ★★注5 ★★★
转换速度 ★★★ ★★★★ ★★★★★
推荐程度 ★★★★ ★★ ★★★注6
  • 注1:服务器判断的正文通常是指「大段连续的文字」,视频、网友评论都不算正文,但在实际使用中发现,某些正文内容因为篇幅相对较短,会判断错误而被丢弃(详见下文截图),用户对此无法干预。
  • 注2:Save As eBook对正文的判断标准更宽松,原因可能是转换不依赖服务器,不需要使用严苛标准来节约服务器资源。
  • 注3:超过数量的图片会被替换成链接。
  • 注4:即使在服务器判断之后转换的正文部分,EpubPress仍然会莫名其妙丢失内容(详见下文截图)。
  • 注5:EpubPress转换的图片会始终跟随epub阅读器窗口尺寸缩放,小图片会变得很模糊。
  • 注6:Save As eBook允许用户决定要转换的内容,非常适合结构复杂的网页,但需要一些HTML/CSS/JS技能,普通用户可能没有耐心折腾。
  • 注7:直接勾选多个打开的标签页即可转换。

高级方案

工具

面对结构复杂的网页时,前面的两个「傻瓜式」工具就力不从心了,必须寻找更高级的方案。这个方案需要以下工具:

  • Save As eBook:Chrome插件,用于提取网页正文(以下简称SAE)
  • TamperMonkey:Chrome插件,用于给网页注入用户编写的JS代码,修改网页结构
  • Sigil:epub编辑器
  • calibre:一站式电子书解决方案,可以编辑、阅读、管理多种格式的电子书

接下来以鸟哥的Linux私房菜为例,展示以上工具搭配使用的流程。

首先展示转换结果对比(点击图片查看清晰大图):

工具 页头 页中 页尾
原始网站
原始网站 2
dotEPUB
EpubPress
SAE
SAE 2
SAE 3

从截图可以看出:

工具 页头 页中 页尾
dotEPUB
  • ✅丢弃顶部banner、左侧导航
  • ✅保留正文链接
  • ✅识别小标题、代码块
  • ❌丢弃重点回顾、习题、参考资料
  • ✅丢弃底部banner
EpubPress
  • ✅丢弃顶部banner、左侧导航
  • ❌丢弃正文链接
  • ❌正文格式错误
  • ❌丢失小标题
  • ❌代码块格式错误
  • ❌丢弃重点回顾、习题、参考资料
  • ✅丢弃底部banner
SAE
  • ❌保留顶部banner、左侧导航
  • ✅保留正文链接
  • ✅识别小标题、代码块
  • ✅保留重点回顾、习题、参考资料
  • ❌丢弃页面修订历史格式
  • ❌保留底部banner

由于dotEPUB和EpubPress的转换是在服务器上进行,不管转换结果如何,用户无法干预;而SAE的转换则是在用户自己的电脑上进行,要想得到一个满意的结果,只能依靠SAE。

按需删除网页内容

那么,如何让SAE只转换我们需要的内容呢?这时候就需要用到TamperMonkey这个插件了:

  1. 点击TamperMonkey图标
  2. 在弹出菜单中点击「添加新脚本……」
  3. 复制以下代码覆盖文本编辑框的内容,然后保存
  4. 刷新鸟哥的Linux私房菜
// ==UserScript==
// @name         vbird-linux-prettify
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  美化《鸟哥的Linux私房菜》网站:用等宽字体显示所有代码;隐藏部分页面元素;
// @author       Yang Li
// @match        http://linux.vbird.org/*
// @require      https://code.jquery.com/jquery-3.2.1.slim.min.js
// @grant        none
// ==/UserScript==

$(document).ready(function(){
    // v0.1
    //   1. 通过添加class来添加新的css规则,避免覆盖原有的font以外的规则(比如下划线)
    //
    $('<style> .monospaced_code {font: 10pt "Anonymous Pro", Consolas, monospace !important; line-height: 1.4 !important;} </style>').appendTo('head');
    $('table.term td *').addClass('monospaced_code');

    // v0.2
    //   0. 脚本更名:从 vbird-linux-monospaced-code 改为 vbird-linux-prettify
    //   1. 删除顶部和底部banner、左侧前一页按钮、右侧后一页按钮、左上方导航窗口、页面修订历史
    //   2. 增加正文区域宽度,并放置在页面正中
    //   3. 调整最底部三个导航按钮的位置
    //
    $('.toparea, .bottomarea, .leftarea, .rightarea, .nav, .mainarea > div:nth-last-child(3)').remove();
    $('.mainarea').css({'width':'100%','position':'static','float':'none'});
    $('.mainarea > div:last-child').css('margin-top','20px');
});

刷新之后的网页变成了下面这样:


网页原有的「顶部和底部banner、左侧前一页按钮、右侧后一页按钮、左上方导航窗口、页面修订历史」都被删除了。注意,是「删除」,不是「隐藏」!

如果只是把相关元素的CSS规则设置成display: none,让这些元素隐藏起来,这对SAE没有任何用处,因为SAE转换的时候会忽略所有CSS规则,只保留正文相关的HTML元素,必须使用JavaScript把元素彻底删除,让SAE转换时根本找不到才行。顺便说一下,如果使用另一个非常优秀的Chrome插件uBlock Origin屏蔽了网页上的某些元素,这些元素其实就是被「隐藏」,而不是「删除」。

还有另一种删除网页元素的方法,不需要安装TamperMonkey,也不需要复制粘贴代码,直接通过Chrome浏览器内建的开发者工具就可以,但这种方法只适合转换网页数量极少的情况,每次刷新网页,之前删除的内容都会恢复。具体步骤如下:

  1. 鼠标在网页上想要删除的内容上点击右键,选择「检查」
  2. 在弹出的开发工具面板上,刚才点击的区域对应的代码会被高亮
  3. 鼠标在代码上移动,对应的网页区域也会被高亮
  4. 在想要删除的内容代码上点击右键,选择「Delete element」

把网页上不需要转换的内容删除之后,点击SAE图标,再点击「Save Page」,眨眼之间,epub转换完成,自动下载到电脑上。

如果需要把多个网页一起转换,先把所有网页都打开,在每个网页上点击SAE图标,再点击「Add Page as Chapter」,所有网页都添加之后,点击「Edit Chapters」,在弹出窗口调整网页顺序,最后点击「Generate eBook」,大功告成……

调整epub样式

上述几个插件转换的时候会删除原有的CSS样式表,epub只会保留HTML元素,可谓是素面朝天、不施粉黛,放到不同的epub阅读器会被打扮成不同的样子。如果是文学作品,关系不大;换成示例这样的技术文件,包括文本、图片、代码块、列表,一个合理的样式就非常重要,以下是对比:

表格无框线 有框线
图片、代码块无框线 有框线

从以上截图可以发现,简简单单的几条框线,却能够立竿见影提升可读性。

样式固然重要,在调整样式的过程中,有一点必须注意:网页转换为epub只保留了必要的HTML元素,连id和class属性都被删除,因此,在此基础上恰到好处的微调是最经济的,精雕细琢既不划算,也不现实。以下是我给转换后的《鸟哥的Linux私房菜》epub写的样式表:

body {
  font: 14px/1.5 sans-serif;
}

table {
  border: 1px solid red;
  border-collapse: separate;
  border-spacing: 0;
  border-radius: 10px;
  margin: 5px 0;
  min-width: 100%;
  max-width: 100%;
  display: block;
  box-sizing: border-box;
  overflow: auto;
}

td {
  border-top: 1px solid #ccc;
  border-right: 1px solid #ccc;
  padding: 5px;
}

tr:first-child > td {
  border-top: none;
}

tr > td:last-child {
  border-right: none;
}

tr:first-child > td:only-child {
  border-right: 1px solid #ccc;
}

tr:last-child > td:last-child {
  width: 65%;
}

tr:only-child > td:only-child {
  border: none;
}

div > img {
  display: block;
  box-sizing: border-box;
  border: 2px dotted #ca3;
  margin: 5px;
  padding: 15px;
  max-width: 100%;
}

pre {
  font: 12px monospace;
}

/* 隐藏简答题答案 */
li > div {
  color: #ddd;
}

调整epub样式表需要用到Sigil或者calibre,calibre相对Sigil是个一站式、大而全的工具,Sigil则专注于epub的编辑,正因为专注,Sigil的编辑功能比calibre强出很多。搞笑的是,calibre内嵌的ebook-edit.app编辑好的样式表放到同样内嵌的ebook-viewer.app居然显示不一致。

总结

实际使用之后发现,对于结构复杂、篇幅巨大的网页,例如鸟哥的Linux私房菜现有的工具在转换过程中都会导致内容缺失,进而导致格式错乱,区别只在于程度不同而已。

格式错乱还可以忍受,内容缺失就完全不能接受,因此,对于复杂网页,应当利用Chrome浏览器内置的「打印 → 目标打印机:另存为PDF → 保存」来保存为pdf,所见即所得,省时省力。

鸟哥的Linux私房菜网站另存为pdf

「PDF Expert」阅读器,双页模式:

Leave A Comment