他のサイトのコンテンツを ASP で取得する

最終更新日時:2017-04-28 15:31:51
ASP

ASP を使って他のサイトのコンテンツを取得する方法についてです。
※ ASP なので、非常に古い情報です(^_^;

以下の5つの方法が考えられます。

・BASP21 を使用
・IE オブジェクトを使用
・WinInet を使用
・WinSock, SSPI を使用
・MSXML2 を使用


BASP21 を使用


BASP21 はライセンスフリーなライブラリです。公式サイトはこちら
しかも、単に HTTP 通信だけできるのではなく、FTP, メールの送受信等をはじめ数多くの機能を持っています。
とても便利なライブラリなので、これを使用して解決できるのであれば、迷わず BASP21 を使った方がいいですね。
ただし、業務での開発といった場合には、BASP21 はソースが公開されているわけではないので、少々使うには支障があります。
BASP21 にバグがあった場合には修正することも出来ず、かといってライセンスフリーなライブラリですのでサポートに期待することもできません。
というわけで、私の場合には BASP21 を使わず、自力で解決することになったのでした。
また、BASP21 では HTTPS 通信には対応していません。
これも業務での開発には問題になりがちですね。
ということで、実際には BASP21 を使ったことがないので紹介だけ(/o\)

IE オブジェクトを使用


自力で作るのであれば、一番簡単なのは IE オブジェクトを使う方法です。
以下のようなとても簡単なコードでコンテンツを取得できます。

 Set ie = CreateObject("InternetExplorer.Application")
 ie.Navigate ("http://www.yahoo.co.jp")
 For i = 0 To 10000
   If ie.ReadyState = 4 Then
     Exit For
   End If
 Next
 Set obj = ie.Document
 
 'src に HTML のソースを入れる
 src = obj.body.outerHTML


ただ、この方法だと IE のオブジェクトを作成するのでとても重いです。
For 文中で Sleep を入れたりすれば多少はマシになるかもしれませんが、高々 HTTP 通信するだけでこんなに重いのは割に合わないというものです。
従って、この方法は、ちょっと試しに他のサイトのソースを取ってくる部分を実装してみるくらいの用途しか使えないと思います。

WinInet を使用


wininet.dll の API を使って通信をするという方法です。
wininet.dll はそのままでは ASP からは使えないので、Active X 化する必要があります。
以下のような VB のコードを Active X コンポーネントにし、そのコンポーネントを ASP から呼び出せば、他のサイトのコンテンツを ASP 内で取得できます。

※さらに詳細なコードはダウンローダーを作るを参照。
※Internet 関連の関数についてはGeneral Internet Functionsをどうぞ。

 Public Function Post(url As String) As String
    ih = InternetOpen("User Agent", INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0)
    hFile = InternetOpenUrl(ih, _
                            url, _
                            vbNullString, _
                            0, _
                            INTERNET_FLAG_RELOAD, _
                            0)
                            
    Dim buf         As String * 2048
 
    flag = True
    While flag
        buf = vbNullString
        flag = InternetReadFile(hFile, buf, Len(buf), rsize)
        sBuffer = sBuffer &Left$(buf, rsize)
        If Not CBool(rsize) Then flag = False
    Wend
    
    'InternetCloseHandle ihorh
    'InternetCloseHandle ich
    InternetCloseHandle hFile
    InternetCloseHandle ih
    
    Post = sBuffer
 
 End Function


ただし、これも1つ重大な問題点があります。
wininet.dll 自体が、サービス上での動作をサポートしていません。
詳しくは、[INFO] サービスでは WinInet の使用はサポートされないを参照してください。
簡単に言えば、自作ブラウザのようにクライアントとなるようなアプリケーションでは使用できるが、IIS 上で動く ASP のようにサービス上で動くプログラムの場合には動作が保証されない、ということです。
試してみた感じでは正常に動きますが、長時間連続稼働を考えると怖くて使えません。
ただ、手っ取り早く作りたい場合にはこれはかなり使えると思います。

WinSock, SSPI を使用


おそらく、これが一番正当なやり方です。
が、めちゃめちゃ面倒ですし、難しいです。
SSL を使用しないのであれば WinSock のみなので、これだけならまだ楽かな?
あまりに面倒だったので、ここでは紹介しません(/o\)
MS のサイトからサンプルコードが得られますので、これを元に作ります。

MSXML2 を使用


結局私が使った方法がこれ。
使い方は簡単なのですが、これだと厳密には XML を取得することになるので、応用が利かないかも。

 Dim oXmlHttp
 Set oXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
 Call oXmlHttp.open("POST", url, False)
 Call oXmlHttp.send(data)


この後、

 html = oXmlHttp.responseText


とすると、コンテンツの内容が取得できます。
ちなみに、url には https が頭に付くような URL を指定すれば勝手に SSL 通信をしてくれますので何も考えなくてもよいです。
また、

 oXmlHttp.status


で、HTTP のレスポンスコードを取得できます。

お問い合わせは 掲示板 にて。