IdHTTP.Get で得たWEBページソースの文字化け

解決


lactone  2018-10-24 11:17:06  No: 49576  IP: 192.*.*.*

下記(1)で得たtextは常に正常ですが、
(2)では(おそらく日本語文字部分が)文字化けを起こします。
稀に正常に表示されることもありますが原因不明です。
対処法は?


var 
   HTTP : TIdHTTP; 
   MS : TMemoryStream; 
   S : TStringList; 
 begin 
   HTTP :=IdHTTP1; 
   HTTP.Response.CharSet:='Shift_JIS';
   HTTP.IOHandler:=IdSSLIOHandlerSocketOpenSSL1;
   IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:=sslvSSLv23;

   S := TStringList.Create;  S.Clear; 
   MS := TMemoryStream.Create; 
   HTTP.Get('https://news.yahoo.co.jp/',MS); 
 //  MS.SaveToFile('filename.txt');       //----------(1) 
   MS.Position := 0; 
   S.LoadFromStream(MS); 
   Showmessage(S.text);         //-----------(2) 
   Freeandnil(MS); S.Free; 
 end; 

環境:Windows10 Home + Delphi10.2.3 Comm.Ed. + Indy10.6.2

編集 削除
通りすがり  2018-10-24 13:08:12  No: 49577  IP: 192.*.*.*

文字コードとかどうなってますか?というあたりから確認するべきかと。

編集 削除
lactone  2018-10-24 15:44:04  No: 49578  IP: 192.*.*.*

通りすがりさんありがとうございます。

HTTP.Response.CharSet:='Shift_JIS'; →
HTTP.Response.CharSet:='EUC-JP';
でも変わらず、
過去ログの「文字化け」0での検索によりますと、
原因はYahooページの仕様にあるらしく、
私の手に負えない領域にあると判断しました。

時折成功するという点が心残りですが、撤収します。

編集 削除
通りすがり  2018-10-24 16:31:32  No: 49579  IP: 192.*.*.*

ただwebブラウザでは正常に表示できるわけで、Streamの内容を一旦UTF-8(あるいはASCII)として解釈して、metaタグ内の
charsetを見て、これに従って改めてStreamの内容を所定の文字コードと見なしてString(=UnicodeString=UTF-16LE)に
変換してやればよいのでは?

# ページのソースを見たところUTF-8みたいですけどね

編集 削除
文字コード  2018-10-24 16:32:47  No: 49580  IP: 192.*.*.*

質問者さんが提示しているURLを見ると、utf-8のcharsetが設定されていました。
utf-8にしたらどうでしょうか?

https://news.yahoo.co.jp/

編集 削除
lactone  2018-10-24 20:02:06  No: 49581  IP: 192.*.*.*

通りすがりさん、文字コードさんありがとうございます。

HTTP.Response.CharSet:='Shift_JIS'; → 
HTTP.Response.CharSet:='UTF-8'; 
でも変わりません。 

>Streamの内容を所定の文字コードと見なして
>String(=UnicodeString=UTF-16LE)に 
>変換してやればよいのでは? 
とは、
StringListにEncodeを設定するということですか?
UTF-8の文字コードをUTF-16LEに変換する関数は身近にありますか?

編集 削除
AAA  2018-10-25 11:05:31  No: 49582  IP: 192.*.*.*

HTTP : TIdHTTP;
    MS : TMemoryStream;
    S : TStringList;
  begin
    HTTP :=IdHTTP1;
    //HTTP.Response.CharSet:='UTF-8';   //読み込んだ CharSet が返ってくる
    HTTP.IOHandler:=IdSSLIOHandlerSocketOpenSSL1;
    IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:=sslvSSLv23;

    S := TStringList.Create;  S.Clear;
    MS := TMemoryStream.Create;
    HTTP.Get('https://news.yahoo.co.jp/',MS);
    MS.Position := 0;
    //HTTP.Response.CharSet エンコードを判断する(今回はUTF8)
    S.LoadFromStream(MS,TEncoding.UTF8); ///////////////////
    Showmessage(S.text);         //-----------(2)
    Freeandnil(MS); S.Free;
  end;

編集 削除
lactone  2018-10-25 13:28:11  No: 49583  IP: 192.*.*.*

//HTTP.Response.CharSet エンコードを判断する(今回はUTF8) 
S.LoadFromStream(MS,TEncoding.UTF8); ///////////////////

に感動しました!!!
AAAさん、ありがとうございました。 
----------------------------
<Yahooサイト:'https://news.yahoo.co.jp/'のWEBソースを取得>
var 
    HTTP : TIdHTTP; 
    MS : TMemoryStream; 
    S : TStringList; 
begin 
    HTTP :=IdHTTP1; 
    HTTP.IOHandler:=IdSSLIOHandlerSocketOpenSSL1; 
    IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method:=sslvSSLv23; 
    S := TStringList.Create;  S.Clear; 
    MS := TMemoryStream.Create;  MS.clear;
    HTTP.Get('https://news.yahoo.co.jp/',MS); 
    MS.Position := 0; 
    S.LoadFromStream(MS,TEncoding.UTF8); 
    Showmessage(S.text); 
    Freeandnil(MS); S.Free; 
end;
 
<環境:Windows10 Home + Delphi10.2.3 Comm.Ed. + Indy10.6.2>

編集 削除