PythonでWebスクレイピング

スクレイピング

スクレイピングというのはあれです。
Webのページから必要な情報を抜き出すっていう。アレです。

最近は情報を提供するようなサービスはWeb APIが実装されていることが多いのでJSONでもらってこれることも増えましたが
表示されているHTMLから必要な情報をもらってこざるを得ない場合が存在します。
そんな時はちょっとしたコードで効率よく情報収集したいものですね。

環境

ここではPython3.5を使います。今やWindowsでもMacでもAnacondaなんていう素敵な環境が存在しますので比較的導入が簡単ではないかと思います。

urllibの利用

from urllib.request import urlopen
html = urlopen("http://www.skyarch.net/")

たったこれだけでhttp://www.skyarch.net/の内容が変数htmlに取得できます。
変数htmlはhttp.client.HTTPResponseオブジェクトなので実際に値を取得するにはメソッドを用いて利用することになります。

>>> html.getcode()
200
>>> html.read()
b'<!doctype html>\n<!-- [if lt IE 8]><html class="ie ie7" lang="ja"><![endif]-->\n...

便利ですね。

とはいえ私はrequestsやらmechanizeやら使うことが多いですけど:)

BeautifulSoup4

取得が終われば後はパースをして情報にたどり着きましょう。
ページの取得だけが目的ならwgetでもcurlでももっと簡便な方法がありますし
BeautifulSoupのオブジェクトに取得したhtmlを渡すとHTMLドキュメントを自在に回遊することができるようになります。
たとえば下記でタイトルタグが取得できます。

bsObj = BeautifulSoup(html.read(), "html.parser")
print(bsObj.title)

実行結果

<title>ウェブサービスに最適なクラウドの運用 | スカイアーチネットワークス</title>

文字列だけが欲しいならば

print(bsObj.title.string)

とすれば良いです。

上記で”html.parser”という部分はパーサの指定です。過去のバージョンでは指定しなくても問題ありませんでしたけど現在は目的に応じたパーサを指定しないとワーニグがいっぱい出ます。

まとめるとこんなコードになります。

#! env python3
# -*- encode: utf-8 -*-
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.skyarch.net")
bsObj = BeautifulSoup(html.read(), "html.parser")
print(bsObj.title.string)

実践

さてここでスカイアーチさんのページから事例の一覧を持ってくるコードを考えてみましょう。
スカイアーチさんの事例は
http://www.skyarch.net/library/に存在することで広く知られています。
事例はhtmlの構造としてはざっくりとソースを見てみると下記のような構造ですね。

簡単な処理で処理をするにはsectionタグの中でh4タグを探せば良いみたいですね。ざっくり書くとこんなコードでしょうか。

#! env python3
# -*- encode: utf-8 -*-
from urllib.request import urlopen
from bs4 import BeautifulSoup
html = urlopen("http://www.skyarch.net/library/")
bsObj = BeautifulSoup(html.read(), "html.parser")
article = bsObj.body.find_all("section")
for jirei in article:
  for company in jirei.find_all('h4'):
    print(company.string)

実行結果

$ python3 sky.py
株式会社foo 様
株式会社bar 様
...

通常、実際のアプリケーションとしてのクオリティを上げるには、繋がらなかった際のエラーハンドリングや少々構造に変更があってもなんとか頑張るなどの処理が加わってきたりもしますが、この程度でもデータの収集としては十分に役立つと思います。

それでは良いPythonライフを。

投稿者プロフィール

えんじにあん
インフラ系のエンジニアです。
運用系のスクリプトを書いたり、オートメーションな世界に向かって日々精進しています。

1 個のコメント

  • コメントを残す

    メールアドレスが公開されることはありません。

    Time limit is exhausted. Please reload CAPTCHA.

    ABOUTこの記事をかいた人

    インフラ系のエンジニアです。 運用系のスクリプトを書いたり、オートメーションな世界に向かって日々精進しています。