ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 简介 多多猫插件是一个标签+脚本的xml文件,大概结构如下: ```xml <!--?xml version="1.0" encoding="UTF-8" ?--> <sited ver="1" debug="1" engine="34" schema="1"> <meta> <ua></ua> <guid></guid> <title></title> <author></author> <contact></contact> <intro></intro> <alert></alert> <url></url> <expr></expr> <logo></logo> <encode></encode> <about> <item/> </about> </meta> <main> <home> <hots/> <updates/> <tags> <tags/> </tags> </home> <search/> <tag> <tag/> <tag/> </tag> <book> <sections/> </book> <section/> </main> <script> <require> <item url="http://sited.noear.org/addin/js/cheerio.js" lib="cheerio" /> </require> <code> <![CDATA[ ]]> </code> </script> </sited> ``` 这是一个空白的插件示例,用来向大家展示插件的完整架构,它主要分为下面四个部分: 1. `<sited>`根节点,它标注了插件的版本,调试状态,所用的解析引擎版本号等 2. `<meta>`节点, 它标注了开发者、对应网站、标题、登录等信息 3. `<main>`节点, 它声明了用来解析网页内容的函数,内容图片的显示方式等与内容相关的设定 4. `<script>`节点,它包含了`<main>`节点中所声明函数的具体实现,也就是JavaScript代码部分,用来从网页获取内容 **注意**:插件行首的一对尖括号和包括的代码`<!--?xml version="1.0" encoding="UTF-8" ?-->`是每个插件必须的,不要省略,它指定了插件的编码为UTF-8 更深入事项请见[插件开放平台http://sited.noear.org/dev/](http://sited.noear.org/dev/) 里面的官方开发文档PDF <br> ## 插件示例 下面是一个完整的漫画插件示例,让大家对真实的插件有一个了解 ```xml <!--?xml version="1.0" encoding="UTF-8" ?--> <sited ver="3" debug="1" engine="34" schema="1"> <meta> <ua></ua> <guid>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</guid> <title>naver网漫</title> <author>Guang</author> <contact></contact> <intro>[漫画](v3修复)LINE WEBTOON韩国naver官网。매일매일 새로운 재미, 네이버 웹툰.(部分章节提示下架,要登陆源网站观看)</intro> <alert></alert> <url>http://m.comic.naver.com/</url> <expr>comic\.naver\.com\/</expr> <logo>http://static.naver.net/m/comic/im/favicon/favicon_140327.ico</logo> <encode>UTF-8</encode> <about title="反馈" mail="xx@xx.com"> <item url="我邮箱是xx@xx.com" /> <item /> <item url="欢迎打赏插件开发者Guang,反馈问题。"/> <item txt="点击或扫描二维码对[xxx]支付宝打赏" expr="https://qr.alipay.com/xxx" logo="http://xxx.jpg"/> <item /> <item txt="扫描二维码对我的微信打赏" logo="http://xxx.jpg"/> <item /> </about> </meta> <main dtype="1" btag="漫画"> <home> <hots cache="1d" showImg="1" w="1" h="1" title="hots节点" method="get" parse="hots_parse" url="https://m.comic.naver.com/webtoon/weekday.nhn"/> <updates cache="1d" showImg="1" w="1" h="1" title="updates节点" method="get" parse="updates_parse" url="https://m.comic.naver.com/webtoon/weekday.nhn"/> <tags title="分类"> <tags cache="1d" method="get" parse="tags_parse1" url="https://m.comic.naver.com/webtoon/genre.nhn"/> <tags cache="1d" method="get" parse="tags_parse_challenge" url="https://m.comic.naver.com/bestChallenge/genre.nhn"/> </tags> </home> <search cache="1d" method="get" parse="search_parse1" url="https://m.comic.naver.com/search/result.nhn?keyword=@key&amp;searchType=WEBTOON" > <search cache="1d" method="get" parse="search_parse_challenge" url="https://m.comic.naver.com/search/result.nhn?keyword=@key&amp;searchType=BEST_CHALLENGE" /> </search> <tag> <tag cache="10m" showImg="1" w="1" h="1" method="get" parse="tag_parse1" expr="webtoon\/genre.nhn"/> <tag cache="10m" showImg="1" w="1" h="1" method="get" parse="tag_parse_challenge" expr="bestChallenge\/genre.nhn"/> </tag> <book cache="1d" method="get" buildUrl="book_buildUrl" parse="book_parse" expr="\/list\.nhn" > <sections cache="1d" method="get" buildUrl="book_s_buildUrl" parseUrl="book_s_parseUrl" parse="book_s_parse" /> </book> <section cache="1d" method="get" options="0,0,0,1" parseUrl="section_parseUrl" parse="section_parse" header="referer"/> </main> <script> <require> <item url="http://sited.noear.org/addin/js/cheerio.js" lib="cheerio" /> </require> <code> <![CDATA[ function urla(u) { var host = "https://m.comic.naver.com"; if (u.indexOf("http") < 0) { if (u.substr(0, 2) != '//') { if (u.substr(0, 1) != '/') u = host + '/' + u; else u = host + u; } else { u = 'https:' + u; } } return encodeURI(u); } function hots_parse(url, html) { var $ = cheerio.load(html); var list = []; $('.toon_lst li .lst a').each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.attr('href')).replace(/&week=.+$/, ''); bm.logo = item.find('img').attr('src'); list.push(bm); }); return JSON.stringify(list); } function updates_parse(url, html) { var $ = cheerio.load(html); var list = []; $('.toon_lst li .lst a').each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.attr('href')).replace(/&week=.+$/, ''); bm.logo = item.find('img').attr('src'); bm.newSection = ''; bm.updateTime = item.find('.sub_info').eq(0).text(); list.push(bm); }); return JSON.stringify(list); } function tags_parse1(url, html) { var $ = cheerio.load(html); var list = []; list.push({ 'group': '正式漫画' }); $('#webtoonGenreTab ul li a').each(function () { var item = $(this); var bm = {}; bm.title = item.text(); bm.url = urla(item.attr('href')) + '&sort=NEW&page=@page'; list.push(bm); }); return JSON.stringify(list); } function tags_parse_challenge(url, html) { var $ = cheerio.load(html); var list = []; list.push({ 'group': 'best新星漫画' }); $('#genreTab ul li a').each(function () { var item = $(this); var bm = {}; bm.title = item.text(); bm.url = urla(item.attr('href')) + '&sort=UPDATE&page=@page'; list.push(bm); }); return JSON.stringify(list); } function tag_parse1(url, html) { var $ = cheerio.load(html); var list = []; $('.toon_lst li').each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.find('a').attr('href')); bm.logo = item.find('img').attr('src'); bm.author = ''; bm.status = '正式漫画'; bm.newSection = ''; bm.updateTime = ''; list.push(bm); }); return JSON.stringify(list); } function tag_parse_challenge(url, html) { var $ = cheerio.load(html); var list = []; $('.toon_lst li').each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.find('a').attr('href')); bm.logo = item.find('img').attr('src'); bm.author = ''; bm.status = 'best新星漫画'; bm.newSection = ''; bm.updateTime = ''; list.push(bm); }); return JSON.stringify(list); } function search_parse1(url, html) { var $ = cheerio.load(html); var list = []; $('.lst').slice(0, 10).each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.children('a').attr('href')); bm.logo = item.find('img').attr('src'); bm.author = item.find('.sub_info').eq(0).text(); bm.status = '正式漫画'; bm.newSection = ''; bm.updateTime = ''; bm.btag = "正式漫画"; if (!bm.url.match(/javascript:goPcPage/i)) list.push(bm); }); return JSON.stringify(list); } function search_parse_challenge(url, html) { var $ = cheerio.load(html); var list = []; $('.lst').slice(0, 6).each(function () { var item = $(this); var bm = {}; bm.name = item.find('.toon_name').text(); bm.url = urla(item.children('a').attr('href')); bm.logo = item.find('img').attr('src'); bm.author = item.find('.sub_info').eq(0).text(); bm.status = 'best新星漫画'; bm.newSection = ''; bm.updateTime = ''; bm.btag = "best新星漫画"; if (!bm.url.match(/javascript:goPcPage/i)) list.push(bm); }); return JSON.stringify(list); } function book_buildUrl(url) { return url.replace(/^http.+?\/\/[^\/]+/i, 'https://m.comic.naver.com'); } function book_parse(url, html) { var $ = cheerio.load(html); var data = {}; data.name = $('.info_in .title').text(); data.author = $('.info_in .nm').text(); data.logo = $('.toon_info .im_br img').attr('src'); data.intro = $('.info_in .info_cont').text(); data.updateTime = ''; data.isSectionsAsc = 0; if ($('.lst>a').length > 1) { if ($('.lst>a').eq(0).attr('href').match(/no=(\d+)/i)) { var a0 = $('.lst>a').eq(0).attr('href').match(/no=(\d+)/i)[1]; } else { var a0 = $('.lst').eq(0).parent().attr('data-no'); } if ($('.lst>a').eq(1).attr('href').match(/no=(\d+)/i)) { var a1 = $('.lst>a').eq(1).attr('href').match(/no=(\d+)/i)[1]; } else { var a1 = $('.lst').eq(1).parent().attr('data-no'); } if (Number(a0) < Number(a1)) data.isSectionsAsc = 1; } data.sections = []; return JSON.stringify(data); } function book_s_buildUrl(url) { return url.replace(/^http.+?\/\/[^\/]+/i, 'https://m.comic.naver.com'); } function book_s_parseUrl(url, html) { var $ = cheerio.load(html); var urls = url; if ($('.current_pg').text().match(/\d+\D+(\d+)/i)) { var pages = Number($('.current_pg').text().match(/\d+\D+(\d+)/i)[1]); for (i = 2; i <= pages; i++) { urls = urls + ';' + url + '&page=' + i; } } return urls; } function book_s_parse(url, html) { var $ = cheerio.load(html); var data = {}; data.sections = []; $('.lst>a').each(function () { if ($(this).attr('href') && $(this).attr('href').match(/titleId/i)) { var bm = { name: $(this).find('.toon_name').text().trim(), url: urla($(this).attr('href')) }; } else { var bm = { name: $(this).find('.toon_name').text().trim() + '-要登陆源网站观看', url: '' }; } data.sections.push(bm); }); return JSON.stringify(data); } function section_parseUrl(url, html) { var $ = cheerio.load(html); if ($('#id_area').length || $('#toonLayer').length || $('#mflick').length) { return url; } else { curl = html.match(/effecttoonContent[\s\S]+?imageUrl.+?['"\s]+(http.+?)['"\s]/i)[1] + '/'; return urla(html.match(/documentURL\s*:\s*['"]\s*(.+?)\s*['"]/i)[1]); } } function section_parse(url, html) { var list = []; if (url.match(/detail.nhn\?titleId=/i) || url.match(/nid.naver.com\/nidlogin/i) || url.match(/detail.nhn\?titleId=.+?#nafullscreen/i)) { var $ = cheerio.load(html); if ($('#toonLayer').length) { $('#toonLayer ul li img').each(function () { list.push($(this).attr('data-src')); }); } else if ($('#mflick').length) { $('#mflick>.swiper-wrapper>.swiper-slide>img').each(function () { list.push($(this).attr('data-src')); }); } else {} } else { var json = JSON.parse(html); for (var i in json.pages) { for (var j in json.pages[i].layers) { var item = json.pages[i].layers[j].asset.replace('image/', ''); var imageurl = json.assets.image[item]; if (imageurl.match(/\.jpg/i)) list.push(curl + imageurl); } } } return JSON.stringify(list); } ]]> </code> </script> </sited> ``` (本节完)