サイトに更新があるとそのサイトに行って自動で画像をダウンロードするスクリプトを過去に書いたので紹介.毎日のネットサーフィンをする中で機械的に収集する画像…なんとか自動化できないか…モジュールが充実するPythonやRSSを使うと自動化できるんじゃないか,と考え実装した. 使用言語はPython3. アクセスするサイトをjsonで指定する. サイトへのアクセスにはseleniumを使用. 完全な自動化(スクリプトを走らせるだけで画像が集まる状態)のために最初に必要なことは,対象のサイトの更新を知ること. そこで簡単な実装としてRSSを使ってサイトの更新を知るようにする.RSSにアクセスし,最新のURLが Pythonにはfeedparserというモジュールがあるので,これを使う. コードはこんな感じ. 画像のダウンロードはselenimのdriverと,driverから得られるhtmlをパースするBeautifulSoupの両方を使うことで行う.
BeautifulSoupはwebページ中,指定した属性の指定したパラメータの情報だけを抜き取れる. 今回であればダウンロード対象の画像URLはその画像ファイルネーム以外共通していることが予想されるので,その共通部分を正規表現としてフィルタする. 予想される共通部分はjsonの ダウンロードしたい複数の画像で共通するurlを正規表現としてパーサに渡すことで得られるタグ情報のリスト 最後に,次に走らせるときのためにjsonを更新する. これにより, バッチファイル等でコンピュータ起動時に実行されるように登録すれば便利. この記事を読んでいただいた方への創作の刺激となればいいと思う.私は起動時に走るようにしているが,更新がある度に自動的に全ての画像が保存されていくので選別に苦労している.次は個人の好みで選別できる判別器を作らなければ…完全自動化には時間がかかりそうである.はじめに
実装
サイトの指定
{
"SITE_NAME":{
"rss": "RSS_URL",
"prev_link": "VISITED_URL",
"tag_attributes": "^http://TAG_URL",
"split_char": "/"
}
}
プロパティ名
用途
SITE_NAME
複数のサイトへのアクセス時にサイトで区別するため
rss
サイトのRSSのURLを記述するため
prev_link
前回アクセスしたサイトのURLを記録するため
tag_attributes
画像に付与されているURLの共通部分
split_char
画像のファイルネームを決めるため
よく見るとプロパティ名が不適切なものがあるが…サイトへのアクセス
options = Options()
options.set_headless(True)
driver = webdriver.Chrome(chrome_options=options)
RSS
prev_link
と一致しなければ更新があるということ.feed_result = feedparser.parse(site_prop['rss'])
for entry in feed_result.entries:
if entry.link != site_prop['prev_link']:
print(entry.title)
download_images(site_prop, entry.link)
else:
break
if site_prop['prev_link'] != feed_result.entries[0].link:
site_prop['prev_link'] = feed_result.entries[0].link
site_prop
は直前でjsonをマップとして読み込んでいるもの.画像のダウンロード
tag_attributes
に記録.img_tags = soup.find_all('a', {'href':re.compile(_site_prop['tag_attributes'])})
img_tags
についてダウンロードしていく.for tag in img_tags:
img_url = tag.attrs['href']
word_list = tag.attrs['href'].split(_site_prop['split_char'])
res = requests.get(img_url)
with open('YOUR_DIR'+word_list[len(word_list) - 1], 'wb') as f:
f.write(res.content)
split_char
でURLをsplitし,最後の要素をファイルネームとして保存する.jsonの更新
prev_link
が更新されるので実行の度に同じURLを見なくて済む.with open('site_props.json', 'w') as target_file:
json.dump(json_dict,target_file)
target_file.close()
使い道
さいごに