Подтвердить что ты не робот

Проблема кодирования символов 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.

Есть ли способ? метки могут быть оригинальными (ü) снова на выходе?

4b9b3361

Ответ 1

Атрибут charset отсутствует в заголовке ответа HTTP Content-Type. Jsoup будет применять кодировку по умолчанию для платформы при анализе HTML. Document.OutputSettings#charset() не будет работать так, как он использовался только для презентации (в html() и text()), а не для синтаксического анализа данных (другими словами, это уже слишком поздно).

Вам нужно прочитать URL как 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.

Ответ 2

Ну, я понял, как это сделать. В моем случае у меня был объект Jsoup Connection, и я хотел получить html-ответ из запроса post() на веб-сайте, который был закодирован с помощью "ISO-8859". Поскольку кодировка по умолчанию для JSOUP - это UTF-8, контент из ответа (html) шел с заменой некоторых букв. Мне нужно было каким-то образом преобразовать его в ISO-8859-15. Для этого я создал соединение

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

После этого я создал ответный документ, в котором содержится ответ на сообщение. Из-за того, что было непонятно, как мы можем установить кодировку ответа в Jsoup, я решил выполнить пост, а затем сохранить ответ в виде байтов, сохраняя свойства кодирования. После этого я создал новую строку, передающую этот массив байтов, и правильную кодировку, которая должна быть применена. После этого документ будет создан с правильной кодировкой.

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

Итак, есть возврат до и после модификации, когда мы используем response.html()

До:

62.09-1-00 - Suporte t cnico, manuten o e outros servi os em tecnologia da informa o

После:

62.09-1-00 - Suporte técnico, manutenção e outros serviços em tecnologia da informação

Ответ 3

В документации Jsoup указано, что Jsoup должен автоматически определять правильную кодировку при чтении в документе, но по какой-то причине она не работает для меня. Затем я попытался вручную установить кодировку Document с помощью функции outputSettings(). 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.

Ответ 4

Я использовал:

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

Кроме того, сохранен класс как UTF-8