java.util.Scanner e Wikipedia
-
22-08-2019 - |
Domanda
Sto cercando di utilizzare java.util.Scanner per prendere i contenuti di Wikipedia e usarlo per ricerche basate parola. Il fatto è che è tutto bene, ma quando la lettura di alcune parole che mi danno errori. Guardando il codice e fare qualche controllo si è scoperto che con alcune parole sembra non riconoscere la codifica, o giù di lì, e il contenuto non è più leggibile. Questo è il codice usato per prendere la pagina:
// -Start -
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
Il problema si pone con parole come "Pubblico" per la wikipedia italiana. il risultato della println sulla parola Pubblico è come questo (tagliate): ï¿ï¿½] KSR> � ~ E �1A���E�ER3tHZ�4v�� & PZjtc�¿½ï¿½D�7_ | ���� = 8��Ø}
Avete qualche idea del perché? Eppure hanno esaminato sorgente della pagina e intestazioni sono gli stessi, con stessa codifica ...
è scoperto che il contenuto è compresso con gzip, quindi posso dire wikipedia non mandarmi teir pagine zip o è l'unico modo? grazie
Soluzione
provare a utilizzare un Reader
invece di un InputStream
- penso che funziona in questo modo:
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);
Si potrebbe anche solo passare il charset al costruttore scanner direttamente, come indicato in un'altra risposta.
Altri suggerimenti
Provare a utilizzare lo scanner con un set di caratteri specificato:
public Scanner(InputStream source, String charsetName)
Per il costruttore di default:
byte dal flusso sono convertiti in caratteri utilizzando charset di default della piattaforma sottostante.
È necessario utilizzare un URLConnection
, in modo che è possibile determinare il content-type intestazione nella risposta. Questo dovrebbe dire la codifica dei caratteri da utilizzare quando si creare il Scanner
.
In particolare, guardare il parametro "charset" dell'intestazione Content-Type.
Per inibire la compressione gzip, impostare il Accept-Encoding intestazione di "identità". Vedere specifiche HTTP per ulteriori informazioni.
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 non cambia. perché?
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());
Così funziona !!!