VB6.0を初めて2ヶ月ほどの初心者です。
今度WEBを扱うプログラムに挑戦したいと思っています。
WEBページを表示させてもさせなくてもよいのですが、VB上でWEBページ上の特定のボタンを押したり、入力欄に入力させたり(例えばボタンひとつでインターネット販売の注文ができるとか)ということはそもそもできるのでしょうか?
できるのならやり方を教えてほしいのです。
もしくは、その辺のことが詳しく(&易しく)載っている本やホームページなどもあれば教えてください(私の知っている本ではわかりませんでした)。
リッキーさんと同じことで悩んでいる者です。
VBで自動的にWEBページのボタンを(間隔を空けたりして)押すことは可能なのでしょうか?
WEB BROWSER CONTROLを使って、ブラウズ化させることが出来るという所までは分かったのですが、どうもコードを組んでWEBページと連動させる方法が分かりません。
もし、ご存知の方がいらっしゃいましたら、ご教授頂けませんでしょうか?どうかよろしくお願いします。
画面表示はしません(出来ません)が
セクションを保持してページを飛んだり
POST値等を送信して結果のhtmlを取得するAPをAPIを使用して最近組みました。
ただソースや参考資料が職場の為,今は...
月曜日に出直してきます
> インターネット販売の注文ができるとか
わざわざ、注文をプログラム的に行う必要があるのでしょうか?
B2Cな電子商取引を行う目的であれば 処理の確認を行うためにも、
ブラウザから手動で操作した方が安全な気がするのですけれども。。。
(プログラムのバグで、大量発注をかけてしまうなんて事があると怖い!)
これがB2Bとして、データを元に自動発注を行う仕組みを作るという目的に
使う事もできるでしょうが、その場合、Webサーバ側に、SOAPによる
Webサービスを構築する形の方が安全です。Webの画面表示と、発注処理を
分割して開発できるので、将来、HTML画面のデザイン構成を変更しても、
発注業務のプログラムの方を変更せずに済みますし。
例えば、googleによる検索処理を自動化したい、などという場合を想定しても、
google APIが用意されているので、そっちを使った方が効率的ですしね。
http://www.atmarkit.co.jp/fjava/column/andoh/andoh09.html
http://www.google.com/apis/reference.html
> できるのならやり方を教えてほしいのです。
ボタン押下やテキスト入力などは、技術的にはさほど難しくないのですが、
悪用すると、例えば、「広告」を複数掲示板に自動投稿するためのアプリが
作れてしまったりするので、あまり良い印象を受けないので、個人的には
具体的なソースは書きたくないと思っています。
といっても、過去ログを検索すると、ソースも出てきてしまいますので、
ヒントだけ書くと———MSHTML.TLBを参照設定すると、道が開けるかも。
WebBrowserコントロール、もしくはInternetExplorerオブジェクトの
Documentプロパティから、HTMLDocumentオブジェクトを得る事が
できます。これは、Dynamic HTMLでいうところの「documentオブジェクト」と
同じ物ですので、そこから、HTMLと同様の操作方法でボタン等を操作できます。
細かい事を知りたい場合、DHTMLに関する資料を探して見ると良いかと。
もしくは、ブラウザといえども、裏で行っているのはWebサーバとの
データの通信に過ぎないわけですから、Inetコントロールや
WinSockコントロール、あるいはXMLHTTPオブジェクトなどといった
通信オブジェクトを使って、HTTP通信を直接行うという手もあります。
HTTPヘッダの内容などまで処理したい場合は、こっちの方法が便利です。
36NETさん、お早いご回答ありがとうございます。
>POST値等を送信して結果のhtmlを取得する
POSTを使ってボタンのようなON/OFFのフォームを動かすことが出来るのですか?本当に無知ですみません。
Dentalさん、詳しいご説明をどうもありがとうございます。
ですが、僕にはDHTMLに関する知識がまるでない為、VBからDHTMLへのアクセス等がまだよく分かっていません…。
なので僕も出直してDHTMLについて勉強することにします。
取り合えずざっくりですが
InternetOpenでInternetオブジェクトハンドルを作成して
InternetConnectでInternetセッションハンドルを作成し
HttpOpenRequestでアドレスを指定
HttpSendRequestでヘッダやPOST情報を送信したら
InternetReadFileでページ内容を受信し
InternetCloseHandleでハンドルの開放です
関数名で検索すれば使い方はだいぶヒットします
レス遅れてすみません。
困ったことに、VBのヘルプで関数等を検索することが出来ないんです…。
なので、インターネットでこれらの名前を探したのですが、これでもよく分かるサイトは見つかりませんでした…。
WebBrowserControlを使った、HTMLDocumentsオブジェクトを取得するにはどうすればよいか分かりませんでしょうか?
> WebBrowserControlを使った、HTMLDocumentsオブジェクトを取得するには
WebBrowserコントロールのdocumentプロパティが、そのものです。
HTMLページを表示後、
MsgBox TypeName(WebBrowser1.Document)
などとしてみてください。HTMLDocumentが返されていることを
確認できるかと思います。
魔界の仮面弁士さん、どうもありがとうございます。
見事にDocumentプロパティを使っていろいろ試すことが出来ました!
ですが、一つ問題が。eventプロパティを使いたいのですが、WebBrowserコントロールでは、Windowオブジェクトを参照できないのでしょうか?
いくつもいくつも質問してすみませんが、どうかよろしくお願いします…。
> Windowオブジェクトを参照できないのでしょうか?
parentWindowプロパティ経由で参照しましょう。
毎度、ありがとうございます。
過去ログを検索したら、チェックボックスの操作法が載っていました。
内容は「input type="check"オブジェクトのcheckedプロパティにTrueを代入する」ということなんですが、
WebBrowser1.Document.all.input type="check".checked=Trueというものしか僕には思いつきませんでした…。これでは、inputとtypeの間の空白と、=の部分でエラーを起こしてしまいます(当然ですが)。どうすれば、チェックボックスやラジオボタンを選択することが出来るのでしょうか?
> 「input type="check"オブジェクトのcheckedプロパティにTrueを代入する」
えーと。それ、「input type="checkbox"」の間違いです。すみません。(^^;
ここでは、単純に
「inputオブジェクトのcheckedプロパティにTrueを代入する」
と読み替えた方が理解しやすいかも知れませんね。
処理としては、例えばこのようなイメージになります。
For Each objInputElement In 〜.document.getElementsByTagName("INPUT")
Select Case LCase(objInputElement.type)
Case "radio"
:
Case "checkbox"
:
End Select
Next
> どうすれば、チェックボックスやラジオボタンを選択することが
対象コントロールにid属性やname属性が付いている場合には、
それを利用するのが手軽かと思います。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200302/03020045.txt
なお、「選択する」というのが、VB6でいうValueプロパティの意味なら、
checkedプロパティを使う事になりますが、VB6でいうSetFocusメソッドの
意味であれば、「focusメソッド」を使う事になります。
すみません…。これほど丁寧なお答えを頂いておきながら、未だにラジオボタンにマークすることが出来ません…。フレームを使っているサイト(ちなみにCGIで作られています)なので、
For Each objInputElement In WebBrowser1.Document.frames(2).getElementsByTagName("INPUT")
Select Case LCase(objInputElement.Type)
Case "radio"
objInputElement(0).Checked = True
End Select
Next
等とやってみたのですが、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」と表示されてしまいます。そもそも、このコードではSelect Caseを使っている意味もありませんし、どうすれば良いのでしょうか?
Select Case LCase(objInputElement.Type)
Case "radio"
objInputElement(0).Checked = True
End Select
の部分を
If objInputElement.Type="radio" Then
objInputElement(0).Checked = True
End If
に変えてみてはどうでしょうか?
> objInputElement(0).Checked = True
「For Each 〜 Next」と「For 〜 Next」の違いに注意してください。
Forループの場合は、
For I = 0 To objInputElements.length - 1
If LCase(objInputElements(I).type) = "radio" Then
objInputElements(I).Checked = True
Exit For
End If
Next
のような書き方になりますが、For Eachの場合は、
For Each objInputElement In objInputElements
If LCase(objInputElement.type) = "radio" Then
'ここで使うのは、objInputElements ではなく、
'objInputElement の方です。(変数名が似ているので注意)
objInputElement.Checked = True
Exit For
End If
Next
などとなります。
なお、ラジオボタンの場合、チェックボックスと違って、グループ内にある
複数の項目をチェックする事はできませんので、その点も考慮してください。
マグさん、魔界の仮面弁士さん、レスありがとうございます。
けれども、今うまく行かないのはそれ以前の、「objInputElement In WebBrowser1.Document.frames(2).getElementsByTagName("INPUT")」という、この部分なんです…。いろいろ試してみると、どうやらframesではgetElementsByTagNameというメソッドが使えないようです。分割されたそれぞれのページを開こうとしても、CGIでアクセスを制限しているらしく、ソースが分からないので、FORMのID属性やNAME属性も調べられません…。どこかで、MSHTMLのHTMLDocumentでページの内容を全て取得出来ると見かけたのですが、一つ一つのページを開けない以上、これも無意味でしょうし…。
同じ内容で何度もすみませんが、どうかよろしくお願いします…。
> 「objInputElement In WebBrowser1.Document.frames(2).getElementsByTagName("INPUT")」
WebBrowser1.Document.frames(2).getElementsByTagName("INPUT")
ではなく、
WebBrowser1.document.frames(2).document.getElementsByTagName("INPUT")
として試して見てください。
> framesではgetElementsByTagNameというメソッドが使えないようです。
Debug.Print TypeName(WebBrowser1.Document.frames(2))を実行して見ると、
おそらく、「HTMLWindow2」という文字列が返されると思います。
HTMLWindow2オブジェクト(IHTMLWindow2インターフェイス)は、
DHTMLでいうところの「windowオブジェクト」に相当します。
http://msdn.microsoft.com/workshop/browser/mshtml/reference/ifaces/interface.asp
そして、上記URLを確認して貰うと、IHTMLWindow2というインターフェイスには
getElementsByTagNamegaメソッドが実装されていない事がわかるかと思います。
> CGIでアクセスを制限しているらしく、ソースが分からないので
この場合、サーバ側のcgiソースを確認する必要は無いと思いますよ。
「HTMLを生成するためのソースコード」が確認できなくても、
実際に生成されたHTMLの内容を見れば、name属性等は確認できますよね。
たしか、CGIにはパーミションというアクセス権限をかけることができたと思います。(ソースに)
自分以外はソースを見ることができないようにするためです。
その理由は他人に個人情報とか取られないようにするためが理由のようです。よって、ソースを表示するのは不可能だと思います。
>魔界の仮面弁士さん
詳しい解説と、情報の豊富なサイトを教えて頂き、ありがとうございます。
>CGIにはパーミションというアクセス権限をかけることができたと思います。
マグさんの言う通り、ページに表示されているHTMLの内容も覗けないようになっています。
結論を申しますと、魔界の仮面弁士さんのご指摘された部分を直すことで、プログラムは正常に動くことが分かりました。
しかし、とても残念なことに、今回アクセスしようとしているサイトはセキュリティーに気を使っているようで、
ラジオボタンを操作しようとすると、「アクセスが拒否されました」と表示されるのです…。
それでも、他の所ならきっと動くはずなので、今までのお答えは無駄にはしません。
本当にお手数をお掛けしました。それと共に、長いこと、本当にありがとうございました!
>魔界の仮面弁士さん
詳しい解説と、情報の豊富なサイトを教えて頂き、ありがとうございます。
>CGIにはパーミションというアクセス権限をかけることができたと思います。
マグさんの言う通り、ページに表示されているHTMLの内容も覗けないようになっています。
結論を申しますと、魔界の仮面弁士さんのご指摘された部分を直すことで、プログラムは正常に動くことが分かりました。
しかし、とても残念なことに、今回アクセスしようとしているサイトはセキュリティーに気を使っているようで、
ラジオボタンを操作しようとすると、「アクセスが拒否されました」と表示されるのです…。
それでも、他の所ならきっと動くはずなので、今までのお答えは無駄にはしません。
本当にお手数をお掛けしました。それと共に、長いこと、本当にありがとうございました!
> しかし、とても残念なことに、今回アクセスしようとしているサイトはセキュリティーに気を使っているようで、
> ラジオボタンを操作しようとすると、「アクセスが拒否されました」と表示されるのです…。
サーバー側のパーミッションと、DHTMLのアクセス制限は、全く別物だと思いますけれども。(^^;)
サイトがFRAMESETで構成されている場合、各ドキュメントが同一サイト内にあれば良いのですが、ドメインが異なる場合(www.aaa.comとwww.bbb.comのように)には、アクセスが制限されます。これはIEの仕様です。
http://support.microsoft.com/default.aspx?scid=kb;ja;167796
CGIは一般にCスクリプトやperlやaspと呼ばれています。
そして、これらのスクリプトは外部サーバで働きます。
リンク構成は
CGIを呼び出すとき
HTML→アップしたサーバ(パーミションというセキュリティ<たとえば ジオシティズ等>)→CGI
という構成になっています。
つまり
CGIを表示するならアップしたサーバを通る必要があります。
よって、万が一できたとしても、プログラムにハッ○ン○させているような感じになってしまうわけだと思います。(私的には)
解決表示したのに、レスして頂いてありがとうございます。
>サイトがFRAMESETで構成されている場合、各ドキュメントが同一サイト内にあれば良い
三つのフレームはどれも同サーバー上にあるので、この可能性も低いかと思います。
別のサイトで今までのことを試していたところ、分からない事がまた出てしまいました…。
開いたフレームのボタンをクリックした時に、ページの内容が変わるのですが、
その変更が完全に終了するまで処理の実行を遅らせたいのです。
「解決」としてある所で新たな質問をするのもどうかと思いますが、もしまだご覧でしたらどうかよろしくお願いします。
プログラムで実際に遅らせるよう記述をさせるというのはどうでしょうか?
例えばfor文を使い2万回ぐらい回すとか。
DocumentCompleteイベントが発生してから処理を行うようにしてみるとか。
編集 削除スレッド関数だったかな?
を使って、スレッドのところで重い処理をさせる
というのはどうでしょうか?
>例えばfor文を使い2万回ぐらい回すとか。
一連の処理を何百回も繰り返すつもりなので、なるべくなら、forで無駄に動かし続けたくはないんです。。
>DocumentCompleteイベントが発生してから処理を行うようにしてみるとか。
ありがとうございます。これが今回のケースには一番合っていると思い、アイディアを頂戴してコードを組んだのですが、(↓)
Private Sub Command2_Click()
cnum = 1
・・・・・・(ページ情報を変更)
End Sub
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
Select Case cnum
Case 1
checker
Case 2
・・・・
End Select
cnum = cnum + 1
・・・・・・・・・・
End Sub
・・・・・・・・・・
Private Sub checker()
For Each objInputElement In WebBrowser1.Document.frames(1).Document.getElementsByTagName("INPUT")
Select Case LCase(objInputElement.Type)
Case "radio"
objInputElement(0).Checked = True
End Select
Next
End Sub
としても、checkerサブルーチン等に飛んだ形跡がありません。
どこがいけないのか、分かりますでしょうか?
Case 1を通らなかったという可能性もあるのではないでしょうか?
もしかして、cnum = 1で値を代入していますけど、定義をしていないため
サブルーチンで移動したときにcnum = 0のように書き換えられているのでは?
マグさん、ありがとうございます。
恥ずかしいことに、cnumの定義をしておりませんでした…。
宣言したら見事解決しました!
どうもありがとうございました。