Webからファイルをダウンロードする方法については、
過去ログから、XMLHTTPオブジェクトを使う方法や、Inetコントロールを使う方法などがあることを知りましたが、
これらの方法は、ログイン状態でのみ表示されるページでもダウンロードできるのでしょうか。
やってみたのですが、XMLHTTPオブジェクトを使っても、Inetを使っても、失敗しました。(目的のページはダウンロードできませんでした。)
ログインするには、Microsoft Internet Controlを使って、IEオブジェクトで行っています。
なお、WebBrowserコントロールは使用していないため、WebBrowserコントロールでの方法は考えていません。
Webからファイルを取得するには、どの方法が一番良いのでしょうか。Inetコントロールは制約があると書かれていたのですが、どのような制約なのでしょうか。
よろしくお願いします。
http://support.microsoft.com/default.aspx?scid=kb;ja;409931
自己レスすみません。
上記のページを見つけまして、Inetの制約を知りました。
じゃあXMLHTTPオブジェクトの方が良いのかな…と思いましたが、失敗したんですよね。
ルータとか、ファイアーウォールとか、そういうのは関係あるのでしょうか??
> これらの方法は、ログイン状態でのみ表示されるページでもダウンロードできるのでしょうか。
目的のサイトが、どのような認証方式を採用しているかによって異なります。
たとえば、.NET Passport認証を採用しているサイトもあれば、
IPアドレスやUser-Agentを見て判断しているサイトもありますよね。
単純な所では、BASIC認証で済ませている事も珍しくないですし、あるいは
SSLクライアント認証を採用している場合もありうるでしょう。
変わった所では、スマートカードが使われるサイトや、指紋認証で
ログインするサイトもありますし、あるいはそれらが複合的に
使われる事もあります。
まずは、目的のサイトのログイン方式を調査する所から始めてみてください。
とりあえず、BASIC認証方式のサイトであれば、XMLHTTPからは
open時の引数で、ユーザー/パスワード情報を指定できると思います。
HTMLフォームにて、ユーザーIDやパスワードを入力させる方式なら、
GETメソッドでのリクエストでは、送信情報をURLに含めて渡せばOKです。
POSTメソッドでのリクエストなら、リクエスト本文に含めて渡す事になります。
魔界の仮面弁士さん、回答ありがとうございます。
対象のサイトは、HTMLのFORM(POST)によるSSL認証です。(ヤフーなどのログインと同じ感じです。)
現在、formに直接データを送ってsubmitボタンをClickしてログインしてから、ダウンロードしたいページを以下のようにしています。
objHTTP.open "GET", strURL, False
objHTTP.send
> HTMLフォームにて、ユーザーIDやパスワードを入力させる方式なら、
> GETメソッドでのリクエストでは、送信情報をURLに含めて渡せばOKです。
> POSTメソッドでのリクエストなら、リクエスト本文に含めて渡す事になります。
きっとこうおっしゃっているのは、対象のページにログイン認証がある場合でしょうか?
やりたいのは、対象のページにログイン認証があるわけではなく、ログインした後、そのサイト内のページを参照できるというものです。
この場合、どのようにすれば解決できるでしょうか。
また、”POSTのリクエスト本文に含めて渡す”というのは、どのようにするのでしょうか。
すみませんがお力を貸してください。よろしくお願いいたします。
> (ヤフーなどのログインと同じ感じです。)
それは、
https://login.yahoo.co.jp/config/login
の事でしょうか。
上記ページを見たところ、データを取得するたびに
<input type=hidden name=".u" value="〜〜">
<input type=hidden name=".challenge" value="〜〜">
の部分が毎回変化しているようですね。フォーム認証とは別に、
ワンタイムパスワード認証も併用されているのでしょうか。
> ログインした後、そのサイト内のページを参照できるというものです。
その場合はさらに、セッションステートのアーキテクチャについても
調査する必要があると思います。(「ログインされている」という情報を、
サーバ側がどのような手法で維持・管理しているか)
たとえば、セッションクッキーで保持されているのであれば、
Dim X As Object
Set X = CreateObject("MSXML2.XMLHTTP.4.0")
X.Open "POST", ログイン情報のPOST先
X.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
X.send CVar(ログインパラメータ)
X.Open "GET", 取得したいページ
X.send
のように、同一プロセスから連続して呼び出せば、セッションが
引き継がれたように思います。
# といっても、最近使っていないので、あまり覚えていないのですが。(^_^;)
> ログインするには、Microsoft Internet Controlを使って、IEオブジェクトで行っています。
[Microsoft Internet Transfer Control] ではなく、
[Microsoft Internet Control] なのですよね。
> なお、WebBrowserコントロールは使用していないため、
あれ?
[Microsoft Internet Control]って、WebBrowserコントロールの事ですよね。
結局、WebBrowserは使われているのでしょうか。
それとも、まったく使っていないのでしょうか?
> WebBrowserコントロールでの方法は考えていません。
XMLHTTP あるいは Inet コントロールでの取得方法は検討されたのに、
WebBrowserコントロールや InternetExplorerオブジェクトを使う方法は
採用されなかった(or 検討されなかった)のには、何か理由がありますか?
魔界の仮面弁士さん、ありがとうございます。
いろいろ言葉足らず&認識不足ですみません。
実際のサイトはヤフーではありません。
見たところ、ヤフーのような毎回変化するような値は使っていませんでした。
ログイン情報は、きっとセッションクッキーで保持していると思います。
(詳しくないのではっきりとはわからないのですが…)
> [Microsoft Internet Transfer Control] ではなく、
> [Microsoft Internet Control] なのですよね。
> 結局、WebBrowserは使われているのでしょうか。
> それとも、まったく使っていないのでしょうか?
申し訳ありません。私の認識不足でした。
[Microsoft Internet Transfer Control]ではなく、
[Microsoft Internet Control]を使っています。
WebBrowserコントロールは使用していませんが、InternetExplorerオブジェクトは
使用しています。
WebBrowserコントロールとInternetExplorerオブジェクトの参照先が、
共に[Microsoft Internet Control]だとは知りませんでした…。
(参照設定では参照していますが、コンポーネントには追加していません。)
> XMLHTTP あるいは Inet コントロールでの取得方法は検討されたのに、
> WebBrowserコントロールや InternetExplorerオブジェクトを使う方法は
> 採用されなかった(or 検討されなかった)のには、何か理由がありますか?
上記の誤解に関連して、WebBrowserコントロールは使用していなかったため、
WebBrowserコントロールの使用は検討から外しました。
> Dim X As Object
> Set X = CreateObject("MSXML2.XMLHTTP.4.0")
> X.Open "POST", ログイン情報のPOST先
> X.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
> X.send CVar(ログインパラメータ)
> X.Open "GET", 取得したいページ
> X.send
この方法でやってみようと思います。
これだとログインも行っているため、これ以前のFORMでのログインは不要になるのでしょうか。
また、「ログインパラメータ」とはどのような形式で指定するのですか?
X.send CVar("&user=myname&pass=password")
で合っていますでしょうか?
あともう一つ、質問です。
XMLファイルを取得したい場合、動的に生成された(RSSのような)ファイルの場合、
"Content-Type" が "text/xml" ではない場合があります。
この場合は responseXMLでXMLオブジェクトを取得できないんですが、
これの解決方法ってあるでしょうか。
objHTTP.SetRequestHeader "Content-Type", "text/xml" としてみましたがダメでした。
(当てずっぽうでやってみたので、根本的に間違ってるでしょうか…)
> (参照設定では参照していますが、コンポーネントには追加していません。)
なるほど、そういう事ですか。
> WebBrowserコントロールとInternetExplorerオブジェクトの参照先が、
> 共に[Microsoft Internet Control]だとは知りませんでした…。
両者は、同じInterfaceを実装しています。
プロパティやメソッドも、ほとんど一緒ですよね。
> WebBrowserコントロールは使用していませんが、InternetExplorerオブジェクトは
> 使用しています。
InternetExplorerを既に使っておられるならば、
1. IEのNavigate2メソッドでログインページを表示。
2. formエレメントのsubmitメソッドで認証情報を送信。
3. IEのNavigate2メソッドで、取得したいページに移動。
4. 表示されたdocumentプロパティをIPersistFile.Saveにて保存。
という手法もあるかと。
> これだとログインも行っているため、これ以前のFORMでのログインは不要になるのでしょうか。
「これ以前のFORMでのログイン」というのが、何の事なのかわかりません…。
> また、「ログインパラメータ」とはどのような形式で指定するのですか?
> X.send CVar("&user=myname&pass=password")
最初の & が余計に思えます。
たとえば、formエレメントの内容が、
<input type="hidden" name="foo" value="123">
<input type="text" name="user" value="myname">
<input type="text" name="pass" value="password">
ならば、
X.send CVar("foo=123&user=myname&pass=password")
ですかね。
> "Content-Type" が "text/xml" ではない場合があります。
> この場合は responseXMLでXMLオブジェクトを取得できないんですが、
仕様なのだそうです。
> これの解決方法ってあるでしょうか。
こんな感じで。
Dim F As Boolean
F = 妥当性検査をするか否か
Set Doc = CreateObject("MSXML2.DOMDocument.4.0")
Doc.async = False
Doc.resolveExternals = F
Doc.validateOnParse = F
If Doc.Load(x.responseStream) Then
Else
End If
ツイート | ![]() |