novel-downloader
novel-downloader copied to clipboard
[Bug]: 起点文学下载报错
必要条件
- [ ] 我已经搜索 issue 区,并确定没有相同问题存在。
- [x] 我已经尝试将脚本升级至最新版本,但问题仍存在。
- [x] 在尝试下载付费章节前,我已经购买了相应付费章节。
当我尝试复现issue时……
- [X] 我使用的浏览器是最新版 Chrome 或 Firefox
- [ ] 脚本管理器(Tampermonkey/Violentmonkey)是唯一浏览器插件
- [ ] 小说下载器脚本是唯一用户脚本
问题描述
2022年9月14日14点00分开始出现错误,之前使用正常。
问题发生的网址:
https://book.qidian.com/info/1032604531/
复现步骤
1.打开网址https://book.qidian.com/info/1032604531/ 2.登陆网站 3.点击下载
期待的行为
修复下载
实际的行为
下载失败
[Init]开始载入小说下载器…… [Init]当前时间:2022-09-14T06:26:40.988Z [Init]当前页URL:https://book.qidian.com/info/1032604531/ [Init]workerId:7ce7f97b-b0aa-4ecc-8767-3a4acde7b964 [Init]当前页Referrer:https://book.qidian.com/info/1032604531/ [Init]浏览器UA:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0 [Init]浏览器语言:zh-CN,zh,zh-TW,zh-HK,en-US,en [Init]设备运行平台:Win32 [Init]设备内存: [Init]CPU核心数:8 [Init]eval:true, 37 [Init]fetch:true, 33 [Init]XMLHttpRequest:true, 47 [Init]streamSupport:true [Init]window:279 [Init]localStorage:true [Init]sessionStorage:true [Init]Cookie:true [Init]doNotTrack:unspecified [Init]enableDebug:false [Init]ScriptHandler:Violentmonkey [Init]ScriptHandler version:2.13.0 [Init]Novel-downloader version:4.9.4.789 TypeErrorunsafeWindow.jQuery.ajaxSettings.data is undefinedbookParse@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:21893:28 getSections@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:28301:33 [Init]enableDebug: true [Init]自定义设置:{"enableDebug":true,"chooseSaveOption":"null","enableTestPage":false,"currentTab":"tab-1"} [run]下载开始 [] [preTest]nowRunning: 0 [debug]fetch: [ "https://cors.bgme.me/https://jimmywarting.github.io/StreamSaver.js/mitm.html" ] TypeErrorunsafeWindow.jQuery.ajaxSettings.data is undefinedbookParse@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:21893:28 initBook@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:15104:40 run@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:15080:19 TypeErrorunsafeWindow.jQuery.ajaxSettings.data is undefinedbookParse@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:21893:28 initBook@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:15104:40 run@moz-extension://98da7b90-4b7f-40cd-b2f8-e4dfcf8f7b38/%20novel-downloader.user.js#3:15080:19 运行过程出错,请附上相关日志至支持地址进行反馈。 支持地址:https://github.com/404-novel-project/novel-downloader 7ce7f97b-b0aa-4ecc-8767-3a4acde7b964 has closed! 7ce7f97b-b0aa-4ecc-8767-3a4acde7b964 has closed! [stat]小说下载器脚本运行情况统计: { "success": { "book.qidian.com": 1111 }, "failed": { "book.qidian.com": 3 } } [stat]success: book.qidian.com: 1111 [stat]failed: book.qidian.com: 3
小说下载器脚本版本
4.9.4.789
脚本管理器(Tampermonkey/Violentmonkey)版本
暴力猴 v2.13.0
浏览器名称及版本
Mozilla Firefox 104.0.2 (64 位)
出现相似情况
第15320行函数async Qidian::bookParse()对_csrfToken赋值
const _csrfToken = unsafeWindow.jQuery.ajaxSettings.data
._csrfToken
报错是因为unsafeWindow.jQuery.ajaxSettings.data未定义,取_csrfToken成员的时候报错 但是尝试改为
const _csrfToken = unsafeWindow.jQuery.ajaxSettings.data ? unsafeWindow.jQuery.ajaxSettings.data._csrfToken : null
以后反而可以正常下载
起点遇到的一些问题:
- 部分章节会有乱码( issue #226),但是大部分章节字体可以正确解码,原理不明
- 只能在小说主页(“书页”)处使用下载器脚本( url 为 https://book.qidian.com/info/{bookid} ),无法在阅读界面(url为https://read.qidian.com/chapter/././ ,付费为 https://vipreader.qidian.com/chapter/{bookid}/{chaperid}/ )处下载
- 上传到 archive.org 的存档没有小说正文,只有简介和目录,而且即使这个简介也不能正确保存,原始HTML保存的时候只有访问API的少量js,而且该js在浏览器中运行会不断让浏览器刷新
- 起点有少量反调试的 trick ,污染
console.log
,并且每500毫秒调用一次console.clear()
,不过在Violentmonkey中在document start阶段直接替换可以应对
console.G_clear = console.clear
console.G_log = console.log
console.clear = e => 1
setInterval(() => {
if (console.log != console.G_log) {
console.log = console.G_log
}
}, 1000)
不断跳出debugger
似乎没有好的办法,不过Firefox的开发者工具允许格式化js源文件以后忽略debugger
这一行
@willyywt
起点有少量反调试的 trick ,污染
console.log
,并且每500毫秒调用一次console.clear()
,不过在Violentmonkey中在document start阶段直接替换可以应对
可以通过注入如下脚本过滤掉在 setInterval
中定期执行的 debugger
语句。
// ==UserScript==
// @name debugger hook
// @namespace Violentmonkey Scripts
// @match *://*/*
// @grant none
// @version 1.0
// @author -
// @run-at document-start
// @description 12/2/2021, 10:19:13 PM
// ==/UserScript==
// https://github.com/gorhill/uBlock/blob/a94df7f3b27080ae2dcb3b914ace39c0c294d2f6/assets/resources/scriptlets.js
/// noeval-if.js
(function() {
let needle = 'debugger';
if ( needle === '' || needle === '{{1}}' ) {
needle = '.?';
} else if ( needle.slice(0,1) === '/' && needle.slice(-1) === '/' ) {
needle = needle.slice(1,-1);
} else {
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
needle = new RegExp(needle);
window.eval = new Proxy(window.eval, { // jshint ignore: line
apply: function(target, thisArg, args) {
const a = args[0];
if ( needle.test(a.toString()) === false ) {
return target.apply(thisArg, args);
}
}
});
})();
/// no-setInterval-if.js
(function() {
let needle = '/debugger|clear/';
const needleNot = needle.charAt(0) === '!';
if ( needleNot ) { needle = needle.slice(1); }
let delay = '{{2}}';
if ( delay === '{{2}}' ) { delay = undefined; }
let delayNot = false;
if ( delay !== undefined ) {
delayNot = delay.charAt(0) === '!';
if ( delayNot ) { delay = delay.slice(1); }
delay = parseInt(delay, 10);
}
if ( needle === '' || needle === '{{1}}' ) {
needle = '';
} else if ( needle.startsWith('/') && needle.endsWith('/') ) {
needle = needle.slice(1,-1);
} else {
needle = needle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
const log = needleNot === false && needle === '' && delay === undefined
? console.log
: undefined;
const reNeedle = new RegExp(needle);
window.setInterval = new Proxy(window.setInterval, {
apply: function(target, thisArg, args) {
const a = String(args[0]);
const b = args[1];
if ( log !== undefined ) {
log('uBO: setInterval("%s", %s)', a, b);
} else {
let defuse;
if ( needle !== '' ) {
defuse = reNeedle.test(a) !== needleNot;
}
if ( defuse !== false && delay !== undefined ) {
defuse = (b === delay || isNaN(b) && isNaN(delay) ) !== delayNot;
}
if ( defuse ) {
args[0] = function(){};
}
}
return target.apply(thisArg, args);
}
});
})();
// console.clear
window.console.clear = new Proxy(window.console.clear, {
apply:(target, thisArg, args) => null
})
So, can we download the text of Qidian now? Or do we need to fix something to be able to download text without issue #226? :< @yingziwu