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スクレイピングのフリーソフトも出てき始めていますし、プログラムを学んでもいたちごっこなのかなと思ったりもします。

「googleで検索結果5件を表示」これがwebスクレイピング?

検索結果を自動で表示するコード


import requests, sys, webbrowser, bs4

print('googling...') #ダウンロード中
res = requests.get('https://www.google.co.jp/search?q=' + ' '.join(sys.argv[1:]))
res.raise_for_status()

soup = bs4.BeautifulSoup(res.text)
link_elems = soup.select('.r a')

num_open = min(5, len(link_elems))
for i in range(num_open):
webbrowser.open('https://www.google.co.jp' + link_elems[i].get('href'))

「退屈なことはpythonにやらせよう」もついにwebスクレイピングの章まできました。あまり驚きはないスクリプトですが、嬉しい人にとっては嬉しいかもしれないです。このスクリプトはコマンドライン引数というのを使いますので、これを知らないといけません。本見たほうがはやいので気になったら買ってください。

requests.get()

webページをダウンロードします。join(sys.argv[1])はプログラマーが任意で入力する引数です。これがコマンドライン引数ですが、これは本を読んだほうがたぶんはやいです。インターネットにも情報はあるかもしれませんが、理解するまでにおそらく時間がかかります。

raise_for_status()

ダウンロードが成功すれば、何もしないが、失敗すればエラーをおこす。

bs4.BeautifulSoup(res.text)

ダウンロードしたwebページのhtmlをBeautifulSoup()に渡す。→ビューティフルオブジェクトができる
→select()関数が使えるようになる。

.select(‘.r a’)

class ’r’ のaタグの部分をselect()としてリストにする。(html,cssの知識が若干いる)

min()

最小値を返す。検索結果が5件未満であれば、5よりも小さくなるということ。

.get(‘href’)

get()関数にhtmlの属性名を渡すと、属性値を返す。webbrowser.open()によって、検索結果のリンクが開かれていくことになります。
最後のhrefの部分をherfと間違えて記述してしまい、気づくのに時間がかかってしまいました。

webスクレイピングとは呼べないような簡単なスクリプトではありますが、覚えることが多いと感じるかもしれないです。しかしこれはもはや、覚えるというよりも慣れに近い部分があると思います。分からなかったらその都度本で確認する。htmlやcssも関連してきますし、ちょっとハードルが高い気がしなくもないです。抑えるべきポイントは数点かもしれませんが、それでも少し難しく感じます。