Pythonで機械学習用の画像を取得する


## <a id="index" href="#index">目次</a>
* [自己紹介](#section1)
* [キーワードに対する画像取得byスクレイピング](#section2)
  - 画像取得って？
  - 活用例
  - コード作成
  - 結果確認
* [おわりに](#section3)

本日は、webスクレイピングを使った画像収集についての記事を投稿しようと思います。
## 実行環境
　- Mac OS X (Windowsの方はすみません...)
　- Python 3.8以上

# <a id="section1" href="#section1">1.自己紹介</a>  
こんにちは。sgswといいます。今大学生で、好きな言語はPythonです。
![Python](https://www.python.org/static/img/python-logo@2x.png)
[公式サイトはこちら](https://www.python.org)
Pythonにおける、実際の活用例をアウトプットしてゆきたいと思います！

<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>
   

# <a id="section2" href="#section2">2.キーワードに関する画像取得</a>
- スクレイピングによる画像取得<br>

　スクレイピングとは、wikipediaによると以下のことを指します。
>ウェブスクレイピング（英: Web scraping）とは、ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。ウェブ・クローラー[1]あるいはウェブ・スパイダー[2]とも呼ばれる。 通常このようなソフトウェアプログラムは低レベルのHTTPを実装することで、もしくはウェブブラウザを埋め込むことによって、WWWのコンテンツを取得する。

ざっくり言うと、コンピュータが人間の代わりにブラウジングして情報を取ってきてくれる感じです。__何度も同じような作業__をするときに使えそうですね。

今回では、これを __画像検索&画像取得__に応用してみたいと思います。
***
- 活用例

画像検索&画像取得をコンピュータにやらせて何が嬉しいのでしょうか？

>そもそも似たような画像集めまくって使いそうなことある？

こんな声も聞こえてきそうですが、__あります。__

__機械学習です。__<br>

ここでは述べませんが、機械学習では何かの特徴量を機械につかんでもらうために、大量の情報を必要とします。<br>
[※機械学習について知りたい方は、こちらのwebサイトなどを参考にしてください.](https://www.codexa.net/cnn-mnist-keras-beginner/)

画像認識を機械学習のテーマとしたとき、同じグループの画像を何個も集めることが必要になってきます。

こういったときに同じ種類の画像をコンピュータに取得してもらえたらとても楽ですよね。

何より

「保存先を間違えた、統一性のない変な名前で保存しちゃった...etc」<br>
とかいった心配をしなくて済みます。


Pythonを使って、Google画像検索で同じテーマの画像をスクレイピングすることを以下で行っていきましょう。

***
- コーディング例

完成コードは以下のようになります。初めの方に必要なライブラリーは列挙してます。

```python

import bs4
import requests
import re
import urllib
import os

header = {
    'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36"}


def text_search(word_list):
    url_lists = []
    assert 1 <= len(word_list) <= 4
    params = {'q': " ".join(word_list), 'tbm': 'isch'}
    r = requests.get("https://www.google.co.jp/search", params=params)
    url_lists.append(r.url)
    return url_lists


def get_soup(url, header):
    return bs4.BeautifulSoup(urllib.request.urlopen(urllib.request.Request(url, headers=header)), 'html.parser')


def main():
    key_ward = input("put key_wards! > ")
    words = [key_ward]
    url_list = text_search(words)
    res = set([])
    for i, url in enumerate(url_list):
        bs = get_soup(url=url, header=header)

        for a in bs.find_all("img", {"data-src": re.compile("^(https://).*")}):
            if "data-src" in a.attrs:
                x = a.attrs["data-src"]
                if not x in res:
                    res.add(x)

    res = list(res)

    URLS = list(res)
    print("Okay,ready to save images!")
    path = ""
    while path == "":
        path = input("put the path to save>")
        if path != "":
            if os.path.exists(path):
                print("you are going to save images here -> {}\n".format(path))
                command = input("put y if you are OK otherwise put another.")
                if command == "y":
                    continue
                else:
                    path = ""
            else:
                print("Oops,that path does not seem to exists!")
                path = ""
        else:
            path = ""
    print("whole images: {}".format(len(URLS)))
    print("saving images...!")
    N = len(URLS)
    for i in range(N):
        file_name = "{}/{}.jpg".format(path, i + 1)
        url = URLS[i]
        response = requests.get(url)
        image = response.content
        with open(file_name, "wb") as f:
            f.write(image)
        print("{}/{} has done !".format(i + 1, N))
    print("ALL COMPLETE!")
    return


if __name__ == "__main__":
    main()
```


実行の仕方は簡単です。コードを保存したところに移動して、Pythonファイルを実行するだけです。ファイル名をscraping.pyとすると、以下の通りです。

```python
  > python scraping.py
```
実行すると、標準入力に従ってゆくことで、打ち込んだkeywardに関連した画像を100枚ほど取得できます。


    put key_wards! >dog
    Okay,ready to save images! 
    #保存する場所を決定します。

    put the path to save>./dog_images
    you are going to save images here >./dog_images

    #保存場所に誤りがなければyを押します。それ以外はもう一度pathを指定します。
    put y if you are OK otherwise put another >y
    whole images: 92
    saving images...!

    1/92 has done !
    2/92 has done !
    3/92 has done !
    4/92 has done !
    ...   
    94/95 has done !
    95/95 has done !
    ALL COMPLETE!

基本的な使い方は以下の通りです。
ここで実際に収集できる画像は100枚程度なので、機械学習で使うには物足りない感じはありますが、その画像の水増しは画像の線形変換などを用いるのが良いでしょう。<br>

一度に収集できる画像の枚数をもう少し増やすこともしたいので、何か良いアイデアがあれば教えていただきたいです。



<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>

# <a id="section2" href="#section2">3.おわりに</a>
Pythonにおける画像取得は難しくないことがお分かりいただけたのではないでしょうか？<br>
「今までPythonを学んできたけれども、いまいち具体的な活用方法がわからない...。」<br>
という人にきっかけを与える手助けになれたら幸いです。<br/>

それでは、よきコーディングライフを！
<p class="ec__link-index"><a href="#index">[↑ 目次へ]</a></p>