前回、アンジュの画像をDLしましたが、
https://qiita.com/helloworld2/items/6008d5408a33dfe1a2a8
結局取れたのはサムネイルだったし、それじゃショボいので、いろいろがんばってグーグル画像検索の元イメージをスクレイピングしようとしたんですが、非常に困難だということがわかりました。
ということで、若干敗北感もありますが、スクレイピングではなく画像DLの自動化に方針を切り替えてトライしてみます。
sleniumというブラウザ操作を自動化する便利ツールがあり、(当然のように)pythonラッパーも提供されているのでpythonで実装します。
やったこと
yahooの画像検索からアンジュの画像を150枚DL。
yahoo画像検索はグーグル検索画面と違って、フォトプレーヤ的な機能が実装されています。これをseleniumで叩くと、良い感じに検索結果画像を閲覧していくことが出来ます。
コードのメイン処理
picker = YahooImagePicker('アンジュ・カトリーナ', 150)
picker.jump()
for i, u in enumerate(picker.image_urls()):
r = requests.get(u)
with open(os.path.join(IMAGE_FOLDER, 'ange_{}.jpg'.format(i)), 'wb') as f:
f.write(r.content)
イメージピッカーのインスタンス生成(キーワード「アンジュ」、枚数=150)して、最初の画像イメージまでジャンプします。
後は画像DL=>次の画像へジャンプ=>画像DLの繰り返しです。ピッカーのimage_urlsメソッドはyield実装してあるので、指定された枚数分、毎回画像URLを返します。
ピッカークラス実装
class YahooImagePicker:
def __init__(self, keyword, count):
self._keyword = keyword
self._count = count
self._driver = webdriver.Chrome()
def jump(self):
# yahooページへ遷移
self._driver.get('http://yahoo.co.jp')
# 検索キーワード入力/実行
query = self._driver.find_element_by_name('p')
query.send_keys(self._keyword)
query.submit()
time.sleep(3)
# 画像リンクページへ遷移
self._driver.find_element_by_link_text('画像').click()
time.sleep(3)
# 最初の画像イメージをクリック
self._driver.find_element_by_tag_name('img').click()
time.sleep(3)
def image_urls(self):
while True:
# イメージリンク取得
c = self._driver.find_element_by_id('imgContainer')
c.find_element_by_id('imgInner')
i = c.find_element_by_id('imgInner')
i.find_element_by_tag_name('img')
i2 = i.find_element_by_tag_name('img')
i2.get_attribute('src')
u = i2.get_attribute('src')
# 次のイメージへ移動
self._driver.find_element_by_class_name('next').click()
time.sleep(3)
print('count = {}'.format(self._count))
self._count -= 1
if self._count > 0:
yield u
else:
return u
コンストラクタでchromeのドライバを生成し、jumpメソッドで最初の画像ページまでジャンプ、image_urlsで画像URLを取得します。ところどころに入っているtime.sleepは、seleniumのwait機能を使ってかしこくつくるべきだし、イメージリンクの抽出はもっと少ない行で可能だと思いますが、とりあえず動いたのでよしとします。
大量にアンジュの画像が集まってきます。seleniumすばらしい。
いにゅいの画像が混ざったりしてるのはグーグルAIの限界でしょうか。
いくつかDLに失敗してるファイルもあります。これらはtime.sleepというベタ制御のせい・・だと思いますが、どうだろう。
全コードは以下。
https://github.com/mogrodown/hobby_python/blob/master/ange_picker.py