最近VB6を始めた者です。
個人用の小物アプリを作っていましたが、
最近、Web上のデータを取得するアプリが作りたくなりました。
今作っているのは Yahoo!オークションのウォッチリスト、出品リストなどを
VBに取り込み閲覧するソフトです。
これまでは Inet にてページドキュメントを取得し、
htmlを解析してテキストを抜き出し配列に格納していました。
これですとページレイアウトが少しでも変わると思った通りのデータを取得できなくなってしまいます。
そこで直接データのみを取得したいと考えているのですが、全く方法が分かりません。
皆様の助言を頂けると幸いです。よろしくお願い致します。
私はWebBrowserを使っています。
これで検索してみて下さい。
だるさん
私も同じことに挑戦してます。
今のところ、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
のようにすべて取り出せます。
参考になりましたでしょうか?
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オークションもこれで取れます。
あとはタグを見てどうとでも.....
ねろさん
ありがとうございます。
ヘッダ情報が要らないのであれば、
WebBrowser.Document.body.outerhtml
のみで取り出せます。
タグ解析は以前しないといけないのですが。。。
ねろさん、tomoさん、お返事ありがとうございます。
なるほど WebBrowser コントロールですか。
私は単にブラウザを作るためにあるコントロールと解釈してまして、
全く気にしていませんでした。
MSDNをはじめ、いろいろ検索して情報を集めまして早速試してみます。
tomoさんのお話にあった EUC→S-JIS の変換なのですが、
NKF32.DLL を使用して変換しておりました。
仕様なので仕方がないと言えばそれまでですが、
VBが直接EUCを読めないことを知った時は結構マイクロソフトを恨みましたw
> VBが直接EUCを読めないことを知った時は結構マイクロソフトを恨みましたw
Streamオブジェクトであれば、任意の文字コードの文字列を扱えます。
もちろん、EUC-JPコードも認識できますよ。
(このオブジェクトは、文字コード変換のために利用する事もできます)
また、HttpRequestオブジェクトのresponseTextメソッドも、
(Webサーバが文字コード情報を返してくるならば)、受信結果をそのまま、
正しい文字列として扱うことができます。WebBrowserも同様ですね。
WebBrowserを使う上で一つ心配な点があります。
WebBrowserはページを表示しますので、画像を読み込む際に
時間がかかるのでは無いかという点です。
今のところ、大きな画像を読んでないので、本当に遅いかどうか
よく分かりませんが、実際のところは、どうなのでしょうか?
もし、EUCの問題が解決(NKFを使わずに)できるのであれば、
私は、INETの方が良いのでは無いかと思っております。
魔界の仮面弁士さん
Streamオブジェクト、及びHttpRequestオブジェクトですが、
私には良く使い方がわかりませんでした。
具体的に、教えていただけましたら、ありがたいです。
> 私は、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
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
> WebBrowserはページを表示しますので、画像を読み込む際に
> 時間がかかるのでは無いかという点です。
画像の読込が完了していなくても、HTMLの読込さえ完了していれば、
HTMLの解析は可能です。ただ、全て読み込むまで処理をしないのであれば、
Internet Explorerで表示するのと、同じだけの時間がかかるでしょう。
> 今のところ、大きな画像を読んでないので、本当に遅いかどうか
> よく分かりませんが、実際のところは、どうなのでしょうか?
まずは実際にやってみて、試しましょう。(^^;)
横から失礼します。
VB6には、いちおうインターネットに接続し、データを取得する機能が備わっています。
http://hp.vector.co.jp/authors/VA015521/
このサイトのTipsに、その機能を使うためのユーザーコントロールがあります(結局中身でやってるのは、Wininetとかと変わりないですけど、こちらの負担は軽くすみます)。
これでダウンロードしたあと、テキストファイルならば、何らかの方法(SJISならばStrConvだけでもいいようです)で文字コード変換してください。
C言語で作られたDLLなど、使ってみてはどうでしょうか?
魔界の仮面弁士さん、アドバイスありがとうございます。
WebBrowserコントロールやServerXMLHTTPオブジェクトにて
HTMLソースを取得する方法を知ることができ勉強になりました。
できればもう1つ教えて頂きたいのですが、
冒頭で質問させてもらったように Webページをhtmlではなく、
データとして取得することは無理なものでしょうか?
すいません。
ゆっくり入力していたため、たかみちえさんのお返事見逃してしまいました。
> 冒頭で質問させてもらったように Webページをhtmlではなく、
> データとして取得することは無理なものでしょうか?
HTMLも、一応(テキスト形式の)データの一種ですよ。
まぁ、XHTMLと比べると、非常に扱いにくいですけれどね。(^_^;)
で、HTMLページの解析には、ねろさんやtomoともさんの回答にもあるように、
WebBrowser(というかMSHTML)を利用するのが最も手軽でしょう。
リンクの列挙、画像の列挙、テーブルの取得等々、HTMLの内容を
オブジェクトとして扱えるようになりますので。
ただしyahoo!のサイトは、多くの(HTMLの文法的な)間違いを含んでいますので、
ページによっては、望むべき解析結果にならない可能性もあります。
《最初の質問》
> これですとページレイアウトが少しでも変わると思った通りのデータを取得できなくなってしまいます。
> そこで直接データのみを取得したいと考えているのですが、全く方法が分かりません。
「レイアウトが変わってもデータ取得したい」というのは、
よほど丁寧に書かれたWebページでなければ、難しいかも知れません。
レイアウトが大幅に変わってしまった場合は、やはりどうしても、
ページを解析するプログラムを作り変える必要があるでしょうね。
取得先ページが、レイアウトとデータを明確に分離してあるサイト
(たとえば、元データがXML(またはXHTML)になっていて、
レイアウトを全てCSS(ないしはXSLT)で行ってあるページなど)であれば、
どんなにレイアウト(CSS等)が変わっても、元データの構造は同じなので、
同じプログラムでデータを取得できますが、そのような構成になっているサイトは稀です。
皆様、多くのアドバイスありがとうございます。
webbrowser、MSHTML など、勉強して作り直してみようと思います。
(テーブルの取得も可能なんですね。知らないことばかりで恥ずかしい限りです)
特に多くの質問に的確に答えている魔界の仮面弁士さんの知識量には脱帽してしまいました。
まだまだ満足な質問すらできない私ですが、今後ともよろしくお願いします。
Debug.Print WebBrowser1.Document.links(i).outerHTML
ってVB6.0じゃ使えませんか?
実行時にエラーが出ます
解決してるスレあげんなよ。
ツイート | ![]() |