no-image

pythonで画像をダウンロードしまくる?【人間のほうが能力が低い。】 

漫画ページのコミックをダウンロードするPythonコード


import requests, os, bs4

url = 'http://xkcd.com'
os.makedirs('xkcd', exist_ok=True)

while not url.endswith('#'):
#ページをダウンロードする
print('ページをダウンロード中 {}...'.format(url))
res = requests.get(url)
res.raise_for_status()

soup = bs4.BeautifulSoup(res.text)

#コミック画像のURLを見つける
#id="comic"の imgタグ
comic_elem = soup.select('#comic img')
if comic_elem == []:
print('コミック画像が見つかりませんでした')
else:
comic_url = 'http:' + comic_elem[0].get('src')
#画像をダウンロードする
print('画像をダウンロード中 {}...'.format(comic_url))
res = requests.get(comic_url)
res.raise_for_status()

#画像を./xkcdに保存する

#prevボタンのurlを取得する
image_file = open(os.path.join('xkcd', os.path.basename(comic_url)), 'wb')
for chunk in res.iter_content(100000):
image_file.write(chunk)
image_file.close()


#prevボタンのURLを取得する
prev_link = soup.select('a[rel="prev"]')[0]
url = 'http://xkcd.com' + prev_link.get('href')

print('完了')

1行1行追っていかないと理解できないです。短いスクリプトならいいですが、これよりもっと長いスクリプトだとどうなるのだろうかと思ったりします。このスクリプトではじめてバックグラウンドで動いているという感覚が得られました。繰り返しでどんどん画像をとっていくので、はっきり言って怖いです。
条件がそろわないとプログラムは停止しませんので、やめたいときは自分で止める必要があります。

スクリプトの流れ

  1. importで必要なモジュールを読み込む
  2. os.makedirsでカレントディレクトリに新しいフォルダを作る。exist_ok=Trueは同名のフォルダが存在していたら例外をおこさない
  3. requests.get()で該当ページをダウンロード
  4. bs4.BSにurlを渡す
  5. soup.select()で id=” comic”のimgタグをセレクトしてリストにする
  6. リストがなかったらprint(‘コミックが見つかりませんでした ‘)
  7. リストがあったら、get(‘src’)でsrc属性から属性値を得るそれをhttp:と合体
  8. requests.get()で合体したurlをダウンロード
  9. open()関数内ではフォルダ名とurlのbasenameをjoinでつなげて、’wb’というバイナリ書き込みモードで開く
  10. forループでiter_content(100000)で100キロバイトにごとに書き込む。終わったら閉じる
  11. select() aタグのrel属性が”prev”のものをみつける。
  12. get(‘href’)でhrefの属性値とつなげる。→これがurlになる
  13. whileなのでこれを繰り返す。

for whileで段落がないので少々わかりにくいかもしれません。webスクレイピングはアイデア次第では色々なことができそうです。たぶんあんまり使わないと思うけど。

実際webスクレイピングのフリーソフトも出てき始めていますし、プログラムを学んでもいたちごっこなのかなと思ったりもします。