MSXML2.XMLHTTPを利用してブラウザへ自動ログインするためには?


lalala5087  2011-09-15 16:49:18  No: 103038  IP: [192.*.*.*]

■質問概要
ログインする必要があるブラウザへ自動ログイン出来る方法を教えて下さい。
ただし制限としてMSXML2.XMLHTTPを利用する必要があります。

■実現したいこと
ブラウザのhtml認証画面(basic認証ではない)にて
自動ログインが出来るエクセルマクロを作成したい。

■詳細
以下URLにMSXML2.XMLHTTPを利用した今回の質問概要に近いサンプルが
記載されているのですが、実際に試してみるとうまくいきません。
http://madia.world.coocan.jp/vb/vb_bbs2/200412/200412_04120009.html


Dim X As Object
Set X = CreateObject("MSXML2.XMLHTTP.4.0")
X.Open "POST", ログイン情報のPOST先
X.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
'下記のuser,passはサイトフォームに合わせている
X.send CVar("user=myname&pass=password")
X.Open "GET", 取得したいページ
X.send

うまく動作するサンプルなどがあると非常に助かります。

編集 削除
魔界の仮面弁士  2011-09-16 01:31:44  No: 103039  IP: [192.*.*.*]

> ログインする必要があるブラウザへ自動ログイン出来る方法を教えて下さい。
提示されたコードには、ブラウザとの連動部分が記載されていないようですが…。

対象となるブラウザおよびそのバージョンは何でしょうか。
Internet Explorer? WebBrowser? あるいはそれ以外のブラウザでしょうか?


> ただし制限としてMSXML2.XMLHTTPを利用する必要があります。
確かに、XMLHTTP 等を使えば HTTP 通信によるデータ送受信を行えますが、
それをブラウザのログイン目的に使うのは無理があると思いますよ。

ブラウザの制御が必要なら、直接ブラウザに通信させた方がスマートかと。

XMLHTTP が有効なのは、Webサイトを自動巡回してデータを取得したり、
HTTP によるデータの自動アップロード/ダウンロードなどといったケースです。


> 自動ログインが出来るエクセルマクロを作成したい。
対象となるページがどのような構成になっているのかが明かされていないので、
具体的なコードは提示できませんが、特定の Web サイトに対して、
ブラウザでログインするまでが目的であれば、XMLHTTP を使うのではなく
InternetExplorer オブジェクトを CreateObject して、
対象のページに Navigate2 した後、ドキュメントの解析完了を待ってから、
Document プロパティを操作するという流れにしてみては如何でしょう。

(必要なのはログインまでであって、そこから先の処理は不要なのですよね?)


まぁ、XMLHTTP を必要としている理由は正直、良く分からなかったのですが、
とりあえずブラウザの話はここまでにしておいといて、以下では
HTTP 通信部分だけに着目してコードを見ていくことにします。


> 実際に試してみるとうまくいきません。
確認しようにも、対象としているサイトの情報などが一切ありませんので、
現時点では、そのサイトに対応したサンプルを提示するのは困難です。


今の状況では、まずは調査が先決かと思います。

Fiddler2 や Network Monitor や InetSpy などのツールを使って、
普通に手作業でブラウザからログインした場合の通信内容と、
プログラムからログインさせようとした場合の通信内容とが、
具体的にどのような違っていたのかを調べてみてください。

http://msdn.microsoft.com/ja-jp/library/bb250442.aspx
http://www.microsoft.com/japan/powerpro/TF/column/am_01_1.mspx
http://hide.maruo.co.jp/software/inetspy.html



> X.Open "POST", ログイン情報のPOST先
> X.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
user, pass を POST することでログインできるタイプの Web サイトであることは
確認済みなのですね? ログイン後のセッション管理は Cookie で行われるのでしょうか。

もしそうなら、先述のツール等を使って、Cookieが正しくやりとりされているかを
確認してみてください。MSXML のバージョンによっては、Cookie 送出に
問題がある可能性があるようですので。
http://support.microsoft.com/kb/290899/en-us

ただし今の段階では、Cookie が原因かどうかまでは分かりません。

しかし、もし仮に Cookie の扱いに問題があったのだとしたら、
WinInet 系である MSXML2.XMLHTTP.4.0 ではなく、
WinHTTP 系である WinHttp.WinHttpRequest.5.1 を使った方が
細かい制御には向いているかも知れません。
(ただしその場合、Cookie の取得とセットは自前で行うことになるかと思います)

編集 削除
lalala5087  2011-09-20 17:59:32  No: 103040  IP: [192.*.*.*]

返信遅くなり申し訳ありません。
また、詳細なコメントありがとうござます。
頂いたコメントに対して返信します。

> 対象となるブラウザおよびそのバージョンは何でしょうか。
> Internet Explorer? WebBrowser? あるいはそれ以外のブラウザでしょうか?
対象ブラウザはIE6以上(その他のブラウザは対象外)



> 確かに、XMLHTTP 等を使えば HTTP 通信によるデータ送受信を行えますが、
> それをブラウザのログイン目的に使うのは無理があると思いますよ。
> ブラウザの制御が必要なら、直接ブラウザに通信させた方がスマートかと。
> XMLHTTP が有効なのは、Webサイトを自動巡回してデータを取得したり、
> HTTP によるデータの自動アップロード/ダウンロードなどといったケースです。
詳細な背景を伝えていなくて、すみません。
XMLHTTPでなければやりたいことが実現出来ないのです。(理由は後述)


> 対象となるページがどのような構成になっているのかが明かされていないので、
> 具体的なコードは提示できませんが、特定の Web サイトに対して、
> ブラウザでログインするまでが目的であれば、XMLHTTP を使うのではなく
> InternetExplorer オブジェクトを CreateObject して、
> 対象のページに Navigate2 した後、ドキュメントの解析完了を待ってから、
> Document プロパティを操作するという流れにしてみては如何でしょう。
今回対象となるページは、
https://login.yahoo.co.jp/config/login?.src=www&.done=http://www.yahoo.co.jp
をイメージして頂けると分かりやすいと思います。
(ユーザID、パスワードが必要なhtmlフォーム)

おっしゃる通りInternetExploreオブジェクトでhtmlフォームにてログイン出来ることは確認済みなのですが、
既にxmlhttpオブジェクトで実装しているため、InternetExploreオブジェクトは利用出来ません。
※もう少し詳細にお伝えすると今とあるVBAの既存ツール改良を行っており、
※過去のツールはbasic認証画面対応ツールだったので、容易ににxmlhttpオブジェクトでログイン出来ました。
※しかし今回対象画面のインターフェースが変更になりhtmlフォーム認証になったため、四苦八苦しています。

cookieについてはも少し調査してみます。

以上、よろしくお願いします。

編集 削除
魔界の仮面弁士  2011-09-20 20:07:36  No: 103041  IP: [192.*.*.*]

> をイメージして頂けると分かりやすいと思います。
そのページが、XMLHTTP による送受信を許可しているかどうかも
確認しておいた方が良いでしょう。たとえば Twitter というサイトでは、
利用規約にてスクレイピングが明確に禁止されています。


> 既にxmlhttpオブジェクトで実装しているため
XMLHTTP では、結果が HTTP のリクエストとして、
「文字列」「XML」「バイナリ」のいずれかの形式として返されますよね。

しかし今回は、データの取得では無く、『ブラウザへ自動ログイン』が
目的だったはずです。XMLHTTP で取得した情報をブラウザ(IE6)へと
渡す部分については、どのように実装する予定なのでしょうか?

InternetExploreオブジェクトを使わずに渡すとなると、
かなり面倒なことになりそうに思えるのですが…。


> ユーザID、パスワードが必要なhtmlフォーム
入力されたパスワード等が、JavaScript を利用して、
毎回異なる文字列に暗号化してから送出されるタイプのサイトだと、
XMLHTTP での通信は非常に困難です。

そうではなく、通信内容が固定的もしくは規則的なものであれば、
XMLHTTP で対処できそうです。

いずれにしても、前回紹介した InetSpy や Fiddler2 といったツールを
用いて、送受信データの内容を調査するのが先決でしょうね。

(HTML コードの内容を見ただけで送信内容を想像できる場合は、
 そうしたツールを導入する必要は無いでしょうけれども)

編集 削除