油猴脚本开发系列之“ctext.org"添加下载按钮

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了

油猴脚本开发系列之“ctext.org"添加下载按钮

声明

本人所有逆向、破解及爬虫相关教程均是以纯技术的角度来探讨研究和学习,严禁使用教程中提到的技术去破解、滥用、伤害其他公司及个人的利益,以及将以下内容用于商业或者非法用途。

前言

ctext.org网站名字叫做:“中国哲学书电子化计划”,此网站有很多咱们中国的文化书籍,但是网站却没有下载按钮,如果要下载的话只能手动复制,今天咱们就来给他加一个下载按钮

内容获取

image.png 就拿这篇文章为例,我们要想下载内容,肯定要先把想要下载的内容获取到,咱们来分析一下。

标题

下载一篇完整的文章,一定要有个标题,我们先来把标题取到,直接F12打开调试模式看看

可以很明显的看到标题文本元素的位置,但元素下面还有子节点,子节点下面还存在着文本。所以获取节点文本的时候不能直接用textContent,可以使用如下方法:

document.querySelector('.wikisectiontitle').firstChild.nodeValue
复制代码

可以看出标题已经成功获取出来了

内容

下面就是获取文章的内容了,同样先看看内容所在的元素,

可以看到这里的内容就是在tbody下面的每一个tr下面,所以我们只要获取所有的tr就可以获取所有的文字内容了,所以根据特征可以写出 css 表达式为:

document.querySelectorAll('table[style="width: 100%;"]>tbody>tr')
复制代码

下面就是获取每个 tr 里面的内容,但为注意的是,tr里面可能是标题,也可能是内容,所以要更加特征去区分一下

可以看到标题和文本虽然都在tr下面,但是其 css 样式还是不一样的,只要在遍历的时候区分出来就好,如下代码:

    let texts = []
    // 查询所有的tr
    let all_text_el = document.querySelectorAll('table[style="width: 100%;"]>tbody>tr')
    // 依次遍历所有的tr
    all_text_el.forEach(el => {
        // 子标题的元素
        let title_el = el.querySelector('.wikisubsectiontitle')
        // 文本的元素
        let text_el = el.querySelector('td:nth-child(2)')
        // 有标题元素就把标题文本加入进去,否则就加入文本
        if (title_el) {
            texts.push(title_el.textContent)
        } else {
            texts.push(text_el.textContent)
         }
    })
    // 换行符分割,拼成字符串
    let text = texts.join('\n')
复制代码

下载按钮

下载的方法找到了,就要有一个处罚的地方,总不能进来直接就下载啊,体验多不好,我们研究研究网页,看看啥地方合适。

这里刚好有个地方,可以看看怎么加进去,先看看其他几个咋加的

咱们也仿照一下,在找一个下载的按钮图标,也同样加在后面就可以了, 可以这样写:

    let a = document.createElement('a')
    a.innerHTML = '<img src="https://cdn.icon-icons.com/icons2/7/PNG/128/arrow_torrent_download_889.png" border="0" width="44" height="44" alt="" title="">';
    document.querySelector('div[class="noprint opt"]').appendChild(a);
复制代码

如此就把下载的按钮加到网页上面去了,就像这样:

然后就是点击下载按钮的事件了

下载吧

下载的操作可以使用URL.createObjectURL的方式去下载,如一下示例代码:

    let blob = new Blob([text])
    let filename = `${title}.txt`
    a.download = filename
    a.href = URL.createObjectURL(blob)
    URL.revokeObjectURL(blob)
复制代码

这样就完成了,点击的时候会弹出下载的弹窗

整合进油猴脚本

可以把脚本放到油猴脚本或脚本猫中,都可以,下面附上全部代码:

// ==UserScript==
// @name         中国哲学书电子化计划下载
// @namespace    https://bbs.tampermonkey.net.cn/
// @version      0.1.0
// @description  中国哲学书电子化计划添加下载按钮
// @author       昊色居士
// @match        *://ctext.org/wiki.pl?if=*&chapter=*
// ==/UserScript==

(function () {
    'use strict';

    // 标题的元素
    let title = document.querySelector('.wikisectiontitle').firstChild.nodeValue

    let texts = []
    // 查询所有的tr
    let all_text_el = document.querySelectorAll('table[style="width: 100%;"]>tbody>tr')
    // 依次遍历所有的tr
    all_text_el.forEach(el => {
        // 子标题的元素
        let title_el = el.querySelector('.wikisubsectiontitle')
        // 文本的元素
        let text_el = el.querySelector('td:nth-child(2)')
        // 有标题元素就把标题文本加入进去,否则就加入文本
        if (title_el) {
            texts.push(title_el.textContent)
        } else {
            texts.push(text_el.textContent)
         }
    })
    // 换行符分割,拼成字符串
    let text = texts.join('\n')

    // 添加下载按钮
    let a = document.createElement('a')
    a.innerHTML = '<img src="https://cdn.icon-icons.com/icons2/7/PNG/128/arrow_torrent_download_889.png" border="0" width="44" height="44" alt="" title="">';
    document.querySelector('div[class="noprint opt"]').appendChild(a)
    
    // 增加下载事件
    let blob = new Blob([text])
    let filename = `${title}.txt`
    a.download = filename
    a.href = URL.createObjectURL(blob)
    URL.revokeObjectURL(blob)
    
})();

复制代码

结语

一篇小油猴脚本的创造过程就是这些了,不能的地方呢,我感觉就是还是不能全集下载和文档格式如果是markdown的就更好了,我在研究研究,弄好了分享给大家

猜你喜欢

转载自juejin.im/post/7131019713798209549