Python
Python3
BeautifulSoup
Webスクレイピング

Bing Wallpaper Archive 上で公開されている風景写真を網羅的にダウンロードするツールの開発


1. はじめに

 Bing Wallpaper Archive では,世界各国の高品質な風景写真が公開されており,無料でダウンロードすることが可能である。2009 年 5 月から更新されており,執筆時点(2018/12/16)で約 3,000 枚の風景写真が公開されている。これらの風景写真を手動でダウンロードするのは膨大な時間が必要になる。そこで,Bing Wallpaper Archive 上で公開されている風景写真を網羅的にダウンロードするツールを開発する。

 続く 2 章では,作業を行う環境について記述する。3 章では,風景写真の URI を取得する方法について記述する。4 章では,風景写真をダウンロードする方法について記述する。5 章では,本記事のまとめを記述する。


2. 環境情報

 次章以降で行う作業は以下の環境下で行ったものである。


  • Beautiful Soup Ver.4.6.3

  • pip Ver.18.1

  • Python Ver.3.7.1

  • Linux Kernel Ver.4.19.8-arch1-1-ARCH


3. 風景写真の URI を取得する

 風景写真をダウンロードするためには,風景写真の URI を取得する必要がある。そこで,以下に記述する 2 つの手法を試みた。

 ① http://www.bing.com/HPImageArchive.aspx に対してリクエストパケットを送信することで風景写真の情報を取得する手法

 ② http://bingwallpaper.anerg.com に対して Web スクレイピングすることで風景写真の情報を取得する手法

 ① は XML や JSON などのデータフォーマットで風景写真のメタデータを取得することができるため,取得・加工が非常に容易に行える。しかし,新しい風景写真の情報は取得することができるが,古い風景写真の情報は取得することができなかったため ① は不適切である。

 ② が適切であるかを確かめるため,curl を用いて Bing Wallpaper Archive の HTML を解析した。解析結果の一部を抜粋して以下に示す。

$ curl http://bingwallpaper.anerg.com

(略)
<a href="http://cdn.nanxiongnandi.com/bing/YosemiteBridge_EN-US10544416282_1366x768.jpg" target="_blank" title="Open in new window"><img src="http://cdn.nanxiongnandi.com/bing/YosemiteBridge_EN-US10544416282_1366x768.jpg" alt="The Stoneman Bridge on the Merced River in Yosemite National Park (© Ron_Thomas/E+/Getty Images)(Bing United States)" width="100%" /></a><div class="panel-overlay"><p>The Stoneman Bridge on the Merced River in Yosemite National Park (© Ron_Thomas/E+/Getty Images)(Bing United States)</p></div>
(略)

 上記の実行結果より,風景写真の URI が埋め込まれていることが確認できる。そのため,② は適切であるということがわかる。そこで,本記事では ② のツールを開発していく。


4. 風景写真のダウンロードする

 Web スクレイピングを行うためには様々な方法が考えられるが,本記事では Python と,その外部ライブラリである Beautiful Soup を用いて Web スクレイピングを行う。風景写真をダウンロードする Python スクリプトと,その実行結果を以下に示す。

#!/bin/python3

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

from bs4 import BeautifulSoup
import urllib
import datetime

countryList = ['us', 'uk', 'au', 'jp', 'cn', 'nz', 'de', 'ca', 'fr']
yearList = range(2009, datetime.date.today().year + 1)
monthList = range(1, 13)
urlList = ['http://bingwallpaper.anerg.com/' + _countryList + '/' + str(_yearList) + str(_monthList).zfill(2) for _countryList in countryList for _yearList in yearList for _monthList in monthList] # http://bingwallpaper.anerg.com/[国名]/[日付]

for url in urlList:
html = urllib.request.urlopen(url)
bs = BeautifulSoup(html, "html.parser")
for i in bs.find_all("img")[1:]: # 配列の先頭には logo.gif が格納される
fn = i.get("src").replace("http://cdn.nanxiongnandi.com/bing/", "")
with open(fn, "wb") as f:
f.write(urllib.request.urlopen(i.get("src")).read())


5. まとめ

 本記事では,Bing Wallpaper Archive 上で公開されている風景写真を網羅的にダウンロードするツールの開発について記述してきた。しかし,本記事で開発したツールには以下のような課題が残っている。


  • キャッシュ機能が無いため,実行速度が遅い

  • シングルスレッドのため,処理速度が遅い

  • 同じ URI を複数回,参照している

 今後は,これらの課題に取り組んでいきたいと考えている。


参照情報