java.util.Scanner e Wikipedia
-
22-08-2019 - |
Pergunta
Eu estou tentando usar java.util.Scanner tomar conteúdo da Wikipédia e usá-lo para buscas baseadas em palavras. O fato é que está tudo bem, mas quando ler algumas palavras que me dar erros. Olhando para o código e fazer alguma verificação descobriu-se que com algumas palavras que parece não reconhecer a codificação, ou assim, eo conteúdo não mais legível é. Este é o código usado para tirar a página:
// -Comece -
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
O problema surge com palavras como "pubblico" para a wikipedia italiana. o resultado do println na palavra pubblico é assim (cortado): ï¿ï¿½] Ksr> � ~ E �1A���E�ER3tHZ�4v�� & PZjtc�¿½ï¿½D�7_ | ���� = 8��Ø}
Você tem alguma idéia de por que? No entanto, olhou para fonte de página e cabeçalhos são os mesmos, com a mesma codificação ...
Descobriu-se que o conteúdo é compactado, para que eu possa dizer wikipedia não me enviar teir páginas fechado ou é a única maneira? obrigado
Solução
Tente usar um Reader
em vez de um InputStream
- Eu acho que funciona assim:
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);
Você também pode apenas passar o charset para o construtor Scanner directamente como indicado em outra resposta.
Outras dicas
Tente utilizar o scanner com um conjunto de caracteres especificado:
public Scanner(InputStream source, String charsetName)
Para o construtor padrão:
bytes do fluxo são convertidos em caracteres usando charset padrão da plataforma subjacente.
Você precisa usar um URLConnection
, de modo que você pode determinar o do tipo de conteúdo cabeçalho na resposta. Isso deve dizer-lhe a codificação de caracteres para usar quando você criar seu Scanner
.
Especificamente, olhe para o parâmetro "charset" do cabeçalho do tipo de conteúdo.
Para inibir gzip compressão, definir o cabeçalho aceitar que codifica para "identidade". Consulte o HTTP especificação para obter mais informações.
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());
codificação não muda. por quê?
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());
Assim funciona !!!