菜鸟教程在线文档缓存本地

1,561 阅读4分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

前言

之所以有这么个 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

图片.png

第一反应就是,我好像给人 gank 了?!通过询问万能的度娘,得到答案

图片.png

敲黑板!!如果我们使用 http 协议,就会存在一个情况,他人通过使用 nginx 的反代,直接镜像出我们的站点,同时又可以对内容进行随心所欲的修改!

典型场景就是,实际站点是 A.com,我们搭建一个 B.com 的站点,反向代理到 A.com,同时插入广告甚至盗号木马,用户不小心访问到了 B.com,以为是官方的 A 站点,而实际上是访问了我们魔改后的镜像站点,存在的风险不言而喻

那么用 nginx 搞反代的方案算是折~了??等等,问问度娘 nginx 反代到 https 的可行性

图片.png

方案有不少,就留到后续再折腾吧(懒得折腾了,谁让我是解决了问题再来复盘的呢)

图片.png

IDEA 2

我们可以通过在 油猴 上编写代码块,来实现我们的目的

  1. 拉取到左侧的菜单,把 url 记录下来
  2. 清空 body 中的所有元素
  3. 遍历并请求记录的 url,将获取到的 html 元素,依次嵌入到 body 节点
  4. 检查获取到的元素,修改窗口大小,记录下需要移除的元素

好了,思路已经捋清楚了,开干

// ==UserScript==
// @name     导出 菜鸟教程的文档
// @version  1
// @grant    none
// @match		 https://www.runoob.com/mysql/**
// ==/UserScript==
// 需要手动复制到控制台,等文档加载完成后,直接ctrl+p 打印文件
let hrefs = document.getElementById('leftcolumn').children;

至于为啥只写了一截,因为我原生的 js 不会了。。。

图片.png

IDEA 3

既然方案已经确认为编写插件了,那干脆直接控制台跑脚本得了。。。

注意:谷歌的浏览器,支持添加存储代码片段,即会帮我们保存代码文件,我们需要的时候可以直接去那里 run !

图片.png

成品的代码见下

{
  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 太难了 不是吗)

图片.png

总结

现在已经基本实现目标,在线文档保存到本地 pdf,但还存在一个小问题,文档不带书签,算是美中不足吧。通过研究文档,发现标题齐全,但是到处的 pdf 没有根据标题来生成书签,就很难受,md 文档都是会根据标题来自动生成的

图片.png

针对这点,我想的一个点子就是,专门生成一页目录,然后链接到对应的标题,具体的技术细节点就是 a标签锚点定位,这个就需要后续再研究瞧瞧了,理论上可行

还有一个思路就是,直接 pdf 转 md 文件,网上都比较推荐这个在线的工具 pdf to markdown,我试了,发现一个很大的缺点:丢失图片

对了,我想起个事,反手捞一个 用自定义插件将掘金的文章缓存到本地(收藏怪的福音),这篇文章就是教大家怎么缓存掘金的文章的

欢迎大家留言一起交流~

图片.png

2021.10.09 更新

上文不是提到了通过 ctrl+p 直接打印 pdf 会没有书签,非常的难受,现在发现一个好的解决方案:

如果 windows 的剪切板顶得住的话,我们直接 ctrl+a 全选内容,带格式粘贴到 typora(一个 md 编辑器),会完美携带内容以及图片,同时,typora 会根据标题直接生成层级菜单

我们在 typora 中生成 pdf 文件就会携带上书签,perfect ~

image.png