TomoProgの技術書

底辺プログラマーが達人プログラマーになるまで

Python使ってYahoo画像検索の画像を自動で収集してみた

皆さん
こんにちは、こんばんは
TomoProgです。

記念すべき10記事目!!
頑張っていきましょう!!

今回はPythonを使ってYahoo画像検索の画像を自動で画像を収集してみようと思います。

指定したWebサイトのhtmlを取得する

まずはWebサイトのhtmlを取得してみたいと思います。
Pythonにはurllibという指定したURLに簡単にアクセスできるモジュールが備わっています。

import urllib.request

request = urllib.request.urlopen(url)
html = request.read()

urllib.request.urlopenを使うと引数に指定したURLを開きます。
あとは開いたURLの情報をreadで読み取るだけです。

実際にgoogle検索のトップページのhtmlを取得してみます。

#-*- coding:utf-8 -*-

import urllib.request

url = "https://www.google.co.jp"
request = urllib.request.urlopen(url)
html = request.read()

print(html)
実行結果:
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="\x90\xa2\x8aE\x92\・・・
(長いので省略)

こんな感じで指定したURLのhtmlを簡単に取得出来ます。

htmlを読めるようにデコードする

htmlを取得したのは良いものの、request.readの戻り値をそのまま出力すると何らかの文字コードエンコーディングされたまま取得してしまうので、謎の文字(上の実行結果の\x90\xa2\x8aEなど)が出力されてしまいます。

これでは何が書いてあるのかわからないので、取得したhtmlの文字コードを特定してデコードしましょう。

文字コードを特定するには様々な文字コードで片っ端からデコードしていきます。

#-*- coding:utf-8 -*-

import urllib.request

url = "https://www.google.co.jp"
request = urllib.request.urlopen(url)
html = request.read()

encoding_list = ["utf-8", "utf_8", "euc_jp", 
                    "euc_jis_2004", "euc_jisx0213", "shift_jis",
                    "shift_jis_2004","shift_jisx0213", "iso2022jp",
                     "iso2022_jp_1", "iso2022_jp_2", "iso2022_jp_3",
                    "iso2022_jp_ext","latin_1", "ascii"]

for enc in encoding_list:
    try:
        html.decode(enc)
        break
    except:
        enc = None

print(enc)
if enc != None:
    print(html.decode(enc))
実行結果:
shift_jis
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta content="世界中のあらゆる・・・
(長いので省略)

先ほどの謎の文字が日本語になりましたね!!
(これ以外のやり方を知っている人がいたら是非教えて下さい!!)

Yahoo画像検索のhtmlを見てみる

ここまでで指定したサイトのhtmlを手に入れる術を身につけたので、実際にYahoo画像検索で欲しい画像を検索します。
CodeIQさんのプログラミング漫画「走れ! コード学園」で検索!!
f:id:TomoProg:20160212235220j:plain

可愛い女の子がいっぱいですね!!

それはさておき、このサイトのhtmlをじっくり見てみるとどうやら画像がaタグのhref属性に書かれたURLに存在するようです。

<a href="http://ord.yahoo.co.jp/o/image/.../sample.jpg" target="imagewin">
(長いので途中省略)

このaタグのhref属性の中身だけを抽出できれば画像が取得出来そうです。

htmlからaタグのhref属性だけを抽出する

htmlを解析するモジュールはPythonにはいくつかありますが、今回はBeautifulSoupというモジュールを使用します。

BeautifulSoupは標準モジュールではないので、pipコマンドでインストールします。

$ pip install beautifulsoup4

これだけでBeautifulSoupを使用する準備は完了です。

実際にBeautifulSoupを使ってみます。

#-*- coding:utf-8 -*-

import bs4

html = """
        <html>
            <head>
                <body>
                    <a href="http://www.yahoo.co.jp">Yahoo!!</a>
                    <a href="https://www.google.co.jp">Google</a>
                    <p>こんにちは</p>
                </body>
            </head>
        </html>
        """

resources = []

# BeautifulSoupオブジェクトを作成
soup = bs4.BeautifulSoup(html)

# htmlのすべてのaタグの中のhref属性の内容を取得
for a_tag in soup.find_all("a"):
    href_str = a_tag.get("href")
    resources.append(href_str)

# hrefの内容を表示
for resource in resources:
    print(resource)
実行結果:
http://www.yahoo.co.jp
https://www.google.co.jp

BeautifulSoupを使う際はimport bs4を最初に書きます。
find_all("a")ですべてのaタグの内容を取得、get("href")でaタグの中のhrefの内容だけを取得出来ます。

これで画像ファイルのURLをすべて取得出来ました!!

URLからダウンロードする

あとは取得した画像ファイルのURLを開き、バイナリ形式でファイルに書き出すだけです。

#-*- coding:utf-8 -*-

import urllib.request

# 画像ファイルのURLを開く
# (urlに画像ファイルのURLを指定)
request = urllib.request.urlopen(url)

# ファイルをバイナリモードで開き、URLの内容を書き込み
# (file_nameに保存時のファイル名を指定)
f = open(file_name, "wb")
f.write(request.read())

# ファイルを閉じる
f.close()

実際に自動収集してみる

ここまで長い道のりでしたが、なんとか完成しました!!
実際に自動収集してみます!!
youtu.be

これでWebの画像も集め放題です!!
ソースはGitHubで公開しておきます。
それではまた。

GitHub
https://github.com/TomoProg/HatenaBlog/blob/master/python/web_crawler.py

Twitter
TomoProg (@TomoHelloxxx) | Twitter