reqwestで適当なURLからページのコンテンツを取得する場合、以下のようなコードを実装するかと思います。
use reqwest;
# [tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let body = reqwest::get("https://example.com")
.await?
.text()
.await?;
println!("{}", body);
return Ok(());
}
このコードの中で取得したコンテンツを文字列に変換する処理は text()
関数によって行われています。
これはHTTPレスポンスヘッダーのContent-Typeにcharsetの指定がある場合はそのcharsetでデコードし、そうでなければUTF-8でデコードを行います。
世の多くのWEBコンテンツはUTF-8でエンコーディングされていますので多くのケースで問題にはならないのですが、
例えばContent-Typeにcharsetの指定がなく、コンテンツがUTF-8以外の文字エンコードを利用している場合、取得したコンテンツは文字化けするという問題が発生します。
text()
の実装を覗いてみると以下のようになっていることが確認出来ます。
pub async fn text(self) -> crate::Result<String> {
self.text_with_charset("utf-8").await
}
どうやら text_with_charset()
関数に変換する文字コードを渡すことで任意の文字エンコードにすることができるようです。
つまり、UTF-8以外のページを取得する場合は、 text()
関数ではなく、 text_with_charset()
関数を利用して適当な文字コードを指定すれば良さそうです。
let body = reqwest::get("https://example.com")
.await?
.text_with_charset("euc-jp") // EUC-JPの場合
.await?;
println!("{}", body);
ちなみに、 text_with_charset()
の実装内で先に書いた「HTTPレスポンスヘッダーにcharsetの指定がある場合はそのcharsetでデコードし、そうでなければUTF-8でデコードを行う」という実装がされています。
なお、文字のデコードには encoding_rs を利用して行われています。