VBでWeb上のデータを取得するにはどうすればいいですか?

解決


だる  2003-08-31 23:09:40  No: 108359

最近VB6を始めた者です。
個人用の小物アプリを作っていましたが、
最近、Web上のデータを取得するアプリが作りたくなりました。
今作っているのは Yahoo!オークションのウォッチリスト、出品リストなどを
VBに取り込み閲覧するソフトです。
これまでは Inet にてページドキュメントを取得し、
htmlを解析してテキストを抜き出し配列に格納していました。
これですとページレイアウトが少しでも変わると思った通りのデータを取得できなくなってしまいます。
そこで直接データのみを取得したいと考えているのですが、全く方法が分かりません。
皆様の助言を頂けると幸いです。よろしくお願い致します。


ねろ  2003-09-01 00:34:58  No: 108360

私はWebBrowserを使っています。
これで検索してみて下さい。


tomo  2003-09-01 00:42:34  No: 108361

だるさん

私も同じことに挑戦してます。
今のところ、Inetですと、YahooはEUCコードですので、VBで解析する
為には、EUC→S-JISに変える手間がかかりますので、使ってません。
この所はだるさんはどのようにしているでしょうか?

今は、WebBrowserを使ってますが、同じようにHTMLを解析してます。
マイクロソフトインターネットコントロールを使うとWebBrowserが使えます。

ただし、WebBrowserはすべてオプジェクトとして扱ってますので、
解析しなくても可能だとは思ってます。
例えばリンクなどは、
    For i = 0 To WebBrowser1.Document.links.Length - 1
        Debug.Print WebBrowser1.Document.links(i).outerText
        Debug.Print WebBrowser1.Document.links(i).href
        Debug.Print WebBrowser1.Document.links(i).outerHTML
    Next i
のようにすべて取り出せます。
参考になりましたでしょうか?


ねろ  2003-09-01 01:12:11  No: 108362

tomoさんの方法はlinkをとる方法ですね    
HTMLテキストを取るには
For n = 0 To WebBrowser.Document.All.length - 1
  If UCase(Trim(WebBrowser.Document.All(n).tagname)) = "HTML" Then
      s = WebBrowser.Document.All(n).outerhtml 'HTMLのテキスト
  End If
Next
こんな感じですか
yahooオークションもこれで取れます。
あとはタグを見てどうとでも.....


tomo  2003-09-01 01:24:47  No: 108363

ねろさん

ありがとうございます。

ヘッダ情報が要らないのであれば、
WebBrowser.Document.body.outerhtml
のみで取り出せます。

タグ解析は以前しないといけないのですが。。。


だる  2003-09-01 04:34:51  No: 108364

ねろさん、tomoさん、お返事ありがとうございます。
なるほど WebBrowser コントロールですか。
私は単にブラウザを作るためにあるコントロールと解釈してまして、
全く気にしていませんでした。
MSDNをはじめ、いろいろ検索して情報を集めまして早速試してみます。

tomoさんのお話にあった EUC→S-JIS の変換なのですが、
NKF32.DLL を使用して変換しておりました。
仕様なので仕方がないと言えばそれまでですが、
VBが直接EUCを読めないことを知った時は結構マイクロソフトを恨みましたw


魔界の仮面弁士  2003-09-01 06:01:26  No: 108365

> VBが直接EUCを読めないことを知った時は結構マイクロソフトを恨みましたw

Streamオブジェクトであれば、任意の文字コードの文字列を扱えます。
もちろん、EUC-JPコードも認識できますよ。
(このオブジェクトは、文字コード変換のために利用する事もできます)

また、HttpRequestオブジェクトのresponseTextメソッドも、
(Webサーバが文字コード情報を返してくるならば)、受信結果をそのまま、
正しい文字列として扱うことができます。WebBrowserも同様ですね。


tomo  2003-09-01 07:39:41  No: 108366

WebBrowserを使う上で一つ心配な点があります。
WebBrowserはページを表示しますので、画像を読み込む際に
時間がかかるのでは無いかという点です。
今のところ、大きな画像を読んでないので、本当に遅いかどうか
よく分かりませんが、実際のところは、どうなのでしょうか?

もし、EUCの問題が解決(NKFを使わずに)できるのであれば、
私は、INETの方が良いのでは無いかと思っております。

魔界の仮面弁士さん
Streamオブジェクト、及びHttpRequestオブジェクトですが、
私には良く使い方がわかりませんでした。
具体的に、教えていただけましたら、ありがたいです。


魔界の仮面弁士  2003-09-01 08:46:47  No: 108367

> 私は、INETの方が良いのでは無いかと思っております。
個人的には、Inetは制限が多いのでお奨めしません。
HTMLソースの取得が目的ならばServerXMLHTTPオブジェクト、
HTMLの解析が目的ならばWebBrowserコントロールの方が融通が利くかと。

> Streamオブジェクト、及びHttpRequestオブジェクトですが、
> 私には良く使い方がわかりませんでした。
Streamオブジェクトは、たとえばこのように使います。
    With CreateObject("ADODB.Stream")
        .Open
        .Charset = "euc-jp"
        .WriteText "あいうえお"
        .SaveToFile "C:\EUC.TXT"
        .Close
    End With
これで、EUC-JPで「あいうえお」と書かれたファイルが作成されます。
また、LoadFromFileメソッドを使って、EUC-JPファイルを読むことも出来ます。

ファイルを介さずに変換する事もできます。

Option Explicit

Private Sub Form_Load()
    Text1.Text = "魔界の仮面弁士"
End Sub

Private Sub Command1_Click()
    Dim SJIS() As Byte
    Dim JIS() As Byte

    '元データ
    SJIS = StrConv(Text1.Text, vbFromUnicode)

    '変換
    JIS = ConvertCharset(SJIS, "Shift_JIS", "EUC-JP")
    Stop
End Sub

'====================================================================
'     SrcData: 変換元のデータ
'  SrcCharset: 変換元の文字コード
' DestCharset: 変換後の文字コード
'      戻り値: 変換後のデータ
'====================================================================
Public Function ConvertCharset( _
        ByRef SrcData() As Byte, _
        ByVal SrcCharset As String, _
        ByVal DestCharset As String) As Byte()
    Dim Src As ADODB.Stream
    Dim Dst As ADODB.Stream

    '改行コードの変換やBOMの除去は行っていません。必要に応じて追加してください。
    '(LineSeparatorプロパティは、既定の adCRLF のままです)

    Set Src = New ADODB.Stream
    Src.Open
    Src.Type = adTypeBinary
    Src.Write SrcData
    Src.Position = 0
    Src.Type = adTypeText
    Src.Charset = SrcCharset

    Set Dst = New ADODB.Stream
    Dst.Open
    Dst.Type = adTypeText
    Dst.Charset = DestCharset
    Src.CopyTo Dst
    Dst.Position = 0
    Dst.Type = adTypeBinary
    
    Src.Close
    ConvertCharset = Dst.Read(adReadAll)
    Dst.Close
    
    Set Src = Nothing
    Set Dst = Nothing
End Function


魔界の仮面弁士  2003-09-01 09:01:33  No: 108368

HttpRequestに関しては、こんな感じになります。
必要に応じて、任意のデータをHTTP要求ヘッダ/要求ボディに含めて
送出することもできます。SSL(https://〜〜形式のサイト)にも対応しています

Dim HttpRequest As Object

'1.0〜4.0までの、各XMLHTTP/ServerXMLHTTPの生成方法。
'通常は、これらのうちのどれか1つを使えばOKでしょう。
Set HttpRequest = CreateObject("Microsoft.XMLHTTP")
Set HttpRequest = CreateObject("MSXML2.XMLHTTP")
Set HttpRequest = CreateObject("MSXML2.ServerXMLHTTP")
Set HttpRequest = CreateObject("MSXML2.XMLHTTP.2.6")
Set HttpRequest = CreateObject("MSXML2.ServerXMLHTTP.3.0")
Set HttpRequest = CreateObject("MSXML2.XMLHTTP.3.0")
Set HttpRequest = CreateObject("MSXML2.ServerXMLHTTP.4.0")
Set HttpRequest = CreateObject("MSXML2.XMLHTTP.4.0")

'「GETモード、yahooサイト、非同期モード」で取得
HttpRequest.open "GET", "http://www.yahoo.co.jp/", False

'データ取得開始(送信データを何も送らない場合)
HttpRequest.send

'データをUnicodeテキストとして取得
'文字コード情報を送り返さないWebサーバの場合は、文字化けする事があります
Dim S As String
S = HttpRequest.responseText

'データをバイト配列として取得
'生データです。文字列に変換したい場合は、自前で文字コード変換してください。
Dim B() As Byte
B = HttpRequest.responseBody

'データをストリームとして取得
Dim U As IUnknown
Set U = HttpRequest.responseStream


魔界の仮面弁士  2003-09-01 09:04:53  No: 108369

> WebBrowserはページを表示しますので、画像を読み込む際に
> 時間がかかるのでは無いかという点です。
画像の読込が完了していなくても、HTMLの読込さえ完了していれば、
HTMLの解析は可能です。ただ、全て読み込むまで処理をしないのであれば、
Internet Explorerで表示するのと、同じだけの時間がかかるでしょう。

> 今のところ、大きな画像を読んでないので、本当に遅いかどうか
> よく分かりませんが、実際のところは、どうなのでしょうか?
まずは実際にやってみて、試しましょう。(^^;)


たかみちえ  URL  2003-09-01 09:45:22  No: 108370

横から失礼します。

  VB6には、いちおうインターネットに接続し、データを取得する機能が備わっています。

http://hp.vector.co.jp/authors/VA015521/
  このサイトのTipsに、その機能を使うためのユーザーコントロールがあります(結局中身でやってるのは、Wininetとかと変わりないですけど、こちらの負担は軽くすみます)。
  これでダウンロードしたあと、テキストファイルならば、何らかの方法(SJISならばStrConvだけでもいいようです)で文字コード変換してください。
  C言語で作られたDLLなど、使ってみてはどうでしょうか?


だる  2003-09-01 10:13:27  No: 108371

魔界の仮面弁士さん、アドバイスありがとうございます。
WebBrowserコントロールやServerXMLHTTPオブジェクトにて
HTMLソースを取得する方法を知ることができ勉強になりました。

できればもう1つ教えて頂きたいのですが、
冒頭で質問させてもらったように Webページをhtmlではなく、
データとして取得することは無理なものでしょうか?


だる  2003-09-01 10:17:14  No: 108372

すいません。
ゆっくり入力していたため、たかみちえさんのお返事見逃してしまいました。


魔界の仮面弁士  2003-09-01 12:54:51  No: 108373

> 冒頭で質問させてもらったように Webページをhtmlではなく、
> データとして取得することは無理なものでしょうか?
HTMLも、一応(テキスト形式の)データの一種ですよ。
まぁ、XHTMLと比べると、非常に扱いにくいですけれどね。(^_^;)

で、HTMLページの解析には、ねろさんやtomoともさんの回答にもあるように、
WebBrowser(というかMSHTML)を利用するのが最も手軽でしょう。
リンクの列挙、画像の列挙、テーブルの取得等々、HTMLの内容を
オブジェクトとして扱えるようになりますので。

ただしyahoo!のサイトは、多くの(HTMLの文法的な)間違いを含んでいますので、
ページによっては、望むべき解析結果にならない可能性もあります。

《最初の質問》
> これですとページレイアウトが少しでも変わると思った通りのデータを取得できなくなってしまいます。
> そこで直接データのみを取得したいと考えているのですが、全く方法が分かりません。

「レイアウトが変わってもデータ取得したい」というのは、
よほど丁寧に書かれたWebページでなければ、難しいかも知れません。
レイアウトが大幅に変わってしまった場合は、やはりどうしても、
ページを解析するプログラムを作り変える必要があるでしょうね。

取得先ページが、レイアウトとデータを明確に分離してあるサイト
(たとえば、元データがXML(またはXHTML)になっていて、
レイアウトを全てCSS(ないしはXSLT)で行ってあるページなど)であれば、
どんなにレイアウト(CSS等)が変わっても、元データの構造は同じなので、
同じプログラムでデータを取得できますが、そのような構成になっているサイトは稀です。


だる  2003-09-02 04:38:22  No: 108374

皆様、多くのアドバイスありがとうございます。
webbrowser、MSHTML など、勉強して作り直してみようと思います。
(テーブルの取得も可能なんですね。知らないことばかりで恥ずかしい限りです)
特に多くの質問に的確に答えている魔界の仮面弁士さんの知識量には脱帽してしまいました。
まだまだ満足な質問すらできない私ですが、今後ともよろしくお願いします。


やま  2005-11-23 23:09:23  No: 108375

Debug.Print WebBrowser1.Document.links(i).outerHTML
ってVB6.0じゃ使えませんか?
実行時にエラーが出ます


名無し  2005-11-24 01:10:15  No: 108376

解決してるスレあげんなよ。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加