【问题标题】:HTML Mixed Encodings?HTML混合编码?
【发布时间】:2011-09-28 14:48:58
【问题描述】:

首先我要提前感谢您的帮助。

我目前正在编写一个网络爬虫,它可以解析 HTML 内容、去除 HTML 标签,然后对从解析中检索到的文本进行拼写检查。

使用 JSoup 和 Google Spell Check API,剥离 HTML 标签和拼写检查没有造成任何问题。

我能够从 URL 中提取内容并将此信息传递到 byte[] 中,然后最终传递到 String 中,以便可以对其进行剥离和拼写检查。我遇到了字符编码问题。

例如解析http://www.testwareinc.com/时...

原文:我们扩展了我们的移动网络和移动应用测试服务。

...根据元标记,该页面正在使用 ISO-8859-1...

ISO-8859-1 Parse:我们扩展了我们的移动网络和移动应用测试服务。

...然后尝试使用 UTF-8...

UTF-8 Parse:我们扩展了我们的移动网络和移动应用测试服务。

问题 网页的 HTML 是否可能包含多种编码?以及如何检测到?

【问题讨论】:

  • 处理文本很糟糕。祝你好运!
  • 快速浏览(只是在浏览器中,而不是在十六进制编辑器中),该字符看起来像是一个有效的 ISO-8559-1 字符。你为什么认为这里有两种编码?您的解析器不可能以某种方式简单地吞下字符吗?
  • 感谢 cdeszaq 我已经在这个爬虫上工作了大约 6 个月,解析是唯一给我带来问题的部分,但我有点知道它会因为“in-the-wild” HTML可能因站点而异。
  • 我在想 CP1252 和 ISO-8859-1 是在互相玩游戏。我使用了 juniversalchardet,如下所述,它通知我页面上的内容实际上不是 ISO-8859-1。至少我可以找出我应该使用什么来获得尽可能多的数据,如果我有点松懈的话。

标签: java html parsing encoding web-crawler


【解决方案1】:

看起来撇号被编码为 0x92 字节,根据Wikipedia,这是一个未分配/私有代码点。

从那里开始,浏览器似乎通过假设它是一个未编码的 1 字节 Unicode 代码点来回退:+0092私人使用两个)似乎表示为撇号。不用等,如果是一个字节,则更可能是cp1252:浏览器必须根据宣传的 CP 有一个后备策略,例如 ISO-8859-1 -> CP1252。

所以这里没有混合编码,但正如其他人所说的那样,文件损坏了。但是使用后备启发式有时会有所帮助,有时不会。

如果你足够好奇,你可能想深入研究 FF 或 Chrome 的源代码,看看他们在这种情况下到底做了什么。

【讨论】:

  • 运行 juniversalchardet 时您是正确的,我看到该页面实际上是 CP1252,而不是元标记中设置的 ISO-8859-1。当使用 CP1252 作为字符集解码 InputStream 时,撇号会正确显示。
【解决方案2】:

在一个文档中有超过 1 个编码不是混合文档,而是一个损坏的文档。

不幸的是,有很多网页使用的编码与文档定义不匹配,或者包含一些在给定编码中有效的数据和一些无效的内容。

没有很好的方法来处理这个问题。可以尝试猜测文档的编码,但这很困难并且不是 100% 可靠的。在像您这样的情况下,最简单的解决方案就是忽略文档中无法解码的部分。

【讨论】:

  • 感谢您的回复,不幸的是,这就是我所害怕的。看起来我将能够使用 juniversalchardet 准确地检测到编码。但我相信即使这样也会引起问题。例如,使用 juniversalchardet 发现 HTML 使用的是 cp1252,而不是元标记中概述的 ISO-8859-1。再次感谢!
【解决方案3】:

Apache Tika 有一个编码检测器。如果您需要 C++ 中的某些东西并且有能力花钱,也有商业替代品。

我几乎可以保证每个网页都采用 one 编码,但是很容易误认为 哪个

【讨论】:

  • 我同意我决定选择 juniversalchardet。它似乎运作良好。如果 juniversalchardet 找不到字符集,我可能想研究一种使用元标记作为后备的方法。
【解决方案4】:

似乎是特殊字符的问题。如果有帮助,请检查此StringEscapeUtils.escapeHtml。或那里的任何方法

已编辑:添加此逻辑,因为他无法让代码正常工作

public static void main(String[] args) throws FileNotFoundException {
        String asd = "’";
        System.out.println(StringEscapeUtils.escapeXml(asd)); //output - ’
    System.out.println(StringEscapeUtils.escapeHtml(asd)); //output - ’
}

【讨论】:

  • @daniel 奇怪的是人们认为问题的唯一解决方案是调查问卷的内容。在你否定答案之前,你可以等他评论这不是他的解决方案。
  • No StringEscapeUtils 将不起作用。我试过了。在源代码中,撇号被编码为撇号而不是 HTML ’所以不,这是行不通的。
  • @spitpsu 请检查您的编码。我尝试了逻辑,我得到了如上所示的输出。从问题中复制您的角色并再次尝试逻辑或使用我的代码。代码工作正常。如果它对您有用,请接受答案。你的问题已经让我损失了 4 分
  • @Daniel 希望你能看到我的方式也可以实现逻辑:P
  • 巴布,我完全理解,是的,您第一次正确执行的代码,逻辑没有问题。我只是说你给出的答案不是问题的适当答案。我问的是关于分析 HTML 文档的字符集而不是如何转换特定字符的问题,我提供的 URL 只是一个示例。
猜你喜欢
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2016-06-21
  • 2012-04-18
  • 1970-01-01
相关资源
最近更新 更多