转自@夜明的孤行灯
最近看漫画有点多,因为各种各样的原因各个网站的漫画都不全,好不容易找到一个好用的,估计服务器不在大陆,速度特别慢。但是又只有网页版本,自然没有各种缓存,离线 下载功能了。

本来寻思自己写一个,但是在知乎看到一个推荐多多猫的,就简单尝试了一下,果然不要自己造轮子呀。

多多猫这个app本身是没有任何内容的,它只是一个插件容器,内容来源是需要插件实现的。而插件的标准(?)名为sited,是xml格式,具体代码实现是javascript。简单来说文档是有的,而且只找到了一份官方的,可以看出有些内容并没有及时更新,但是照着做一个还是没有问题的。

简单来说一下这个漫画网站的结构,主页就是一个列表,每个漫画有分页,一页10张图,一般一个漫画200张左右,就是一个没有目录结构的顺序图集。

先来看看插件大体格式

<?xml version="1.0" encoding="utf-8"?>
<sited ver="1" debug="0" engine="32" schema="1">
    <meta>
        <title>XXX漫画</title>
        <encode>utf-8</encode>
        <ua>Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87
            Safari/537.36
        </ua>
    </meta>
    <main dtype="4" durl="xxx">
        <home>
            <hots cache="10m" title="首页" method="get" parse="hots_parse" url="xxx" showWeb="0"
                  showImg="2"/>
        </home>
    </main>
    <script>
        <require>
            <item url="http://sited.noear.org/addin/js/cheerio.js" lib="cheerio"/>
        </require>
        <code>
        </code>
    </script>
</sited>

主要结构是meta,main和script三大块。其中meta主要是插件的一些信息,main定义的逻辑节点,比如主页,tag,详细页面等等,script中是具体的处理逻辑。

每一块的所有属性都在文档中有这里就不细说了。先来看看home块,最关键的是parse属性,这里定义的是处理方法,而根据文档需要返回一个对象,包含了name,logo,url三个属性。

function hots_parse(url, html) {
    var $ = cheerio.load(html);
    var list = [];
    $('.post_box').each(function () {
        var slf = $(this);
        var bm = {};
        bm.name = slf.children("div.c-top").find('a').text();
        bm.url = urla(slf.children("div.c-top").find('a').attr('href'));
        bm.logo = urla(slf.children("div.c-con").find('img').attr('src'));
        list.push(bm);
    });
    return JSON.stringify(list);
}

这里依赖了cheerio作为网页解析,而返回的是一个json格式的list,当然具体的解析逻辑要根据需求来。

具体的详细页面的解析式定义在book块中,根据文档这里有两个函数,一个是根据网址返回一个图片地址列表,一个是根据网址返回要处理的网址。

根据网站的结构,在列表页获取的只是漫画的前十张图,还需要获取所有的分页地址,然后再处理,所以这里两个函数都需要。

<book cache="1d" method="get" parse="book_parse" parseUrl="book_parse_url" showWeb="0" showImg="2"/

先来看看book_parse_url函数

function book_parse_url(url, html) {
    var $ = cheerio.load(html);
    var list = [];
    var max = $('.single-navi').last().text();
    for (var i = 1; i <= max; i++) {
        list.push(url + '/' + i);
    }
    return list.join(';');
}

这里返回的是一个字符串,而具体的处理函数返回的是一个列表

function book_parse(url, html) {
    var $ = cheerio.load(html);
    var list = [];
    $('.entry-content').children("p").each(function () {
        var slf = $(this);
        list.push(slf.children("img").attr('src'));
    });
    return JSON.stringify(list)
}

这样就实现了整个插件的核心逻辑,可以自由浏览漫画,同时因为多多猫作为插件容器实现了通用功能,这样也就拥有了历史记录,离线下载,收藏等功能了。

总的来说多多猫和sited插件体系是一个很有意思的东西,对于不同资源的定义和插件标准的设计能否覆盖大部分需求,唯一的问题就是开发时如果有任何问题要么显示插件格式解析失败,要么就是白页面,所以调试基本靠脑补。不过好在代码量不大,出错几率也不是很高。

Last modification:October 18, 2017
如果觉得我的文章对你有用,请随意赞赏