Google画像検索について

タグの編集
投稿者 パル36  (学生) 投稿日時 2011/8/6 13:03:21
こんにちは。今回も画像検索について質問させてください。

Googleの画像検索で例えば「テスト」と検索します。
真ん中に画像一覧が表示されるのですが、この表示されている画像のアドレスを取得するのはどうすれば良いのでしょうか。

現在、コードでは下のように取得しています。
Dim Body As HtmlElement = BrowserMain.Document.Body 'BrowserMain(WebBrowser)からソースを取得 
Dim Images As HtmlElementCollection = Body.GetElementsByTagName("img"'Img要素を取得 

        For Each Img As HtmlElement In Images '取得したImg要素を1つずつ繰り返す。 
            Dim src As String = Img.GetAttribute("src"'src属性(アドレス)を代入 
            Dim ext As String = Path.GetExtension(src) '変数srcから拡張子だけを取得して代入 

            If src.Length = 0 Then '文字数が0のとき(アドレスがないとき) 
                lstFile.Items.Remove(src) 'リストからアイテムを削除  
            Else
                lstFile.Items.Add(src) '文字があれば追加 
            End If

'別のリスト(lstExt)に変数extの値を追加します。 
            If Not lstExt.Items.Contains(ext) Then '別のリストに拡張子がないなら追加 
                lstExt.Items.Add(ext, True)
            End If
        Next



(コメントを今つけたので、見にくいかもしれません)

これで取得されるのですが、アドレスがエンコードされたようにアルファベットだらけになります。
(例)http://t1.gstatic.com/images?q=tbn:ANd9GcQdhaJCva2PkXBwUfnJK_zvu8LtNP0n3Y8e_ObbQ2t6VSM3Iq2gpg
どうしたらもとのアドレスが取得できるのでしょうか。

ちなみにそのへんなアドレスでも、画像を表示することができます。

宜しくお願いします。
投稿者 パル36  (中学生) 投稿日時 2011/8/6 13:04:34
すみません。身分は学生ではなく、中学生です。
投稿者 通りすがり  (社会人) 投稿日時 2011/8/6 23:37:18
こんばんは。

質問ですが、lstFileに追加される文字列は
http://t1.gstatic.com/images?q=tbn:ANd9GcQdhaJCva2PkXBwUfnJK_zvu8LtNP0n3Y8e_ObbQ2t6VSM3Iq2gpg
ではなく、
data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5Ojf/2wBDAQoKCg0MDRoPDxo3JR8lNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzf/wAARCACMAIwDASIAAh・・・
という文字列ではありませんか?

IE9 VS2010 proではそうなります。


そうだという前提で話しますが、
まず
http://t1.gstatic.com/images?q=tbn:ANd9GcQdhaJCva2PkXBwUfnJK_zvu8LtNP0n3Y8e_ObbQ2t6VSM3Iq2gpg
は、グーグルの画像キャッシュのアドレスです。
data:image/jpg;base64,/9j/4AAQSkZJ・・・
はMIME Base64 エンコード文字列というものです(カンマまでは画像のbase64文字列ですよということを表しています)。画像のようなバイナリデータを文字列として変換してHTML(ハイパーテキスト)でやり取りする形式です。

で、これをImageに戻してあげるには以下のようにすればいいと思います。
If src.StartsWith("data"Then
    ' base64からバイナリ配列に変換、それをメモリストリームとして使用する 
    Dim ms As New MemoryStream(Convert.FromBase64String(src.Split(CChar(","))(1)))
    ' ストリームからImageを作成する 
    Dim img As Image = Image.FromStream(ms)
    ' ストリームを閉じる 
    ms.Close()
Else
    lstFile.Items.Add(src) '文字があれば追加  
End If

エラー処理とかは書いてません。

なお、http:// で始まる画像のアドレスが取得できているのであれば、
WebClientクラスを使うと似たような感じで取得できたような記憶があります。
※ System.Webの参照設定を追加する必要があったかも。
投稿者 YuO  (社会人) 投稿日時 2011/8/7 02:26:00
下手に自動化すると,Googleの利用規約に抵触するので注意してください。
まぁ,ユーザーが検索文字列入力をしてサイトを表示すれば,大丈夫だと思いますが。
ちなみに,問題になりそうなのは
http://www.google.co.jp/accounts/TOS
の5.3です。


とはいえ,代替案をだせないのも確かなのですが……
Google Image Search APIはDeprecatedですし……
http://code.google.com/apis/imagesearch/
投稿者 パル36  (中学生) 投稿日時 2011/8/7 09:58:19
通りすがりさん、Yuoさん ご返答ありがとうございます。

例のアドレスはすみません。ちがうリスト項目でした。
おっしゃるとおり、dataからはじまるアドレスです。

イメージをバイナリで保存する方法は知っていましたが、まさかHTMLで使用されているなんて気づきませんでした。

>で、これをImageに戻してあげるには以下のようにすればいいと思います。
if文がよくわかりません。

アドレスがdataから始まるときは、imgに画像を保存して、ちがうときはリストに追加するんですよね。
elseのように画像をアドレス化して保存するにはどういった手順を踏めば良いのでしょうか。
つまり、dataの画像もリストに追加したいということです。

言葉だけで構いません。

>下手に自動化すると,Googleの利用規約に抵触するので注意してください。
利用規約を確認していませんでした。
ソフトウェアでは、表示されている画像をソースから検索しリストアップするものです。
もちろん、ダウンロードも可能です。

自動化というよりは、ダウンロードのほうが厄介かもしれません;
Readmeかなにかに「全て自己責任で」を追加しておきます。

ご指摘ありがとうございました。
投稿者 通りすがり  (社会人) 投稿日時 2011/8/7 18:06:29
非営利であれば大丈夫だとは思いますが
> Readmeかなにかに「全て自己責任で」を追加しておきます。
だと、ちょっと弱いかもしれませんね。

とりあえず個人の勉強目的という事で回答します。

まず、dataで始まる文字列はすでにURLを含んでいないので、そこからURLをたどるのは無理です。

ざっとソース見た感じだと
img要素にdata-srcという属性にgoogleのイメージキャッシュのアドレスがあり、それをオンロード時に展開しているようですので、同じようにしてその属性からアドレスを取り出せばgoogleの画像検索ページで出力されている画像のアドレスは取得可能と思います。
ただし、これはgoogleから仕様として公開されているものではないので(勝手にソース見て勝手にそう思い込んだだけなので)googleの気分で変更される可能性があります。確実なやり方ではありません。

本来どこのどういうURLの画像だったかも細かくたどれば手に入るかもしれませんが
1.ページを経由せず直接画像をリンクされてダウンロードされるという行為は公開者からは好まれない。
2.画像のリンク先が安全とは限らない。
3.本来の公開者のサーバ負荷となり、「Google画像検索について」からは逸脱する。
4.(私が)そこまで解析する気もない。
などの理由から控えさせて頂きます。
投稿者 (削除されました)  () 投稿日時 2011/8/7 19:26:59
(削除されました)