小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
前言
之所以有这么个 idea,是我比较喜欢阅读本地的 PDF,又有喜欢屯东西的癖好。核心的目的就是,把网页上我们需要的内容,列出来,去掉无关的信息,然后 ctrl+p 调用系统打印生成pdf文件。那么,就开始梭哈了
IDEA 1
我们在自己的网站上可以为所欲为,但如果将别人的站点引入到我们自己的站点再进行操作,就会出现一个常见的异常:跨域警告!
但~是,nginx 搞个反向代理,就能完美解决跨域。理论可行,实践开始
找到 nginx/confi/nginx.conf 文件,在 http 节点下开始编辑
添加一个域名别名
upstream mysql {
server www.runoob.com:80;
}
配置反向代理的相关参数
server {
listen 127.0.0.1:8001;
location / {
proxy_pass http://mysql;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Fonwarded-For $proxy_add_x_forwarded_for;
if ($request_method = 'OPTIONS') {
return 204;
}
}
}
通过命令 start nginx 启动 nginx 的服务,喜提 403
第一反应就是,我好像给人 gank 了?!通过询问万能的度娘,得到答案
敲黑板!!如果我们使用 http 协议,就会存在一个情况,他人通过使用 nginx 的反代,直接镜像出我们的站点,同时又可以对内容进行随心所欲的修改!
典型场景就是,实际站点是 A.com,我们搭建一个 B.com 的站点,反向代理到 A.com,同时插入广告甚至盗号木马,用户不小心访问到了 B.com,以为是官方的 A 站点,而实际上是访问了我们魔改后的镜像站点,存在的风险不言而喻
那么用 nginx 搞反代的方案算是折~了??等等,问问度娘 nginx 反代到 https 的可行性
方案有不少,就留到后续再折腾吧(懒得折腾了,谁让我是解决了问题再来复盘的呢)
IDEA 2
我们可以通过在 油猴 上编写代码块,来实现我们的目的
- 拉取到左侧的菜单,把
url记录下来 - 清空
body中的所有元素 - 遍历并请求记录的
url,将获取到的html元素,依次嵌入到body节点 - 检查获取到的元素,修改窗口大小,记录下需要移除的元素
好了,思路已经捋清楚了,开干
// ==UserScript==
// @name 导出 菜鸟教程的文档
// @version 1
// @grant none
// @match https://www.runoob.com/mysql/**
// ==/UserScript==
// 需要手动复制到控制台,等文档加载完成后,直接ctrl+p 打印文件
let hrefs = document.getElementById('leftcolumn').children;
至于为啥只写了一截,因为我原生的 js 不会了。。。
IDEA 3
既然方案已经确认为编写插件了,那干脆直接控制台跑脚本得了。。。
注意:谷歌的浏览器,支持添加存储代码片段,即会帮我们保存代码文件,我们需要的时候可以直接去那里 run !
成品的代码见下
{
let hrefs = [];
$('#leftcolumn>a').each(function() {
hrefs.push($(this).attr('href'))
})
$('body').empty();
$('body').append('<div id="down-pdf-page"></div>');
let $pages = $('#down-pdf-page');
// hrefs = [hrefs[0], hrefs[1]]
hrefs.forEach((h, i) => {
$pages.append('<div></div>');
try {
$('#down-pdf-page>div:last').load(h, function() {
let $article = $('.article-body');
$('#down-pdf-page>div:last').empty().append($article);
console.log('进度:', (i + 1) / hrefs.length)
})
} catch (e) {
}
})
setInterval(() => {
$('#postcomments').remove();
$('.feedback-btn').remove();
$('.previous-next-links').remove();
$('#respond').remove();
$('#comments').remove();
}, 2000)
}
这份代码是针对 菜鸟教程 进行的编写,我们随便打开里面的技术文档,比如这个 mysql,然后开启控制台,代码一贴,等待所有的文档分页都加载完成之后,直接ctrl+p 保存为 pdf 即可
因为编写的时候,发现需要移除的元素没有处理好,即有的分页的多余元素未移除,直接使用一个定时函数来清理(毕竟修 bug 太难了 不是吗)
总结
现在已经基本实现目标,在线文档保存到本地 pdf,但还存在一个小问题,文档不带书签,算是美中不足吧。通过研究文档,发现标题齐全,但是到处的 pdf 没有根据标题来生成书签,就很难受,md 文档都是会根据标题来自动生成的
针对这点,我想的一个点子就是,专门生成一页目录,然后链接到对应的标题,具体的技术细节点就是 a标签锚点定位,这个就需要后续再研究瞧瞧了,理论上可行
还有一个思路就是,直接 pdf 转 md 文件,网上都比较推荐这个在线的工具 pdf to markdown,我试了,发现一个很大的缺点:丢失图片
对了,我想起个事,反手捞一个 用自定义插件将掘金的文章缓存到本地(收藏怪的福音),这篇文章就是教大家怎么缓存掘金的文章的
欢迎大家留言一起交流~
2021.10.09 更新
上文不是提到了通过 ctrl+p 直接打印 pdf 会没有书签,非常的难受,现在发现一个好的解决方案:
如果 windows 的剪切板顶得住的话,我们直接 ctrl+a 全选内容,带格式粘贴到 typora(一个 md 编辑器),会完美携带内容以及图片,同时,typora 会根据标题直接生成层级菜单
我们在 typora 中生成 pdf 文件就会携带上书签,perfect ~