Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【手抜きUI】今更C#でBingの画像サーチしてみました(50枚以上対応)

More than 3 years have passed since last update.

ある所に、C言語でドライバとかメンテしていれば良かったおっさんがいました。彼は紆余曲折の末、IoT系の部署に放り込まれ、やれAWSだデータ収集だと新しい仕事でテンぱっています。

その流れで機械学習とか面白そうだと感じた彼は、とりあえず流行りのニューラルネット系でもいじってみようかなと考えました。この分野は画像処理が進んでますので、手始めに時崎狂三と鳶一折紙の区別でもさせてみようかと彼は思いました。が、どうも元データをどう集めるか結構面倒である事に気がついたのです。

あっちこっちググりまくると、今(2016/7月)だとBingのWebAPIをC#から扱うのがまぁ簡単そうに見えました。なので、実際にやってみたのがこれです。

Bingについて

本家の説明はここです
Azure系のWebWPIですね。要は。これを使うと検索が出来ますというもの。

利用するには

sadapon2008さんのPHPからBing Search APIを使って画像を収集するという記事がとても良くまとまっていますので、是非ご一読下さい。注意点は以下。

  • 無料では月5000回です。
  • 1回50件までなので、100件欲しい場合は2回消費するシステムです。

ちなみにAzure Marketplaceサービス自体はここ、で今回使うBingは「データ」をクリックすると行きます。

C#から利用するには

以下のリンクを見たり、ダウンロードしたりでやっていく感じと思います。

Migrating Bing Search API Applicationsを見ると分かりますがC#のライブラリを使うと割と簡単に必要なデータが集められそうですが、以下の点に注意が必要です(これはdocxにも記述があります)

  • using System;using System.Net; 特に後者は多分自分で追加が必要
  • System.Data.Services.Client を参照する事。

あと、私の環境だけかもしれませんが、VisualStudio2015では以下の箇所でエラーが出たので少しいじりました。

// docの記述
 var imageQuery = bingContainer.Image(word, null, null, null, null, null); 

// こうすればパスる(null1個追加)
var imageQuery = bingContainer.Image(word, null, null, null, null, null, null);

これで動きますが・・

50件目以降問題

Bingでは1回の検索で50件までの応答が戻ります。50件でディープラーニングを名乗るのはさすがに恥ずかしいため(※)、もう少し欲しくなるじゃないですか。でもその方法が分からない・・
→※ まぁ学習済データを使って20件でディープラーニングしたとかいう話も聞いた事はありますが。。

そこでカスな私がググるとこんなのが。

Bing search api returns only 50 results per request

↑にもありますがこっちのADM_SCHEMA_GUIDEに記載があって、これに従った記述が必要です。具体的には以下ですね。以下は51件目からよこせと指示しているコードです。

imageQuery = imageQuery.AddQueryOption("$skip", 50);

ちなみにこれはBing Search APIデータからリンクされているFAQでも記載がありました。良く見ろって事ですねごめなさい。

C#で検索コードを書いてみる。

という事で実際に書いてみました。さすがにライブラリを使えば非常に簡単でこんなので動きました。ほぼほぼサンプルのままですが。

// ↓をやってます。
using Systemt;
using System.Net;

        private void CallBingSearchAPI(string word)
        {
            // 以下で定義されたメンバ変数を使って検索、結果を格納します。

            // 入力
            // 引数word が検索単語です。
            // 以下のコードで使っている定義です。呼び出す前に設定済です。
            //   private const string BING_SEARCH_API_URL = "https://api.datamarket.azure.com/Bing/Search/";
            //   private string m_BingKey = "プライマリ アカウント キー";
            //   private int m_count; // 何回目の検索であるかが設定されています。

            // 出力
            // 以下に成功失敗が入ります。
            //   private bool m_success;
            // 失敗の際には以下にエラー(例外メッセージ)が入ります。
            //   private string m_exceptionMeggase;
            // 成功の際には、以下の個数が入ります。
            //   private int m_numberOfItem;
            // 以下にタイトルと画像のURLをそれぞれ入れます。
            //   private string[] m_title = new string[50];
            //   private string[] m_mediaUri = new string[50];

            m_numberOfItem = 0;
            try
            {
                m_BingContainer = new Bing.BingSearchContainer(new Uri(BING_SEARCH_API_URL));
                m_BingContainer.Credentials = new NetworkCredential(m_BingKey, m_BingKey);

                var imageQuery = m_BingContainer.Image(word, null, null, null, null, null, null);
                imageQuery = imageQuery.AddQueryOption("$top", 50);
                imageQuery = imageQuery.AddQueryOption("$skip", m_count *50);
                var imageResults = imageQuery.Execute();
                foreach (Bing.ImageResult result in imageResults)
                {
                    m_title[m_numberOfItem] = result.Title;
                    m_mediaUri[m_numberOfItem] = result.MediaUrl;
                    m_numberOfItem++;
                }
                m_success = true;

            }
            catch (Exception e)
            {
                m_exceptionMeggase = e.Message;
                m_success = false;
            }
        }

これは実際に動かしたアプリから該当部分を抜粋して、コピペしたものです。

オプション系は一切使っていませんので、使う際はdocx系など見ながら設定すれば良いのかなと思っています。

コードではタイトル(ブラウザでBIng検索した際に出るアレです)と画像へのURLのみ取り出していますが、もちろん他の情報を取り出す事も出来ます。

動作確認用アプリケーション

上記の確認が行える動作確認用にアプリを、これの宣伝もかねて作ってみました。以下の機能を持ちます。

  • 任意の単語で画像検索します。
  • 検索結果の一覧をHTMLで表示します。クリックで画像を見ることも出来ます。
  • 50件以上でも検索可能です。
  • 過去の情報も持っていますので、例えば200件検索した後、51-100の一覧を再度出すことが出来ます(トランザクション消費はしません)。
  • ただし検索単語を変更すると一覧は消えます。
  • 検索結果をjsonファイルで提供します。jsonファイルは単語が変更されても残ります(同一単語で再検索すると上書きされます)
  • 簡易的ではありますが、プロ生ちゃんが案内してくれます。

要件

  • VisualStudio2015を使います。
  • WIndows7,10 (共に64bit)、Windows8.1(32bit)で確認しています。
  • 開発者がアホのため、ちょっと設定とか必要がです。それに付き合ってくれる人
  • 出来立てなので生暖かい目で見守ってくれる人

ダウンロード

CuiHelperを使っていますので、まずはHTML系のコンテンツが必要です。

  • GitHubのここにあるCuiHelperContentsをフォルダ毎落としてどこかに置いて下さい。
  • 次にアプリ本体のVisualStudioプロジェクトをGitHubのここから落として下さい。

ビルド

  1. BingImageSearch\BingImageSearch\Resourcesフォルダにあるsetting.jsonをエディタで開けます。
{
    "parameters":{
        "ImagePath":"C:\\CuiHelperContents\\img\\",
        "ContentsPath": "C:\\CuiHelperContents\\",
        "PrimayKey" : "Please Your Primary Key"
     }
}

2.各項目を入力します。

  • ImagePathは落とした CuiHelperContents\img\ フォルダを上記例にならってフルパスで指定します(\は2つ続けて下さい)
  • ContentsPathも同様に落とした CuiHelperContents\ フォルダをフルパスで指定します。
  • PrimaryKeyにプライマリ アカウント キーの文字列を入れて下さい。ここの「プライマリ アカウント キー 表示する」をクリックすると出てきます。

3.後はVisualStudioでビルドすればBingImageSearch.exeが出来ます。

使い方

まず最初に謝罪。大変申し訳ございませんが、この確認で何回かトランザクションを消費してしまいます。ご理解の上、進んで戴ければ幸いです。

  1. BingImageSearch.exeをダブルクリックで起動します。DebugモードならVisualStuduioの”デバッグの開始”でも良いです。
  2. 暫くするとBing Search APIの画面に行こうとします。必要であればログインして下さい。もしかすると、ここでうまく立ち上がらないかもしれません。setting.jsonに問題がなければ、大変お手数ですが再度立ち上げてみて下さい。
  3. ログインが終わりますと、Bing Search APIの画面が出ます。ここでトランザクションの残りを確認する事も出来ます。
  4. ここでトランザクションが消費されます。画面上のTextBoxに検索したい単語を入れ、ComboBoxから「Search」を選択し、GOをクリックします。 BingSearchFirst.png
  5. 暫くすると結果が以下のように表示されます。 BingSearchResult.PNG
  6. 青くURLが表示されていると思いますので、そこをクリックすると以下のように画像が出ます。 BingSearchPic.PNG
  7. 元の検索結果に戻りたい場合はComboBoxから「Back」を選んでGOをクリックして下さい。Backで最後に見た結果の画面に戻る事ができます(BACKではトランザクションは消費されません)
  8. ちなみに検索結果のHTMLはCuiHelperContentsフォルダにbing(数字).htmlとして作成されますので、後から見ることが可能です。
  9. 更にBingImageSearch.exeのあるフォルダにはResourcesフォルダがあるかと思います。その中には(検索単語)_(数字).json という名前のJSONファイルが以下のような内容で作成されています。
{"data":[
{"id":1, "url":"http://pronama.azurewebsites.net/wp-content/uploads/2013/08/sato.png"},
{"id":2, "url":"http://i1.wp.com/pronama.azurewebsites.net/wp-content/uploads/2015/09/2015-09-10_2048x1280_buildinsider_2.png?fit=1200%2C1200"},
{"id":3, "url":"http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-71-33-metablogapi/2021.image_5F00_2F586C08.png"},
  // :  以下続きます。

10.ここでトランザクションが消費されます。51枚目以降が欲しければ、ComboBoxからNextをサーチすれば、続いて検索します。必要ならば繰り返して下さい。これは次にSearchを選択するまで続けることが出来ます。
11.複数回繰り返した後、例えば60枚目の確認がしたい場合は下図のようにTextBoxに数値を入れてENTERキーを押します。
BingSearchSelect.PNG
12.このように出てきます(実際にはTOP画面が出ます。これはスクロールしたのをキャプチャしてます)この操作ではトランザクションは消費されません。
Bing60list.PNG
13.ここでトランザクションが消費されます。別のキーワードで画像を検索する際には、TextBoxに再び検索したい単語を入れて「Seach」を選択してください。
14.後は上記の操作を必要なだけ繰り返す感じです。また、「HOME」を選択すると最初のAPIの画面に戻ります。

注意が必要な事として、例えば「プロ生ちゃん」で200枚検索した後に「くいなちゃん」で検索しますと、内部情報をクリアして、一覧画面(具体的にはhtml)を上書きしますので、プロ生ちゃんの一覧画面を見る事が出来なくなります。これに対してJSONファイルは検索単語を変更しても元のデータが消える事はありません。但し同じ単語で再検索した場合は上書きされます。

Bing関係のコードは?

SearchApplication.cs辺りを見てもらいますと、BingのAPI使った処理が記述されています。今はJSONで結果出力していますが、CSVに変えるのとかもここで割合簡単に出来るかと思います。

ライセンス

以下使わせて戴きました。素晴らしいソフトウェアを提供して下さり、ありがとうございます。

以上です。

GDaigo
リストラと日々戦いながら慣れない言語で遊んでいます。当然ですがアイコンみたいなイケメンではないです。Qiitaは自分向けの備忘とかリファレンス置き場みたいな感じで使わせてもらってます。
http://gdaigo.blog.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away