Greasy Fork is available in English.

怠惰小说下载器

通用网站内容抓取工具,可批量抓取任意站点的小说、论坛内容等并保存为TXT文档

安装此脚本?
作者推荐脚本

您或许会喜欢东方永页机

安装此脚本
作者
hoothin
今日安装
205
总安装量
89,499
得分
390 11 1
版本
2.7.3.18
创建日期
2016-11-23
最近更新
2023-01-27
兼容性
与 Firefox 兼容 与 Chrome 兼容 与 Opera 兼容 与 Safari 兼容
许可证
MIT
应用到
所有站点

test case

起点晋江红袖等版权站都推荐用【小说】下载脚本小说下载器,遇到无人适配的小站再考虑我的脚本。

轻量级抓取脚本,用于下载网页小说或其他文字内容,理论上通用于任何静态写入正文的小说网站、论坛、贴吧等而无需规则。

脚本会自动检索页面中的主要内容并下载(省得复制完gal攻略还要手动逐条删除“某某某13级头衔水龙王发表于X年X月X日来自XX客户端”)。 如果位于小说目录页脚本则会遍历所有章节并排序拼接后存为TXT文档。

img 👈 好用的话给我点个 star 吧


操作说明

  • 打开小说目录页或其他任意页面
  • 按下 CTRL + F9 或使用脚本管理器的命令菜单
  • 亦可按下 SHIFT + CTRL + F9 忽略目录,仅下载当前页
  • 如遇目录页分页,可用东方永页机翻完所有目录后再开始下载

通过下载的 MD 文件生成 EPUB 格式或者 MOBI 格式
  • 下载 Calibre 并安装。本文以 3.22.1 Windows 版为例。
  • 在主界面点击“偏好选项”。如果默认没有显示,请将窗口最大化或点击工具栏最右侧的双箭头展开
  • 点击 “格式转换” - “常用选项”。
  • 点击 “内容目录”,在 “Xpath 表达式” 选项框中依次输入 //h:h1 //h:h2 //h:h3 并 “应用”
  • 回到主界面,点击 “添加书籍”,选择需要转换的 md 文件,导入。
  • 点击 “转换书籍”,确认输出格式为 “EPUB” 或者 “MOBI”,点击确定开始转换。

适配申请(☑️已适配站点规则在下面【简易自定义例子】处,自行复制取用) 若是遇到下载出错以及动态加载文本的站点,可随意提交 issue 至 Github,我若恰好有空可尝试帮你编写自定义规则。
注:若是 【小说】下载脚本小说下载器 已适配或者列入 todo 列表,或是我认为适配该站会带来律师函之类的麻烦,则适配请求将被忽略。

恰好对你有帮助的话,可请我喝杯奶茶 PayPal.Me or BuyMeACoffee

donation

怠惰心法

此功共有七层,以第一层最易,第七层最难。

第一层心法(极易)

CTRL+F9 就完事了呗。

第二层心法(超易)⭐

倘若章节链接没有xx章、xx节、xx话之类的特征字样,可点击脚本管理器命令菜单里的自定义下载,输入其中任意一个章节名下载即可。
例如 “第1页-双星”,即可标记所有同级链接为目录章节并下载。
假如页面有两套章节格式,也可标记多个,例如“众神的风车,风车的众神”。
亦可标记排除项,例如“众神的风车01!02!03,风车的众神!铁幕”,代表标记“众神的风车01”同级链接并排除含有 02 的项和含有 03 的项,同时标记“风车的众神”同级链接并排除含有“铁幕”的项。

第三层心法(略易)

如果内页没有正文,但章节链接与真实内容链接有关联,可通过自定义下载,替换链接内容获取真实内容。
例如 【众神的风车@@articles@@articlescontent】,即可替换章节 URL 中的 articles 为 articlescontent 并自动获取内容。

第四层心法(略难)

如果链接无法由直接替换得到最终地址,可用正则替换。
例如【众神的风车@@articles(\d+)@@articlescontent_$1b】,即可替换章节 URL 中的 articles1、articles2 为 articlescontent_1b、articlescontent_2b

第五层心法(难)

输入章节的 css 选择器可以更精确地标记章节链接。
例如.l_chaptname>a,代表 class 为 l_chaptname 的元素下的 a 链接。
可使用>>管道来处理抓取到的item。
下载内容可能含有干扰码,此时只需点击懒人小说下载设置,输入干扰码的 css 选择器即可排除干扰码。
例如 .mask,.ksam,font.jammer,代表删除 class 为 mask 或者 ksam 的元素或者 class 为 jammer 的 font 元素。

第六层心法(超难)

倘若正文不在内页正文,是页面加载后处理得到的,可点击自定义下载,输入自定义代码对内页进行分析获取正确结果。
例如 【众神的风车@@@@@@var noval=JSON.parse(data.querySelector("#meta-preload-data").content).novel;noval[Object.keys(noval)[0]].content;】,即可通过自定义代码处理返回页面获取内容。
代码中使用 data 可以获得返回页面的 document,最后一个表达式的值为最终写入的内容。
如果返回 false,代表异步回调,可自行抓取内容并等待抓取成功后用 cb(content) 返回抓取到的 content。
倘若章节没有链接,点击后方才生成链接跳转,可通过 >> 管道处理抓取到的元素生成章节链接,详情见下方例子。

第七层心法(24K纯难)

倘若正文已经经过加密,需要解密才能获取正确内容,可打开浏览器的控制台,自定义 dacProcess 函数,调取页面中网站自身的解密代码处理抓取的加密数据。
例如控制台输入dacProcess=data=>{return decrypt(xxx);} 代表调用网站的 decrypt 解密章节页面返回的数据。然后再点击自定义下载,需要注意自定义下载时标记章节是必需的。

完整格式说明

某个章节名/CSS选择器【选择器后可跟>>传入item添加处理代码】 @@ 抓取到链接的正则匹配 @@ 对应匹配生成替换URL @@ 根据爬取返回内容data处理并返回最终文本

关于配置项

【以下功能需要通过 Tampermonkey 等管理器的命令菜单进入】

img

  • 自定义目录:如https://xxx.xxx/book-[20-99].html,https://xxx.xxx/book-[01-10].html,意思为下载book-20.html到book-99.html,以及book-01.html到book-10.html,使用[1-10]则不补0。
  • 章节选择器自定义:输入章节链接的 css 选择器即可,后面可以接上 url 替换码、以及自定义处理代码。
  • 干扰码:填入干扰码的 css 选择器,如.mask,.ksam,意为删除 class 为 mask 或者 ksam 的元素。
  • 按标题名重新排序:是则把目录页所有链接按标题名排序后存入txt,否则按页面位置顺序排列。
  • 下载线程数:同时下载的线程数,默认为20,遇到存在限制的站点(例如下载时总有章节获取失败)可调低。

简易自定义例子,打开目录页点击【自定义下载】粘贴即可使用

仅作为示例,如果以下网站改版导致失效了,可自行摸索修改

  1. po18,章节的选择器为 .l_chaptname>a ,输入并下载后发现通过 url 无法下载正文内容,正文是 ajax 通过 articlescontent 下载的。此时可后接 @@articles@@articlescontent (@@ 分隔) 将章节 url 中的 articles 替换为 articlescontent 。 粘贴进命令菜单即可下载。其中第一个 articles 可使用正则,例如 @@articles(\d+)@@$1content 代表将链接中的「articles1」「articles2」等替换为「1content」「2content」。
    .l_chaptname>a@@articles@@articlescontent
    
    如果需要下载已购买的vip章节,用这个规则
    a.btn_L_blue>>let a=document.createElement("a");a.innerText=item.parentNode.parentNode.querySelector('.l_chaptname').innerText;a.href=item.href;return a;@@articles@@articlescontent
    
  2. pixiv,p站小说的章节选择器为main>section ul>li>div>a,无需替换链接,因此后两项留空。有6个@了 😂。正文在meta里,需要自定义代码提取meta-preload数据的content项。其中 "data" 代表抓取网页的document对象,若返回的是纯文本,则用 data.body.innerText 获取。
    main>section ul>li>div>a@@@@@@var noval=JSON.parse(data.querySelector("#meta-preload-data").content).novel;noval[Object.keys(noval)[0]].content;
    
  3. 红薯中文网,红薯中文网没有目录链接,此时可以遍历标签自己创建目录链接下载。同时此站将部分文字加密至样式表了,需要进行额外解密处理
    ul#lists>li>>let href=item.getAttribute("onclick").replace(/.*(http.*html).*/,"$1"),innerText=item.querySelector("span").innerText;return {href:href,innerText:innerText};@@@@@@let rdtext=data.querySelector('div.rdtext');let sc=data.querySelector('div.ewm+script');if(sc&&rdtext){let code=sc.innerText.replace(/for\(var i=0x0;i<words.*/,"window.words=words;");eval(code);[].forEach.call(rdtext.querySelectorAll('span[class]'),span=>{let id=span.className.replace(/[^\d]/ig,"");span.innerText=words[id]}),rdtext.innerText};
  4. yuyan
    https://yuyan.pw/novel/xxx/[xxxxxxx-xxxxxxx].html@@@@@@var c=data.querySelector('body>script:nth-of-type(8)').innerHTML.match(/var chapter =(.*?);\\n/)[1];eval(c).replaceAll("<br />","");
  5. 翠微居
    .chapter-table>a@@@@@@fetch(data.querySelector("div.box-border>script").innerHTML.match(/\/chapter\/(.*?)"/)[0]) .then(response => response.text()) .then(d => {eval("window.txtObj="+d.match(/_txt_call\((.*)\);/)[1]);for(k in txtObj.replace){txtObj.content=txtObj.content.replaceAll(txtObj.replace[k],k)}cb(unescape(txtObj.content.replace(/&#x(.*?);/g,'%u$1')));});return false;
  6. 知乎盐选
    [class^=ChapterItem-root]>>let a=document.createElement("a");let pre=`https://www.zhihu.com/market/paid_column/${location.href.replace(/\D*(\d+)$/,"$1")}/section/`;a.href=pre+JSON.parse(item.dataset.zaExtraModule).card.content.id;a.innerText=item.querySelector("div").innerText;return a;
  7. 腐女屋
    .chapterList>ul>li>a>>let href=item.href.replace(/.*goChapter((\d+))/,"/noval/"+localStorage.booklist+"/$1.html");item.href=href;return item;
  8. 若初文学网
    ul.float-list>li>a@@www\.ruochu\.com/book/\d+/(\d+)@@a.ruochu.com/ajax/chapter/content/$1@@var content = data.body.innerText.match(/"htmlContent":"(.*)","status"/);if(!content)console.log(data.body.innerText);else{content=content[1];content.replace(/\r/g,'\n')}
  9. 明月中文网
    ul.readlist>li>a>>let href=item.getAttribute("onclick").replace(/.*open\('(.*)','.*/,"$1");item.href=href;return item;
  10. 东北人小说网 此站有内分页,故需要使用异步方法,抓取内容后暂不返回,待请求所有分页内容再拼接后一起返回。
    .chapterList li>a>>item.href=item.href.replace(/.*gotochapter\('(\d+)','(\d+)','(\d+)'\).*/,"/$1/$2/$3.html");return item;@@@@@@let content=data.querySelector('#contentinfo,#ChapterView>div:nth-child(3)>div');if(!content)return data.body.innerText;content.innerHTML=content.innerHTML.replace(/<br>/g,"\n");content=content.innerText;let pages=data.querySelectorAll(".chapterPages>a:not(.curr)");if(pages){let num=pages.length,cur=0;content=[content];[].forEach.call(pages, (page,i)=>{let url=page.href.replace(/.*\((\d+),(\d+),(\d+),(\d+)\).*/,"/$1/$2/$3_$4.html");fetch(url).then(r => r.text()).then(d => {let doc = document.implementation.createHTMLDocument(''); doc.documentElement.innerHTML = d;let c=doc.querySelector('#contentinfo,#ChapterView>div:nth-child(3)>div');if(c){c.innerHTML=c.innerHTML.replace(/<br>/g,"\n"); content[i+1]=c.innerText;if(++cur>=num)cb(content.join("\n"));} }); });return false;}return content;
    
  11. 畅读小说网 此站同样有内分页,不同之处在于它的内分页需要加载后才能知道是否存在,故同样异步返回,并且回调fetch直至分页全部分析完
    .section-list>li>a@@@@@@let content="";let checkContent=(doc,over)=>{word=doc.querySelector('.word_read');if(!word)content+='\n'+doc.body.innerText;else [].forEach.call(word.querySelectorAll('p,h3'),c=>content+='\n'+c.innerText);let next=doc.querySelector(".read_btn>a:nth-child(4)");if(next&&/_\d\.html/.test(next.href)){fetch(next.href).then(r => r.text()).then(d => {let _doc = document.implementation.createHTMLDocument('');_doc.documentElement.innerHTML = d;checkContent(_doc,over);});}else over();};checkContent(data,()=>{cb(content)});return false;
  12. lofter 此站包含杂项博文,故需要手动抓取筛选并且排序后下载
    body>>let title="俞亮/时光",chs=[];item.querySelectorAll("ul.list>li>a").forEach(a=>{if(a.children[0].innerText.indexOf(title)!=-1)chs.push(a)});return chs.reverse();
    
  13. 顶点小说网 此站同11项
    .book_last>dl>dd>a:not([style])@@@@@@let content="";let checkContent=(doc,over)=>{word=doc.querySelector('#chaptercontent');if(!word)content+='\n'+doc.body.innerText;else {word.innerHTML=word.innerHTML.replace(/<br>/g,'\n');content+='\n'+word.innerText;}let next=doc.querySelector("#pb_next");if(next&&/_\d\.html/.test(next.href)){fetch(next.href).then(r => r.arrayBuffer()).then(d => {let decoder = new TextDecoder("gbk");let text = decoder.decode(d);let _doc = document.implementation.createHTMLDocument('');_doc.documentElement.innerHTML = text;checkContent(_doc,over);});}else over();};checkContent(data,()=>{cb(content)});return false;
    
  14. 宅男小说网 此站目录链接被隐藏了,因此需要手动构造,同10项。但是因为此站文字被占位图片替换了,因此需要有人整理对照表,否则缺字。
    #list-chapterAll>dd>a>>item.href=item.href.replace(/.*book('(\d+)','(\d+)').*/,"/go/$1/$2.html");return item;@@@@@@let content=data.querySelector('h1~div');if(!content)return data.body.innerText;content.innerHTML=content.innerHTML.replace(/<br>/g,"\n");content=content.innerText;let pages=data.querySelectorAll(".chapterPages>a:not(.curr)");if(pages){let num=pages.length,cur=0;content=[content];[].forEach.call(pages, (page,i)=>{let url=page.href.replace(/.*'(\d+)','([\d_]+)'.*/,"/go/$1/$2.html");fetch(url).then(r => r.text()).then(d => {let doc = document.implementation.createHTMLDocument(''); doc.documentElement.innerHTML = d;let c=doc.querySelector('h1~div');if(c){c.innerHTML=c.innerHTML.replace(/<br>/g,"\n"); content[i+1]=c.innerText;if(++cur>=num)cb(content.join("\n"));} }); });return false;}return content;
    

【高亮并且格式化页面中选中的代码,也可以统计选中字数】

测试网页

FAQ

  • 章节没有“第几章第几节”的字样怎么办?
    参考第二层心法输入其中一个章节名即可
  • 下载一定数量章节后抓取超时失败怎么办?
    可能是网站限制了并发数,在设置中调低线程数即可
  • 按下快捷键没有反应怎么办?
    可能是快捷键被其他应用接管了,使用脚本管理器中的命令菜单下载即可
  • 有无关干扰字符怎么办?
    设置里输入干扰码css选择器即可,多个选择器用逗号分隔
  • 章节顺序不对怎么办?
    设置里切换按网址重新排序与按章节名重新排序即可

为啥要写这个脚本?

主要是怠惰啊 因为我要下载驰星周的漂流街,却发现前人的轮子“【小说】下载脚本”不能用,又不想为这破站 🙃 写规则,而且我就是看不上霸道总裁修仙穿越你咬我啊指不定它三天两头改个版呢。写个通用规则的脚本,一来可以不用追着数不清的小说站适配修改更新,二来也免去了法律风险。 这个脚本会自动去查找主要内容并下载,不需要写规则。当然如果你家网站广告内容比正文还多我也没办法。 遇到特殊网站还是建议用“【小说】下载脚本”。