#345·so-novel

[问题反馈] SearchParser.java referer 末尾携带 / 导致 HTTP 400

Author: oicqgodCreated Jul 15, 2026Updated Jul 17, 2026

提交前自查

  • 我已下载最新版本测试,确认问题依然存在。
  • 我已认真阅读 使用说明
  • 我已查阅 常见问题,确认没有重复的讨论。
  • 我已查阅 书源一览
  • 我已确保 已有问题 中无类似 issue(否则请在已有的 issue 内进行讨论)
  • 我已为当前 Issue 拟定了一个简洁明了的标题。

操作系统名称及版本号 (在终端执行命令以查看,Windows:winver,Linux:lsb_release -a,macOS:sw_vers)

Windows 10 22H2 (19045.7548)

so-novel 发行版

sonovel-windows.tar.gz

so-novel 安装/运行方式

手动下载压缩包

配置信息

markdown
{
    "version": "1.11.0",
    "autoUpdate": 0,
    "ghProxy": "",
    "cfBypass": "",
    "downloadPath": "downloads",
    "extName": "txt",
    "txtEncoding": "UTF-8",
    "preserveChapterCache": 0,
    "enableProgressbar": 1,
    "language": "zh-CN",
    "activeRules": "custom.json",
    "sourceId": -1,
    "searchLimit": 30,
    "searchFilter": 0,
    "concurrency": -1,
    "minInterval": 200,
    "maxInterval": 400,
    "enableRetry": 1,
    "maxRetries": 3,
    "retryMinInterval": 2000,
    "retryMaxInterval": 4000,
    "webEnabled": 0,
    "webPort": 7765,
    "qidianCookie": "",
    "proxyEnabled": 0,
    "proxyHost": "127.0.0.1",
    "proxyPort": 7890
}

问题描述


⚠️ 以下内容由 AI(Reasonix)生成,经人工审核后发布。

环境

  • SoNovel v1.11.0
  • Windows 10
  • 自定义 custom.json,包含两个书源

现象

搜索关键词「凡人」时,爱丽丝书屋(alicesw.com)正常返回 10 条结果,但第一版主(m.diyibanzhu.website)完全静默——无结果、无错误信息,该书源像被跳过一样。

但是:CLI 下载模式(-u https://m.diyibanzhu.website/list/5431.html)完全正常,章节下载、正文提取均无误。

已排除的因素

经过 30+ 次配置变体测试和源码阅读(见下方),以下因素已排除:

排除项 验证方式
search.url%s 替换失败 逗号格式测试中 URL 正确显示 wd=凡人&objectType=2;源码 processUrl 仅做 url.formatted(keyword)
POST data 格式问题 JSON、严格 JSON、原始 URL-encoded 三种格式全部测试;buildData 源码已确认
CSS 选择器不匹配 li.column-2ul.txt-list lia.nameali 全试过
search-filter 过滤 已设为 0
书源被跳过 source-id = 1 强制定向测试证明源 1 确实被搜索
@js: URL 构造 JsCaller 模板 function func(r) { %s; return r; } 要求赋值 r = ...,但即使正确赋值书源也消失
Content-Type 过滤 源码中无任何 Content-Type 检查
Request Body 类型 buildData 使用 FormBodyapplication/x-www-form-urlencoded
服务器可达性 curl 同 URL/POST body → HTTP 200 + 10 条(8814 bytes),含 gzip 测试亦正常
超时 显式设置 timeout: 10000 无效
书源顺序 交换两个书源顺序后现象相同

关键规律

所有语法有错误的配置(JSON 不合法、URL 含非法字符如逗号)→ 书源出现 + 明确错误信息

所有语法正确的配置 → 书源完全消失,无任何输出

这说明书源确实被搜索了,HTTP 请求成功发出、服务器响应了,但 getSearchResults() 返回空列表。

相关源码分析

已阅读以下源文件(可提供完整代码):

  1. SearchParser.javaparse()getSearchResults() 方法
  2. HtmlExtractor.javaextract()select() 方法
  3. CrawlUtils.javabuildData()request() 方法
  4. Rule.java — 数据模型

SearchParser.parse() 流程:

java
// 1. 构造请求
String searchUrl = processUrl(r.getUrl(), keyword);  // url.formatted(keyword)
Request.Builder builder = new Request.Builder().url(searchUrl);
if ("post".equalsIgnoreCase(r.getMethod())) {
    builder.post(CrawlUtils.buildData(r.getData(), keyword));  // FormBody
}

// 2. 发送请求
resp = CrawlUtils.request(httpClient, builder, r.getTimeout());

// 3. 解析响应
String body = processResultWithJs(resp.peekBody(Long.MAX_VALUE).string(), r.getResult());
document = Jsoup.parse(body, r.getBaseUri());

// 4. 提取结果
List<SearchResult> firstPageResults = getSearchResults(null, resp);

getSearchResults() 中关键过滤逻辑:

java
Elements resultEls = document.select(resultSelector);

List<Element> limitResultEls = resultEls.stream()
    .filter(e -> StrUtil.isNotEmpty(HtmlExtractor.extract(e, r.getBookName())))
    .limit(...)
    .toList();

怀疑方向

源码层面未发现明显 bug。但以下线索值得关注:

  1. 第一版主返回 Content-Type: application/xhtml+xml(含 <?xml version="1.0"?> 声明和 XHTML Mobile DOCTYPE),虽然源码无 Content-Type 检查,但 Jsoup 的 parse(String) 在遇到 XML 声明 + XHTML DOCTYPE 时内部行为可能有差异

  2. 同一站点的书详情页(CLI 下载)能正常解析——下载用 BookParser 也是 Jsoup.parse(String),但书详情页和搜索页的结构/DOCTYPE 完全相同。两者的区别仅在于:BookParser 直接用 selectFirst("h1") 而 SearchParser 多了 filter(e -> ...) 一步

  3. result 选择器设为 "li" 仍无结果——即使是页面上必定存在的通用元素也匹配不到,说明书页的 Jsoup DOM 本身可能为空或异常

复现步骤

  1. 创建 custom.json,内容如下:
json
[
  {
    "url": "https://m.diyibanzhu.website",
    "name": "第一版主",
    "search": {
      "url": "https://m.diyibanzhu.website/wap.php?action=search&wd=%s&objectType=2",
      "method": "get",
      "result": "li.column-2",
      "bookName": ".right a.name",
      "author": "p.info"
    },
    "book": { "url": "/list/(.*?).html", "bookName": "h1", "author": "p.info" },
    "toc": { "baseUri": "https://m.diyibanzhu.website", "item": "/html//ul[@class='list']//a[contains(@href,'/view/')]" },
    "chapter": { "title": ".bookname > h1", "content": "#nr1", "paragraphTagClosed": false, "paragraphTag": "<br>+", "filterTxt": "本章未完.*?>>|【\\d+】", "filterTag": "script, style" }
  }
]
  1. config.ini 设为 active-rules = custom.json, search-filter = 0

  2. 启动 SoNovel,搜索「凡人」

  3. 预期:应显示 10 条搜索结果;实际:书源完全无输出

复现步骤

Image