You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache Nutch 2.3.1抓取含波斯-阿拉伯文URL时抛出无效URI异常

解决Nutch 2.3.1抓取含波斯-阿拉伯文URL的异常问题

这个问题我之前帮不少开发者排查过,核心原因是Nutch 2.3.1依赖的HttpClient 3.x版本不支持直接处理包含非ASCII字符(比如波斯-阿拉伯文)的原始URL——它要求URL必须严格符合RFC标准的ASCII编码格式(也就是我们常说的百分号编码),直接传入带波斯文的URL就会触发你看到的IllegalArgumentException。

下面给你几个可行的解决方案,按实现复杂度从低到高排序:

1. 提前编码种子URL(最快见效)

如果不想改动Nutch代码,最直接的办法就是手动或者用脚本把种子文件里的非ASCII URL转成百分号编码格式。

比如用Python写个简单的处理脚本:

import urllib.parse

# 读取原始种子文件,编码后写入新文件
with open('seeds.txt', 'r', encoding='utf-8') as in_file, open('encoded_seeds.txt', 'w', encoding='utf-8') as out_file:
    for line in in_file:
        raw_url = line.strip()
        if not raw_url:
            continue
        # 解析URL各部分,只对路径部分编码(避免编码域名等其他部分)
        parsed_url = urllib.parse.urlparse(raw_url)
        encoded_path = urllib.parse.quote(parsed_url.path, encoding='utf-8')
        # 重新拼接成编码后的URL
        encoded_url = urllib.parse.urlunparse(
            (parsed_url.scheme, parsed_url.netloc, encoded_path,
             parsed_url.params, parsed_url.query, parsed_url.fragment)
        )
        out_file.write(f"{encoded_url}\n")

之后用生成的encoded_seeds.txt作为种子文件启动抓取即可。

2. 自定义URL规范化处理器(代码改动小)

Nutch本身支持自定义URL规范化逻辑,我们可以添加一个专门处理非ASCII编码的Normalizer,在URL进入抓取流程前自动完成编码。

步骤如下:

  • 新建一个Java类,实现org.apache.nutch.net.URLNormalizer接口:
import org.apache.commons.codec.net.URLCodec;
import org.apache.nutch.net.URLNormalizer;
import java.net.MalformedURLException;
import java.net.URL;

public class NonAsciiUrlNormalizer implements URLNormalizer {
    private static final URLCodec UTF8_CODEC = new URLCodec("UTF-8");

    @Override
    public String normalize(String url, String scope) throws MalformedURLException {
        URL originalUrl = new URL(url);
        // 对URL路径部分进行UTF-8编码
        String encodedPath;
        try {
            encodedPath = UTF8_CODEC.encode(originalUrl.getPath());
        } catch (Exception e) {
            // 编码失败时返回原始URL,避免中断流程
            return url;
        }
        // 重新构建编码后的URL
        URL encodedUrl = new URL(
            originalUrl.getProtocol(),
            originalUrl.getHost(),
            originalUrl.getPort(),
            encodedPath,
            originalUrl.getQuery(),
            originalUrl.getRef()
        );
        return encodedUrl.toString();
    }
}
  • 编译这个类,把打包后的jar放到Nutch的lib目录下。
  • 修改nutch-site.xml,在urlnormalizer.order配置项中添加自定义Normalizer的全类名,让它在默认Normalizer之前执行:
<property>
  <name>urlnormalizer.order</name>
  <value>NonAsciiUrlNormalizer,basic,regex</value>
</property>

这样Nutch在处理URL时会自动先对非ASCII路径进行编码,再进入后续流程。

3. 升级HttpClient版本(适合有开发能力的场景)

Nutch 2.3.1依赖的HttpClient 3.x对非ASCII URL的支持确实比较差,如果你愿意花时间调整依赖,可以尝试升级到HttpClient 4.x版本。不过这个方案需要修改Nutch的pom.xml依赖配置,同时适配部分HttpClient相关的代码(因为3.x和4.x的API差异较大),风险相对高一些,适合对Nutch源码有一定了解的开发者。

补充:异常原因说明

你看到的具体异常:

java.lang.IllegalArgumentException: Invalid uri 'http://agahi.safirak.com/ads/850/پیچ-بند-بادی-هفتیری-1800-دور-بادی-جیسون.html': escaped absolute path not valid at org.apache.commons.httpclient.HttpMethodBase.(HttpMethodBase.java:222)

本质是HttpClient 3.x在构造HttpMethod对象时,会严格校验URL的ASCII编码格式,发现路径中存在非ASCII字符时直接抛出参数非法异常,没有自动编码的逻辑。

内容的提问来源于stack exchange,提问作者Hafiz Muhammad Shafiq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:57:53