• 追加された行はこの色です。
  • 削除された行はこの色です。
#title(RESTを使ったWebサービスにアクセスする)

#contents

*.NETプログラミング研究 第73号 [#w46bc3dc]

**.NET Tips [#f80975ad]

***RESTを使ったWebサービスにアクセスする [#r8c22c7c]
**RESTを使ったWebサービスにアクセスする [#r8c22c7c]

前回はSOAPを使ったWebサービスにアクセスする方法を紹介しましたが、今回はRESTによるWebサービスにアクセスする方法について説明します。

現在一般に公開されているWebサービスを調べてみると、RESTを採用いるWebサービスが多いようです。AmazonのようにSOAPとRESTの両方のインターフェイスを提供しているWebサービスでも、アクセスのほとんどがRESTであるといいます(注)。このように現状ではWebサービスのインターフェイスとしてRESTはSOAPよりも広く利用されていると言えそうですが、.NET FrameworkはSOAP重視のようで、MSDNでもRESTについてはほとんど(というより私の知る限りでは全く)触れられていません。

注:「REST vs. SOAP at Amazon」によると、85%がRESTの使用ということです。

-[[REST vs. SOAP at Amazon>http://www.oreillynet.com/pub/wlg/3005?wlg=yes]]

しかし、.NET FrameworkではSOAPほど簡単な方法が用意されていないとはいうものの、RESTのWebサービスへのアクセスも難しいわけではありません。ここでは、Yahoo! JAPANのウェブ検索Webサービスを例に、その方法を具体的に解説します。

-[[Yahoo!デベロッパーネットワーク - ウェブ検索>http://developer.yahoo.co.jp/search/web/V1/webSearch.html]]

RESTを使ったWebサービスにアクセスする流れを簡単にまとめると、次のようになります。

+Webサービスサーバーに送信するデータを作成する。
+データを指定されたURIにHTTPの適当なメソッド(GET、POST、DELETE、PUT)により送信する。
+Webサービスサーバーから返されるXMLデータを受信する。
+受信したデータを解析する。

リクエストを送信し、レスポンスを受信する2、3の部分は、.NET FrameworkのHttpWebRequestとHttpWebResponseクラスを使用すればよいでしょう。DOBON.NETでは、次のページでこれらの使い方を説明しています。

-[[WebRequest、WebResponseクラスを使ってファイルをダウンロードし表示する>http://dobon.net/vb/dotnet/internet/webrequest.html]]

4の受信したXMLデータを解析する方法は、幾つか考えられます。しかし通常は、XmlDocumentクラスを使って解析するか、XMLスキーマ定義ツールXsd.exeにより作成されたクラスを使うかになるでしょう。ここではXsd.exeを利用する方法を紹介します(XmlDocumentクラスを使った方法も後述します)。

***Yahoo!ウェブ検索Webサービスにアクセスする [#i1950fa0]

それではYahoo!ウェブ検索Webサービスにアクセスする方法を見ていきましょう。Yahoo!のWebサービスを使用するには「アプリケーションID」というものが必要ですので、もしなければ、これを登録しておきます。下記のページから登録できます。

-[[Yahoo!デベロッパーネットワーク - アプリケーションIDの登録>http://api.search.yahoo.co.jp/webservices/register_application]]

''Xsd.exe''

まずはXsd.exeを使ってXMLデータを解析するのに役立つクラスを作成しておきます。Xsd.exeのパスは、Visual Studio 2005を「C:\Program Files\Microsoft Visual Studio 8」にインストールしているならば、

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\Xsd.exe

のようになるでしょう。

-[[XML スキーマ定義ツール (Xsd.exe)>http://msdn2.microsoft.com/ja-jp/library/x6c1kb0s.aspx]]

Xsd.exeを使用するために、まずYahoo!ウェブ検索WebサービスのXMLスキーマをダウンロードしておきます。ファイル名は"WebSearchResponse.xsd"としておきます(拡張子は必ず「xsd」にしてください)。

-[[Yahoo!ウェブ検索Webサービス XMLスキーマ>http://api.search.yahoo.co.jp/WebSearchService/V1/WebSearchResponse.xsd]]

そして次のようなコマンドを実行し、クラスを作成します。

xsd.exe /c /l:CS /n:Yahoo.jp.WebSearchResponse WebSearchResponse.xsd

「/c」は指定したスキーマと対応するクラスを作成することを意味します。「/c」の代わりに「/d」を使用してクラスを作成することもできますが、その場合はDataSetから派生したクラスが作成されます(「/d」を用いて作成したクラスの使用法は後述します)。

また「/l:CS」というのは、C#のコードを生成するという意味です。VB.NETであれば「/l:VB」、JScriptであれば「/l:JS」、Visual J#であれば「/l:VJS」とします。何も指定しないと、C#になります。

さらに作成されるクラスの名前空間を「Yahoo.jp.WebSearchResponse」とするために、「/n:Yahoo.jp.WebSearchResponse」を指定しています。「/n」を指定しないと、名前空間なしとなります。

上記のコマンドを実行することにより、WebSearchResponse.xsdのあるフォルダにWebSearchResponse.cs(「/l:VB」としているならばWebSearchResponse.vb)というクラスファイルが作成されます(違うフォルダに作成したいのであれば、「/o」オプションを指定しましょう)。このファイルをWebサービスを使用するプロジェクトに追加すれば、使用できるようになります。

''クライアントアプリケーションの作成''

これで準備は整いましたので、Webサービスを使うクライアントを作成しましょう。ここではWebアプリケーションを作成します。

さっそくですが、具体的なコードを紹介します。ここではフォームにテキストボックス(TextBox1)とボタン(Button1)を配置し、テキストボックスに入力された文字列をクエリーとして検索し、結果をLabel1に表示しています。

#code(vbnet){{
<%@ Page Language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    Protected Sub Button1_Click( _
        ByVal sender As Object, ByVal e As System.EventArgs)
        'URLを構築する
        Dim requestUrl As String = _
            "http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch"
        'アプリケーションIDを指定(必ず指定すること)
        requestUrl += "?appid=xxxxxx"
        '検索クエリー。UTF-8エンコードする。
        requestUrl += "&query=" + Server.UrlEncode(TextBox1.Text)

        'HttpWebRequestの作成
        Dim request As System.Net.HttpWebRequest = _
            CType(System.Net.WebRequest.Create(requestUrl), _
            System.Net.HttpWebRequest)
        Dim response As System.Net.HttpWebResponse = Nothing
        Dim res As Yahoo.jp.WebSearchResponse.ResultSet
        Try
            'レスポンスの取得
            response = CType(request.GetResponse(), _
                System.Net.HttpWebResponse)
            Dim strm As System.IO.Stream = response.GetResponseStream()
            'サーバーから返されたXMLデータを解析
            'xsd.exeで作成したクラスに逆シリアル化
            Dim serializer As New System.Xml.Serialization.XmlSerializer( _
                GetType(Yahoo.jp.WebSearchResponse.ResultSet))
            res = CType(serializer.Deserialize(strm), _
                Yahoo.jp.WebSearchResponse.ResultSet)
        Catch ex As Exception
            Label1.Text = "エラー:" + Server.HtmlEncode(ex.Message)
            Return
        Finally
            If Not (response Is Nothing) Then
                response.Close()
            End If
        End Try
        
        '結果を表示
        Label1.Text = ""
        If res.totalResultsReturned = "0" Then
            Label1.Text += "該当するページが見つかりませんでした。"
        Else
            Label1.Text += "<b>" + _
                Server.HtmlEncode(TextBox1.Text) + _
                "</b> の検索結果 約 " + _
                res.totalResultsAvailable + "件中 " + _
                res.firstResultPosition + " - " + _
                res.totalResultsReturned + " 件目<br />" + vbLf

            Label1.Text += "<ul>" + vbLf
            Dim item As Yahoo.jp.WebSearchResponse.ResultType
            For Each item In res.Result
                Label1.Text += "<li><a href=""" + _
                    item.ClickUrl + """>" + item.Title + "</a>"
            Next item
            Label1.Text += "</ul>" + vbLf
        End If
    End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Yahoo!ウェブ検索Webサービスのサンプル</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server"
         OnClick="Button1_Click" Text="検索" /><br />
        <br />
        <asp:Label ID="Label1" runat="server"
         EnableViewState="False"></asp:Label>
    </div>
    </form>

<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->
<span style="margin:15px 15px 15px 15px">
<a href="http://developer.yahoo.co.jp/about">Webサービス by Yahoo! JAPAN</a>
</span>
<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->
</body>
</html>
}}

#code(csharp){{
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected void Button1_Click(object sender, EventArgs e)
    {
        //URLを構築する
        string requestUrl =
            "http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch";
        //アプリケーションIDを指定(必ず指定すること)
        requestUrl += "?appid=xxxxxx";
        //検索クエリー。UTF-8エンコードする。
        requestUrl += "&query=" + Server.UrlEncode(TextBox1.Text);

        //HttpWebRequestの作成
        System.Net.HttpWebRequest request =
            (System.Net.HttpWebRequest)System.Net.WebRequest.Create(
            requestUrl);
        System.Net.HttpWebResponse response = null;
        Yahoo.jp.WebSearchResponse.ResultSet res;
        try
        {
            //レスポンスの取得
            response = (System.Net.HttpWebResponse)request.GetResponse();
            System.IO.Stream strm = response.GetResponseStream();
            //サーバーから返されたXMLデータを解析
            //xsd.exeで作成したクラスに逆シリアル化
            System.Xml.Serialization.XmlSerializer serializer =
                new System.Xml.Serialization.XmlSerializer(
                typeof(Yahoo.jp.WebSearchResponse.ResultSet));
            res = (Yahoo.jp.WebSearchResponse.ResultSet)
                serializer.Deserialize(strm);
        }
        catch (Exception ex)
        {
            Label1.Text = "エラー:" + Server.HtmlEncode(ex.Message);
            return;
        }
        finally
        {
            if (response != null)
                response.Close();
        }

        //結果を表示
        Label1.Text = "";
        if (res.totalResultsReturned == "0")
        {
            Label1.Text += "該当するページが見つかりませんでした。";
        }
        else
        {
            Label1.Text += "<b>" + Server.HtmlEncode(TextBox1.Text) +
                "</b> の検索結果 約 " +
                res.totalResultsAvailable + "件中 " +
                res.firstResultPosition + " - " +
                res.totalResultsReturned + " 件目<br />\n";

            Label1.Text += "<ul>\n";
            foreach (Yahoo.jp.WebSearchResponse.ResultType item in res.Result)
            {
                Label1.Text += "<li><a href=\"" + item.ClickUrl + "\">" +
                    item.Title + "</a>";
            }
            Label1.Text += "</ul>\n";
        }
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Yahoo!ウェブ検索Webサービスのサンプル</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server"
         OnClick="Button1_Click" Text="検索" /><br />
        <br />
        <asp:Label ID="Label1" runat="server"
         EnableViewState="False"></asp:Label>
    </div>
    </form>

<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->
<span style="margin:15px 15px 15px 15px">
<a href="http://developer.yahoo.co.jp/about">Webサービス by Yahoo! JAPAN</a>
</span>
<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->
</body>
</html>
}}

Yahoo!ウェブ検索Webサービスではリクエストの送信にHTTP GETを使用しますので、まずはWebサービスサーバーにデータを送信するためのURLを構築します。

次にHttpWebRequestとHttpWebResponseクラスを使用してサーバーにアクセスし、結果として返されるXMLデータを取得します。

サーバーから返されたXMLデータは、XmlSerializer.Deserializeメソッドにより、xsd.exeで作成されたResultSetクラスに逆シリアル化されます。こうして作成されたResultSetオブジェクトを参照すれば、結果を簡単に取得できるようになります。

参考:

-[[[HOW TO] XML のシリアル化を使用してオブジェクトの読み込みと書き込みを行う方法>http://support.microsoft.com/default.aspx?scid=kb;ja;301223]]

''xsd.exeでDataSetから派生したクラスを作成した場合''

xsd.exeでクラスを作成するときに「/c」ではなく「/d」としてDataSetから派生したクラスを作成した場合は、DataSet.ReadXmlメソッドを使ってXMLデータを読み込みます。

以下に例を示します。これは先に示したサンプルと全く同じことをするものです。
この例は、[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/DataSetの派生クラスを使用/C#]]と[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/DataSetの派生クラスを使用/VB.NET]]で紹介しています。これは先に示したサンプルと全く同じことをするものです。

例は[[自由区/Webサービス紹介/Yahoo!検索Webサービス]]にあります。

''XmlDocumentクラスでXMLデータを解析する''

xsd.exeで作成したクラスを使わずに、Webサービスが返したXMLデータを解析するには、XmlDocumentクラスを使うのが適当でしょう。上記のサンプルと同じことをxsd.exeで作成したクラスを使わずに、XmlDocumentクラスにより解析する例を以下に示します。
xsd.exeで作成したクラスを使わずに、Webサービスが返したXMLデータを解析するには、XmlDocumentクラスを使うのが適当でしょう。上記のサンプルと同じことをxsd.exeで作成したクラスを使わずに、XmlDocumentクラスにより解析する例を[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/XmlDocumentで解析/C#]]と[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/XmlDocumentで解析/VB.NET]]で紹介しています。

例は[[自由区/Webサービス紹介/Yahoo!検索Webサービス]]にあります。

***Yahoo!ウェブ検索Webサービスの使い方 [#t53dce56]

Yahoo!ウェブ検索Webサービスの使い方をもう少し詳しく説明しましょう。リクエストパラメータとレスポンスフィールドに関する説明はYahoo!デベロッパーネットワークにありますので、ここでは具体的なコードを示します。

-[[Yahoo!デベロッパーネットワーク - ウェブ検索>http://developer.yahoo.co.jp/search/web/V1/webSearch.html]]

以下に示すWebアプリケーションでは、検索に使うクエリー文字のほかに、指定検索の種類(クエリー文字をすべて含むか、いずれかを含むか、文章として含むか)、表示件数、ファイル形式(HTML、PDFなど)、アダルトコンテンツの表示、類似の結果の表示、日本語のページのみの表示、日本にあるウェブサイトのみの表示、検索するドメインといったオプションを指定して検索できます。また、結果も詳しく(要約、キャッシュ情報、更新日、MIMEタイプなど)表示しています。
[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/C#]]と[[自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/VB.NET]]で紹介しているWebアプリケーションでは、検索に使うクエリー文字のほかに、指定検索の種類(クエリー文字をすべて含むか、いずれかを含むか、文章として含むか)、表示件数、ファイル形式(HTML、PDFなど)、アダルトコンテンツの表示、類似の結果の表示、日本語のページのみの表示、日本にあるウェブサイトのみの表示、検索するドメインといったオプションを指定して検索できます。また、結果も詳しく(要約、キャッシュ情報、更新日、MIMEタイプなど)表示しています。

例は[[自由区/Webサービス紹介/Yahoo!検索Webサービス]]にあります。

最後にYahoo!ウェブ検索Webサービスを使用する際の注意点を幾つか挙げます。

Yahoo!デベロッパーネットワークにはlanguageリクエストパラメータのデフォルトは「ja」と書いてありますが、実際にはデフォルトは「すべての言語」であるようです。上のサンプルで「日本語のページのみ」を選択するとlanguageリクエストパラメータをjaとしますが、何も指定しない時と比べて明らかに結果が異なります。

また、Yahoo!のWebサービスを利用するすべてのサイトやアプリケーションにはクレジットを表示する必要があることにも注意してください(上のサンプルでは表示しています)。詳しくは、Yahoo!デベロッパーネットワークをご覧ください。

Webサービスで検索した結果と、実際にYahoo! JAPANで検索した結果が若干違いますが、これがなぜなのかは分かりません。Yahoo!の提供するWebサービスの一つである画像検索Webサービスなどは検索結果が大きく異なり、Webサービスで検索した方が圧倒的に検索件数が少なくなります。本家米国のYahoo!でも同様のWebサービスを提供していますが、この米国のWebサービス「Image Search Web Services」を利用した時の結果はYahoo! JAPANで実際に検索した結果に近くなります。少なくとも画像検索Webサービスについていえば、Yahoo! JAPANのWebサービスを使うよりも、米国Yahoo!のWebサービスを使った方がよさそうです。

-[[Image Search Documentation for Yahoo! Search Web Services>http://developer.yahoo.com/search/image/V1/imageSearch.html]]

ちなみにYahoo! JAPANのウェブ検索Webサービスでは検索結果を最大50件までしか取得できませんが、米国Yahoo!のWebサービスでは100件まで取得できます。(画像、動画の検索では、両方とも50件までです。)

**コメント [#kcbbc1ab]
#comment

//これより下は編集しないでください
#pageinfo(,2010-03-19 (金) 02:52:58,DOBON!,2010-03-19 (金) 02:57:27,DOBON!)
#pageinfo([[:Category/.NET]],2006-09-09 (土) 06:00:00,DOBON!,2010-03-23 (火) 03:14:34,DOBON!)

[ トップ ]   [ 新規 | 子ページ作成 | 一覧 | 単語検索 | 最終更新 | ヘルプ ]