2011年11月14日月曜日

Jericho HTML で一部サイトが文字化け

前回のソースで一部サイトが文字化けを起こした。

Souce のコンストラクタに URLを渡した場合は、ヘッダー情報の Content-Type の charset からエンコードが取得できるかもだが(Jericho が取得しているかは未調査)、BODY 部分のストリームを渡す場合、取得出来ないため内容から自動判別すようで、そこがおかしくなっているようだった。
なので指定してやることに、
HttpClient http = new DefaultHttpClient();
HttpResponse res = http.execute(new HttpGet(URI.create("http://www.example.com")));
if (res.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
{
  LOG.error("Failed to load uri.");
  return false;
}    

InputStream in = res.getEntity().getContent();
if (res.getHeaders("Content-Encoding").length > 0 &&
  "gzip".equals(res.getHeaders("Content-Encoding")[0].getValue()))
  in = new GZIPInputStream(in);

String charset = EntityUtils.getContentCharSet(res.getEntity());

Source source = null;
if (charset != null) source = new Source(new InputStreamReader(in, charset));
else source = new Source(in);
14 行目で Content-Type の charset からエンコードを取得して、指定があれば、17 行明で明示的に指定してやることに。直接渡しているので、Shift_JIS 等で部分的に文字化けがおきそうだがとりあえず。

Source(final Reader reader) の実装が、
this(reader,(reader instanceof InputStreamReader) ? ((InputStreamReader)reader).getEncoding() : null);
となっていて、instanceof が気に入らない。Source(final Reader reader, final String encoding) が public だといいのだが。

Content-Type の charset がなければ今まで通り自動判別。

もっとスマートにいかないものか・・・

0 件のコメント:

コメントを投稿