読み込んだテキストファイルが文字化けする

解決


しげちお  2005-06-12 03:00:10  No: 122498  IP: [192.*.*.*]

こんばんは。

http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200506/05060052.txt

先日お教え頂きました↑の方法でWebサイトのHTMLを
テキストファイルに保存して、それを読み込んで変数に入れて
特定の文字列をInstrで検索したり、Midで抜き出したりしたいのですが、
ヤフーのサイトのHTMLの場合、全角の文字の部分が
見たこともない画数の多い漢字になってしまいます。
(他のサイトだと大丈夫でした。)

LEISAさんに教えて頂いた方法と、魔界の仮面弁士さんに教えて頂いた
両方の方法を試して、読み込み方法はLineInputや
Dim sr As New System.IO.StreamReader(filepath + "0.txt", System.Text.Encoding.Default)
の方法を試して見ましたが、結果は同じでした。

TeraPadというソースを閲覧するソフトでhtmlを一旦表示して、
それをコピー&ペーストで0.txtに保存して読み込むと正常に読み込んで表示もできました。

正常に読み込む方法がありましたらお教え頂けると助かります。
よろしくお願いします。(VB.NETになります。)

編集 削除
通ってみた  2005-06-12 06:09:58  No: 122499  IP: [192.*.*.*]

ソースのエンコードがEUCだからでしょう
.Netならばエンコードの命令があるので調べてみましょう

VB6.0の場合は自前でエンコードするかDLLを使いましょう

編集 削除
魔界の仮面弁士  2005-06-12 14:23:10  No: 122500  IP: [192.*.*.*]

IPersistFile.Save で *.html / *.txt に保存した場合は、
元のデータ形式をそのまま維持しますので、表示しているページの
文字コードが、そのままファイルの文字コードになります。

Yahoo! の場合は、通ってみたさんが書かれたように、EUC-JPの
文字コードで保存されます。たとえば、下記の Sample.txt は、
EUCになりますので、IE/TeraPad/秀丸等では表示できますが、
メモ帳などでは文字が化けて表示されてしまうでしょう。

Sub Main()
  Const FileName As String = "C:\Sample.txt"

  '現在起動中の InternetExplorer を列挙する
  Dim Shell As Object = CreateObject("Shell.Application")
  Dim Windows As Object = CallByName(Shell, "Windows", CallType.Method)
  For I As Integer = 0 To CInt(CallByName(Windows, "Count", CallType.Get)) - 1
    Dim Exp As Object = CallByName(Windows, "Item", CallType.Get, I)
    If Not IsNothing(Exp) Then
      'Yahoo!だったら
      If "http://www.yahoo.co.jp/".Equals(CallByName(Exp, "LocationURL", CallType.Get)) Then
        Dim Doc As Object = CallByName(Exp, "Document", CallType.Get)
        DirectCast(Doc, UCOMIPersistFile).Save(FileName, False)
        Marshal.ReleaseComObject(Doc)
      End If
      Marshal.ReleaseComObject(Exp)
    End If
  Next
  Marshal.ReleaseComObject(Windows)
  Marshal.ReleaseComObject(Shell)
End Sub

> テキストファイルに保存して、それを読み込んで変数に入れて
テキストファイルに保存してから読み取るのではなく、
直接 Document の内容を読み取るように作り変えて見るとか。


> Dim sr As New System.IO.StreamReader(filepath + "0.txt", System.Text.Encoding.Default)
Encoding.Default だと、Shift_JIS 扱いになってしまいますよ。
別の文字コードで開けば、文字化けが起きて当然かと。

元ファイルの文字コードにあわせたエンコードで読み込むか、
もしくは、保存時に文字コードを統一しておくかしましょう。


> 正常に読み込む方法がありましたらお教え頂けると助かります。
IPersistFile.Save で保存するのではなく、outerHTML / innerHTML経由で
保存した場合は、いったん、String型に変換されてから保存しますので、
文字コードの違いを、ある程度吸収する事ができます。

ただし、この場合、MSHTMLで「解析」された結果を元に、再度HTMLに復元して
出力する事になりますので、元のHTML(IEの[ソースの表示]で得られるHTML)とは、
異なる結果にはなってしまいますけれどね。

編集 削除
しげちお  2005-06-13 02:54:08  No: 122501  IP: [192.*.*.*]

通ってみたさん魔界の仮面弁士さん、回答ありがとうございます!

エンコードの方法を変えて試してみたいと思います。
また、ご指摘の通り、ファイルに保存する前にInstrなど
必要な処理をする方法も考えてみたいと思います。

しかしVBは難しいですね。
手元に参考書がありますが、厚さ4cmほどの本ですが、
今回のに関連する事柄はほとんど出ていないようでした。
全部説明にすると厚さ50cmくらいになるんでしょうかね?!(><)
なんか完成まで道のりがとても長く感じてしまいましたが、
地道にやってみようと思います。
度々お返事ありがとうございます。

編集 削除
通ってみた  2005-06-13 09:37:28  No: 122502  IP: [192.*.*.*]

ちなみに自分はこんなのを使ったりする(VB6.0)

    Dim m As String
    Dim oHttp  As Object
    Set oHttp = CreateObject("MSXML2.XMLHTTP")
    oHttp.open "GET", "http://〜", False
    oHttp.Send
    m = oHttp.responseText
    Set oHttp = Nothing

これで文字列変数mにソースが入る
文字化けも解消される・・・はず
詳しくは「MSXML」とかで検索してみるといいかも

編集 削除
魔界の仮面弁士  2005-06-13 10:24:24  No: 122503  IP: [192.*.*.*]

> 文字化けも解消される・・・はず
残念ながら XMLHTTP でも、文字コードの自動認識で失敗する事が
(経験上)ありますので、結局、responseText だけでは取得しきれず、
responseBody からの文字コード変換が必要とされる場面が
少なからずあるかと思います。>通ってみたさん
(DLLのバージョンや、サーバ側の Content-Type 設定などの影響もあるようですが)


で、どうせ文字コードの認識の問題が付いて回るなら、COM の XMLHTTP を
使うよりは、.NET の System.Net.HttpWebRequest を使った方が
スマートかも知れません。(今回の文字化けの件の解決にはなりませんが…)
http://dobon.net/vb/dotnet/internet/webrequest.html

# ただ、その前のしげちおさんの質問では、IEのプロセスIDや
# タイトルまで取得していたようなので、もしかしたら、単純に
# HTMLを取得できればよいと言う物ではなく、IEの介在を
# 前提とした仕様なのかも知れませんが……。

編集 削除
通ってみた  2005-06-13 13:09:02  No: 122504  IP: [192.*.*.*]

>>魔界の仮面弁士さん
なるほど、そうなんですか
自分は今のところ大丈夫だったので気にせず使っております
まずいかな・・・

あと、他に簡単な方法としてWebBrowserを設置してページを読み込ませ、テキストを抽出するというのもありますな

編集 削除
しげちお  2005-06-14 23:06:35  No: 122505  IP: [192.*.*.*]

通ってみたさん、魔界の仮面弁士さん、お返事ありがとうございます。

通ってみたさんのコードをやってみましたら.NETでも
文字化けもなく動作いたしました。
魔界の仮面弁士さんに頂いたリンク先のコードでも同じようにできました。

複数の方法で同じ結果を得ることができるんですね。
おかげさまでまた作業が進められます。
ありがとうございます!

編集 削除