提问人:luiss 提问时间:2/12/2009 最后编辑:skaffmanluiss 更新时间:5/15/2011 访问量:3806
java.util.Scanner 和维基百科
java.util.Scanner and Wikipedia
问:
我正在尝试使用 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”一词上。 Word pubblico 上的 println 结果是这样的(剪切): ï¿ï¿1/2]Ksr>ï¿1/2~E 1/21Aï¿1/2ï¿1/2ï¿1/2Eï¿1/2ER3tHZï¿1/24vï¿1/2ï¿1/2&PZjtcï¿1/2¿1/2ï¿1/2Dï¿1/27_|ï¿1/2ï¿1/2ï¿1/2ï¿1/2=8ï¿1/2ï¿1/2Ø}
你知道为什么吗?然而,查看页面源和标题是相同的,具有相同的编码......
原来内容是 gzip 压缩的,所以我可以告诉维基百科不要向我发送压缩的页面,或者这是唯一的方法吗?谢谢
答:
尝试使用具有指定字符集的扫描仪:
public Scanner(InputStream source, String charsetName)
对于默认构造函数:
流中的字节使用基础平台的默认字符集转换为字符。
尝试使用 a 而不是 an - 我认为它的工作原理是这样的: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);
您也可以直接将字符集传递给 Scanner 构造函数,如另一个答案所示。
评论
您需要使用 ,以便可以确定响应中的 content-type 标头。这应该会告诉您在创建扫描仪
时要使用的字符编码。URLConnection
具体而言,请查看 content-type 标头的“charset”参数。
要禁止 gzip 压缩,请将 accept-encoding 标头设置为“identity”。有关详细信息,请参阅 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());
所以有效!!
评论