以前、Pythonのスクレイピングの練習で「田代まさし」の画像をYahoo!画像検索からスクレイピングするコードを紹介した。

おかげさまで、あまりに華のない画像が大量にPCへダウンロードされてしまったので、今回は心機一転し「有村架純」の画像をスクレイピングしてみた。

また、それに伴い前回のコードを少しバージョンアップし、複数ページにまたがっての画像検索、スクレイピングに対応できるようコードを改変したので、そちらも合わせて紹介していく。

事前準備:画像保存用のディレクトリを用意する

今回は作業ディレクトリ内に「img-kasumi」というディレクトリを用意した。

実際のコードは「main.py」に書いていくことにする。

Yahoo!画像検索のURLパラメータについて

スクレイピングを行うにあたり、まずは画像取得先のページのURLについて調べる必要がある。

今回はYahoo!画像検索を使うのだが、通常の画像検索だと以下のように一定の数に達したら続きの画像は「もっと見る」ボタンを押さないと読み込んでくれない。

ボタンをクリックして読み込んでもURLは変わらないので、この状態だとスクレイピングをしづらい。

そこでまずは検索画面を「簡易版」に変更しておく必要がある。
検索画面上部に「簡易版へ切り替え」というリンクがあるので、ここで検索画面の切り替えを行う。

こうすることで1ページにつき20枚の画像が表示され、以降の画像は以下のとおりページ送りのリンクで、別のURLとして読み込むことができる。

ちなみに簡易版のURLパラメータの構成は次のとおりだ。

https://search.yahoo.co.jp/image/search?p={検索クエリ}&ei=UTF-8&b={ページ先頭に表示する画像番号}

スクレイピング用コード全文

スクレイピングするページのURL構成がわかれば後はコードを書くだけだ。

まずは全文を一気に紹介しよう。

from bs4 import BeautifulSoup
import urllib.request, urllib.error, urllib.parse

keyword = '有村架純'
max_page = 3 # ページ数(20枚/ページ)
dst_path = './img-kasumi/'

headers = {
	"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0",
}

cnt = 1
for i in range(max_page):
	cnt += 20
	url = 'https://search.yahoo.co.jp/image/search?p={}&ei=UTF-8&b={}'.format(urllib.parse.quote(keyword), cnt)

	req = urllib.request.Request(url=url, headers=headers)
	res = urllib.request.urlopen(req)
	soup = BeautifulSoup(res)

	div = soup.find('div', id='gridlist')
	imgs = div.find_all('img')

	for j in range(len(imgs)):
		img = imgs[j]['src']
		tmp = urllib.request.urlopen(img)
		data = tmp.read()

		file_name = dst_path + 'page' + str(i+1) + '_img' + str(j+1) + '.jpg'

		with open(file_name, 'wb') as save_img:
			save_img.write(data)

基本的には前回の「田代まさしスクレイピング」と、ほぼ同じコードでスクレイピングを行っているので、詳しいコードの解説は割愛する。

ただ、今回は取得するページ単位でfor文を回しているため、100枚でも200枚でも大量の画像をスクレイピングできるようになった。

このコードを実行すると、ページ番号・画像番号(1〜20)が名付けられた画像ファイルが「img-kasumi」ディレクトリに一括ダウンロードされる。

まとめ

PythonのBeautifulSoupを使えば、こうしたスクレイピング処理を短時間で書くことができる。

今後はスクレイピングにより取得した大量のデータを使って、何か機械学習のモデルを構築するところまで学んでいこうと思う。