java.util.Сканер и Википедия
-
22-08-2019 - |
Вопрос
Я пытаюсь использовать java.util.Scanner, чтобы взять содержимое Википедии и использовать его для поиска по словам.Дело в том, что всё нормально, но при чтении некоторых слов у меня выдаёт ошибки.Глядя на код и проверяя, что с некоторыми словами, кажется, не распознает кодирование, или около того, и контент больше не читается.Это код, используемый для открытия страницы:
// -Начинать-
try {
connection = new URL("http://it.wikipedia.org
wiki/"+word).openConnection();
Scanner scanner = new Scanner(connection.getInputStream());
scanner.useDelimiter("\\Z");
content = scanner.next();
// if(word.equals("pubblico"))
// System.out.println(content);
System.out.println("Doing: "+ word);
//End
Проблема возникает со словами «pubblico» в итальянской Википедии.результат println для слова pubblico выглядит следующим образом (вырезано):ï¿ïn½] ksr> ï ï ~ e ï ï ï ï ï ï ï ï ï; ¿½ ½ уже}
У вас есть идеи, почему?Тем не менее, если посмотреть на исходный код страницы, заголовки одинаковы, с той же кодировкой...
Оказалось, что контент заархивирован, так что могу ли я попросить Википедию не присылать мне свои страницы в заархивированном виде, или это единственный способ?Спасибо
Решение
Попробуйте использовать Reader
вместо InputStream
- Я думаю, это работает примерно так:
connection = new URL("http://it.wikipedia.org/wiki/"+word).openConnection();
String ctype = connection.getContentType();
int csi = ctype.indexOf("charset=");
Scanner scanner;
if (csi > 0)
scanner = new Scanner(new InputStreamReader(connection.getInputStream(), ctype.substring(csi + 8)));
else
scanner = new Scanner(new InputStreamReader(connection.getInputStream()));
scanner.useDelimiter("\\Z");
content = scanner.next();
if(word.equals("pubblico"))
System.out.println(content);
System.out.println("Doing: "+ word);
Вы также можете просто передать кодировку конструктору сканера напрямую, как указано в другом ответе.
Другие советы
Попробуйте использовать Сканер с указанным набором символов:
public Scanner(InputStream source, String charsetName)
Для конструктора по умолчанию:
Байты из потока преобразуются в символы с использованием кодировки по умолчанию базовой платформы.
Вам нужно использовать URLConnection
, чтобы вы могли определить заголовок типа контента в ответ.Это должно указать вам кодировку символов, которую вы будете использовать, когда вы создай свой Scanner
.
В частности, обратите внимание на параметр «charset» заголовка типа контента.
Чтобы запретить сжатие gzip, установить заголовок принятия-кодирования к «идентичности».Видеть спецификация HTTP Чтобы получить больше информации.
connection = new URL("http://it.wikipedia.org/wiki/"+word).openConnection();
connection.addRequestProperty("Accept-Encoding","");
System.out.println(connection.getContentEncoding());
Scanner scanner = new Scanner(new InputStreamReader(connection.getInputStream()));
scanner.useDelimiter("\\Z");
content = new String(scanner.next());
кодировка не меняется.почему?
connection = new URL("http://it.wikipedia.org/wiki/"+word).openConnection();
//connection.addRequestProperty("Accept-Encoding","");
//System.out.println(connection.getContentEncoding());
InputStream resultingInputStream = null; // Stream su cui fluisce la pagina scaricata
String encoding = connection.getContentEncoding(); // Codifica di invio (identity, gzip, inflate)
// Scelta dell'opportuno decompressore per leggere la sorgente
if (connection.getContentEncoding() != null && encoding.equals("gzip")) {
resultingInputStream = new GZIPInputStream(connection.getInputStream());
}
else if (encoding != null && encoding.equals("deflate")) {
resultingInputStream = new InflaterInputStream(connection.getInputStream(), new Inflater(true));
}
else {
resultingInputStream = connection.getInputStream();
}
// Scanner per estrarre dallo stream la pagina per inserirla in una stringa
Scanner scanner = new Scanner(resultingInputStream);
scanner.useDelimiter("\\Z");
content = new String(scanner.next());
Так работает!!!