よろしくお願いします。
最近mshtml.tlbライブラリを使えばIE上のメソッドをコントロールできることを、知り
はまっております。
特に参考にさせて頂いたサイトは
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200604/06040013.txt
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200606/06060037.txt
ここで、両方サイトとも主にBlueさんが解説されています。
上記の例は両方とも検索ボックスに単語を入力して検索ボタンを押下する動作になります。
GoogleとYahooのサイトの主だった違いはButtonの数が違います。
上記サイトよりButton押下の部分を抜粋して見比べてみますと、
Googleの場合
// ※ラジオボタンの操作
// 日本語のページから検索を選択(2番目のボタン)
pCollection = pDocument->getElementsByName( _bstr_t( L"lr" ) );
MSHTML::DispIHTMLInputButtonElementPtr pButton( pCollection->item( 1 ) );
pButton->click();
// ウェブ検索ボタンを押す(Submit)
pCollection = pDocument->getElementsByName( _bstr_t( L"f" ) );
MSHTML::IHTMLFormElementPtr pForm( pCollection->item() );
pForm->submit();
Yahooの場合
// ウェブ検索ボタンを押す(Submit)
pCollection = pDocument->getElementsByName( _bstr_t( L"w" ) );
MSHTML::IHTMLFormElementPtr pForm( pCollection->item() );
pForm->submit();
このようになりますそこで、質問がございます。
質問1
Googleの例でラジオボタンの操作をサイト画面左の”ウェブ全体から検索”に
する場合のパラメータはどのように与えたらよいのでしょうか?
(_bstr_tの引数の与え方がよく分かりません)
質問2
Googleの例で左の”Google検索”ボタンを押下しますが、右の”I'm Feeling Lucky”の
ボタンを押下させるにはどのように書いたらよいのでしょうか?
質問3
GoogleもYahooも検索単語の入力ボックスは一つですが、複数の入力ボックスが
ある場合はどのように書けばよいのでしょうか?
for ( long j = 0L; j < pCollection->length; j++ )
{
printf("%s\n", pCollection->item( _variant_t( j ) ));
}
pCollectionのitemメンバを書出して確認しましたが上手く取得できませんでした。
以上よろしくお願いいたします。
環境
Windows XP SP2
VS2005 VC8
基本はHTMLを見るしかないです。
>質問1
>pCollection = pDocument->getElementsByName( _bstr_t( L"lr" ) );
で、nameがlrのコレクションを取得しています。
>MSHTML::DispIHTMLInputButtonElementPtr pButton( pCollection->item( 1 ) );
で、nameがlrである2番目のボタンを選択しています。
ここで、HTMLを見てもらうと、
nameがlrである要素は
・ウェブ全体から検索
・日本語のページを検索
の二つあります。それで、元のコードでは「日本語のページを検索」をクリックさせているので、
「ウェブ全体から検索」をクリックさせるにはどうすればいいかわかりますよね?
ただ、「ウェブ全体から検索」はいちいちクリックしなくても、デフォルトで選択するようにしてありますが。
>質問2
I'm Feeling Luckyのsubmitのname属性を見て
>pCollection = pDocument->getElementsByName( _bstr_t( L"f" ) );
の f のところを変えてください。
で、試していないので微妙ですが、pCollection->item()で取得できるのは
MSHTML::DispIHTMLInputButtonElementPtr
になりそうなので、clickメソッドを使えばいいかなと。
>質問3
>printf("%s\n", pCollection->item( _variant_t( j ) ));
printfで何を表示させようとしているのでしょうか?
itemで取れるのは文字列(const char*の値)ではないです。
>複数の入力ボックスがある場合
でも、おそらくname属性は一意にしてあると思いますけど。
よってpCollectionのitemをぐるぐる回るということはないかと。
(別の取得の仕方をすればそなるかもしれないけど。)
今日はBlueさん、丁寧な解説ありがとうございます
>基本はHTMLを見るしかないです。
この一言でよく分かりました、何処で調べても
getElementsByNameの引数はStringと書いてあったと思うのですが
_bstr_tなるものが、よく分からずに、特殊な宣言とか引数があるのかと思っていましたww
>「ウェブ全体から検索」をクリックさせるにはどうすればいいかわかりますよね?
item( 1 )をitem( 0 )に変えたら出来ました。
>f のところを変えてください。
GoogleのHTMLをよく見たのですが、fというパラメータを与えている部分すら発見できませんでした(^^;
落ち着いてじっくり探してみます。
>itemで取れるのは文字列(const char*の値)ではないです。
そうでしたね、ポインタのアドレス取得しても意味ないな、確かに・・・
>おそらくname属性は一意にしてあると思いますけど。
GoogleのHTMLを見てqという値が入力ボックスのパラメータだという事が直に分かりました。
入力ボックスが複数存在しても、それぞれ一意のパラメータを与えて、それに
対応した入力ボックスを特定すれば良いと事と理解しました。
どうもありがとうございました、よく理解できました。
>getElementsByNameの引数はStringと書いてあったと思うのですが
おそらく見ているものがVC用ではないのでは?
(VBとかではString型で渡しますが。)
IHTMLDocument3::getElementsByName Method
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/mshtml/reference/ifaces/document3/getelementsbyname.asp
(タイプライブラリのインポートによって上のメソッドを
(_com_ptr_tクラスかなにかが)ラッピングしたものを使うことになると思います。)
VCであれば、BSTR型の値を指定します。
通常は、
BSTR b;
b = ::SysAllocString( L"f" );
pCollection = pDocument->getElementsByName( b );
::SysFreeString( b );
のように、(LPWSTR≠BSTRなので)SysAllocString等面倒な処理を入れないといけないのですが、
comdef.hの_bstr_tクラスはここら辺を内部でやってくれる便利なクラスで、
利用しています。
>GoogleのHTMLをよく見たのですが、fというパラメータを与えている部分すら発見できませんでした(^^;
fは form タグの名前です。
どちらのボタン(input type=submit)にも名前がついています。
「ウェブ検索ボタン」はformのsubmitメソッドでも押せましたが、
ボタンをclickしても押せると思います。
今回の「I'm Feeling Lucky」はformのsubmitメソッドで押せないので、
ボタンのclickで押すしかないのです。