JSoup字符编码问题

时间:2011-10-09 12:17:41

标签: java jsoup

我正在使用JSoup来解析来自http://www.latijnengrieks.com/vertaling.php?id=5368的内容。这是第三方网站,未指定正确的编码。我使用以下代码加载数据:

public class Loader {

    public static void main(String[] args){
        String url = "http://www.latijnengrieks.com/vertaling.php?id=5368";

        Document doc;
        try {

            doc = Jsoup.connect(url).timeout(5000).get();
            Element content = doc.select("div.kader").first();
            Element contenttableElement = content.getElementsByClass("kopje").first().parent().parent();

            String contenttext = content.html();
            String tabletext = contenttableElement.html();

            contenttext = Jsoup.parse(contenttext).text();
            contenttext = contenttext.replace("br2n", "\n");
            tabletext = Jsoup.parse(tabletext.replaceAll("(?i)<br[^>]*>", "br2n")).text();
            tabletext = tabletext.replace("br2n", "\n");

            String text = contenttext.substring(tabletext.length(), contenttext.length());
            System.out.println(text);


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }    

}

这给出了以下输出:

Aeneas dwaalt rond in Troje en zoekt Cre?sa. Cre?sa is echter op de vlucht gestorven Plotseling verschijnt er een schim. Het is de schim van Cre?sa. De schim zegt:'De oorlog woedt!' Troje is ingenomen! Cre?sa is gestorven:'Vlucht!' Aeneas vlucht echter niet. Dan spreekt de schim:'Vlucht! Er staat jou een nieuw vaderland en een nieuw koninkrijk te wachten.' Dan pas gehoorzaamt Aeneas en vlucht.

有什么办法吗?标记可以是输出中的原始(ü)吗?

4 个答案:

答案 0 :(得分:47)

HTTP响应charset标头中缺少Content-Type属性。在解析HTML时,Jsoup将使用平台默认字符集。 Document.OutputSettings#charset()将无效,因为它仅用于演示文稿(在html()text()上),而不是用于解析数据(换句话说,已经太晚了)。

您需要将网址读作InputStream并在Jsoup#parse()方法中手动指定字符集。

String url = "http://www.latijnengrieks.com/vertaling.php?id=5368";
Document document = Jsoup.parse(new URL(url).openStream(), "ISO-8859-1", url);
Element paragraph = document.select("div.kader p").first();

for (Node node : paragraph.childNodes()) {
    if (node instanceof TextNode) {
        System.out.println(((TextNode) node).text().trim());
    }
}

此结果在

Aeneas dwaalt rond in Troje en zoekt Creüsa.
Creüsa is echter op de vlucht gestorven
Plotseling verschijnt er een schim.
Het is de schim van Creüsa.
De schim zegt:'De oorlog woedt!'
Troje is ingenomen!
Creüsa is gestorven:'Vlucht!'
Aeneas vlucht echter niet.
Dan spreekt de schim:'Vlucht! Er staat jou een nieuw vaderland en een nieuw koninkrijk te wachten.'
Dan pas gehoorzaamt Aeneas en vlucht.

答案 1 :(得分:12)

好吧,我想出了另一种方法。在我的例子中,我有一个Jsoup Connection对象,我想从一个用“ISO-8859”编码的网站中的post()请求中检索html响应。由于JSOUP的默认编码是UTF-8,因此来自响应(html)的内容 替换了一些字母。我需要以某种方式将其转换为ISO-8859-15。为了执行该操作,我创建了连接

Connection connectionTest = Jsoup.connect("URL")
.cookie("cookiereference", "cookievalue")
.method(Method.POST);

之后,我创建了一个回复文档,其中包含帖子的答案。由于我们不清楚如何在Jsoup中设置响应的编码这一事实,我选择执行post然后将响应保存为Bytes,保留编码属性。之后,我创建了一个新的String传递这个字节数组和必须应用的正确编码。之后,将使用正确的编码创建文档。

Document response = Jsoup.parse(new String(
connectionTest.execute().bodyAsBytes(),"ISO-8859-15"));

因此,当我们使用response.html()

时,修改前后会有返回

在:

62.09-1-00 - Suportet cnico,manuten oeoutrosservi osemtecnologiadainforma o

后:

62.09-1-00 - Suportetécnico,manutençãoeoutrosserviçosemtecnologiadainformação

答案 2 :(得分:5)

Jsoup文档声明Jsoup在阅读文档时应该自动检测正确的字符集,但由于某种原因,它对我不起作用。然后我尝试使用outputSettings()手动设置Document的字符集.charset(...):

doc.outputSettings().charset("ISO-8859-1");

但那仍然没有用,所以也许我做错了(我只是在学习Jsoup)。

至少对我来说,一个可行的方法是使用具有字符集集的扫描仪在网页中阅读:

     String charset = "ISO-8859-1";

     URL myUrl = new URL(url);
     Scanner urlScanner = new Scanner(myUrl.openStream(), charset);
     StringBuilder sb = new StringBuilder();
     while (urlScanner.hasNextLine()) {
        sb.append(urlScanner.nextLine() + "\n");
     }
     urlScanner.close();

     doc = Jsoup.parse(sb.toString());

但是我会关注这个帖子,看看是否有人提出了一个更好的建议,一个不需要使用另一个类来阅读HTML的建议。

答案 3 :(得分:-1)

我用过:

public static String charset = "UTF-8";
doc = Jsoup.parse(new URL(theURL).openStream(), charset, theURL);

另外,将课程保存为UTF-8