java.nio.charset.UnsupportedCharsetException:Jsoup 中的 X-MAC-ROMAN 获取网页

The*_*ner 1 java character-encoding jsoup

我有

Document document = Jsoup.connect(link).get();
Run Code Online (Sandbox Code Playgroud)

有时对于某些网址,我会遇到异常:

Exception in thread "main" java.nio.charset.UnsupportedCharsetException: X-MAC-ROMAN
    at java.nio.charset.Charset.forName(Unknown Source)
    at org.jsoup.helper.DataUtil.parseByteData(DataUtil.java:86)
    at org.jsoup.helper.HttpConnection$Response.parse(HttpConnection.java:469)
    at org.jsoup.helper.HttpConnection.get(HttpConnection.java:147)
Run Code Online (Sandbox Code Playgroud)

我有一个 catch 块:

catch (IOException  e1)
Run Code Online (Sandbox Code Playgroud)

我理解这个例外是因为 java 是 unicode 并且该网页/站点没有遵循 unicode。如何处理这个问题,connect 也被用于包括 unicode 和 bytecode 在内的许多网站

Bal*_*usC 5

我理解这个例外是因为 java 是 unicode 并且该网页/站点没有遵循 unicode。

这并不完全正确。您可能会将“Java 是 unicode”这句话与 Java 使用 Unicode 在内存中存储字符串/字符这一事实混淆(您知道,计算机内存只能存储字节(零和一),而不是字符,因此字符需要转换为字节并使用特定的字符编码返回;Java 为此使用 unicode)。

出现此异常是因为您的 Java 代码运行的底层操作系统平台不支持此字符集,因此 Java 无法将 Web 服务器获取的字节转换为此编码中的字符。此字符集特定于 Mac OS 平台,您可能正在运行 Windows 左右。


如何处理这个问题

联系网站管理员并将其报告为错误。他们使用特定于平台的 (Mac OS) 编码而不是通用 (ISO/UTF) 编码是他们的错

至于Jsoup,最好的办法是让网站,InputStream通过URL#openStream()第一,然后将其提供给Jsoup#parse()代替,其中明确指定哪些支持您的平台上的字符编码,如ISO-8859-1。例如:

Document doc = Jsoup.parse(new URL(link).openStream(), "ISO-8859-1", link);
Run Code Online (Sandbox Code Playgroud)

请注意,当存在非 ASCII 字符时,您仍有可能以Mojibake结束。另请注意,您不应该对所有链接都这样做,而应该只对那些抛出的链接UnsupportedCharsetException(因此,在其catch块中执行工作)。


但我可以在我的 chrome 中访问它,为什么不能从 Jsoup

那是因为 Chrome 试图对您如此友好,以至于它忽略了未知编码并选择了默认编码——这可能仍然存在网站在 Mojibake 中显示的风险;超出 ASCII 范围的任何内容都可能看起来格式不正确。


connect 用于许多网站,包括 unicode 和字节码

请刷新您的词汇表,了解“字节码”一词的含义。这与字符编码完全无关。