Символы HTML с загруженной страницы отображаются неправильно

#java #html #character-encoding

#java #HTML #кодировка символов

Вопрос:

Некоторые страницы содержат специальные символы HTML, но они отображаются в виде квадрата (неизвестный символ).

Что я могу сделать?

Могу ли я преобразовать строку, содержащую символы, в другой формат (UTF-8)? Это происходит при преобразовании из InputStream в String. Я действительно не знаю, что является причиной этого.

 public HttpURLConnection openConnection(String url) {
    try {
        URL urlDownload = new URL(url);
        HttpURLConnection con = (HttpURLConnection) urlDownload.openConnection();
        con.setInstanceFollowRedirects(true);
        con.connect();
        return con;
    } catch (Exception e) {
        return null;
    }
}

private String getContent(HttpURLConnection con) {
    try {
        return IOUtils.toString(con.getInputStream());
    } catch (Exception e) {
        System.out.println("Erro baixando página: "   e);
        return null;
    }
}

page.setContent(getContent(openConnection(con)));
  

Комментарии:

1. Не могли бы вы включить свой текущий код?

Ответ №1:

Вам необходимо прочитать кодировку InputStream using InputStreamReader , как указано в Content-Type заголовке загруженной HTML-страницы. В противном случае будет использоваться кодировка платформы по умолчанию, которая, по-видимому, не совпадает с кодировкой HTML в вашем случае.

 Reader reader = new InputStreamReader(input, "UTF-8");
// ...
  

Вы, конечно, также можете использовать программу чтения / синтаксического анализа HTML, такую как Jsoup, которая автоматически учитывает это.

 String html = Jsoup.connect("http://stackoverflow.com").get().html();
  

Обновление: согласно вашему обновленному вопросу, вы, похоже, используете URLConnection для запроса HTML-страницы и IOUtils преобразования InputStream в String . Вам нужно использовать это следующим образом:

 String contentType = connection.getHeaderField("Content-Type");
String charset = "UTF-8"; // Default to UTF-8
for (String param : contentType.replace(" ", "").split(";")) {
    if (param.startsWith("charset=")) {
        charset = param.split("=", 2)[1];
        break;
    }
}

String html = IOUtils.toString(input, charset);
  

Если у вас все еще возникают проблемы с правильным набором символов, то это может означать только то, что консоль / средство просмотра, на которое вы печатаете эти символы, не поддерживает кодировку. Например, когда вы запускаете следующее в Eclipse

 System.out.println(html);
  

Затем вам нужно убедиться, что консоль Eclipse использует UTF-8. Вы можете установить это с помощью Window > Preferences > General > Workspace > Кодировка текстового файла.

Или, если вы записываете это в какой-либо файл с помощью FileWriter , тогда вам лучше использовать InputStream / OutputStream с самого начала, не преобразовывая его сначала в String . Если преобразование в String действительно важный шаг, то вам нужно записать его в new OutputStreamWriter(output, "UTF-8") .

Комментарии:

1. С Jsoup все то же самое, но я попробую с InputStreamReader.

2. Тогда это программа просмотра / консоль, которая не поддерживает кодировку. Где вы печатаете / просматриваете содержимое HTML? Например, в консоли Eclipse? Вам необходимо настроить его на поддержку UTF-8. Или вы записываете это в файл? Затем вам нужно использовать ту же кодировку в Writer . Для получения дополнительной справочной информации проверьте balusc.blogspot.com/2009/05 /…

3. Хорошо, я знаю, что мне теперь нужно делать, но на некоторых страницах кодировка указана не в атрибуте charset, а в той или иной кодировке (различия между HTML, XHTML и т.д.) Есть какой-нибудь класс для автоматического получения этого? Я использую HTMLParser для синтаксического анализа HTML. Я использовал ISO-8859-1 на странице с проблемами, и это было решено. Теперь мне нужно только получить кодировку на страницах.

4. Jsoup делает это автоматически. Ваша проблема заключается в том, как вы печатаете / сохраняете HTML-строку.

5. Я использую Postgres и, прежде чем правильно преобразовать его, в базе данных строка тоже отображается неправильно. После преобразования теперь отображаются правильно.