Python初心者のWebコーダーが書籍「退屈なことはPythonにやらせよう」に触発されて、退屈なことをPythonにやらせるまでの記録です。
今回は「Webスクレイピング」という内容に関連してWeb技術について、これまで曖昧な理解のまま過ごしてしまった自戒の念を込めて、初歩的なところを蛇足気味に書いています。
※作業環境
- OS:macOS
- python:3.6.5
今回の退屈なこと
Webページに列挙されている特定の情報を取得し、出力する。
今回はこのページから、国の首都名を1行ずつ取得し出力する。
pythonにやらせること
- 1.リクエストとレスポンス(HTTPクライアント)
- 2.Webページから首都名の要素を取得し、出力
1.リクエストとレスポンス(HTTPクライアント)
今回はブラウザがやっている、サーバーへのリクエスト送信とレスポンス受信という「HTTPクライアント」をPythonにやらせる。
準備編 HTTPクライアントを用意する
HTTPクライアントを作成するにあたってはPythonに元から付属の「urllib」を利用する。
urlをリクエストし、返ってきたレスポンスを読む処理を作成する。
import urllib.request,urllib.error
url = 'https://scrapethissite.com/pages/simple/'
request = urllib.request.Request(url=url)
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as e:
print('HTTPError: {}'.format(e.code))
except urllib.error.URLError as e:
print('URLError: {}'.format(e.reason))
else:
print(response.read())
実行後、HTTPErrorエラーとなってしまう。
HTTP の 403 Forbidden クライアントエラーレスポンスコードは、サーバーがリクエストを理解したものの、認証が拒否されたことを示します。
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/403
HTTPError: 403
ユーザーエージェント情報の設定
いくつかの web サイト [1] はプログラムからブラウズされることを嫌っていたり、....デフォルトでは urllib は自身の情報を Python-urllib/x.y として扱います... これによって web サイト側が混乱したり、動作しないかもしれません。
https://docs.python.org/ja/3/howto/urllib2.html#headers
403 のレスポンスが返ってきた理由は、ブラウザとしてリクエストしていなかった事が考えられる。プログラムにブラウザのユーザーエージェントを記載して、ブラウザとして名乗らせる必要がある。
今回はリクエストのヘッダに記載する。
import urllib.request,urllib.error
url = 'https://scrapethissite.com/pages/simple/'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
headers = {'User-Agent': user_agent}
request = urllib.request.Request(
url=url,
headers=headers
)
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as e:
print('HTTPError: {}'.format(e.code))
except urllib.error.URLError as e:
print('URLError: {}'.format(e.reason))
else:
print(response.read())
実行後、コンソールにhtmlのソースが出力される。
2.Webページから首都名の要素を取得し、出力
サーバーからWebページをリクエストし、レスポンスを受ける、というHTTPクライアントの役割を果たせるようになったので、次はHTMLから必要な部分だけを取り出す処理を作成する。
HTMLページから情報を抽出するモジュール「beautifulsoup4」を利用する。
pip install beautifulsoup4
公式Docを参考に、htmlから必要な要素を取得し、テキストだけ取り出す処理を作成。
import urllib.request,urllib.error
from bs4 import BeautifulSoup
url = 'https://scrapethissite.com/pages/simple/'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)'
headers = {'User-Agent': user_agent}
request = urllib.request.Request(
url=url,
headers=headers
)
try:
response = urllib.request.urlopen(request)
except urllib.error.HTTPError as e:
print('HTTPError: {}'.format(e.code))
except urllib.error.URLError as e:
print('URLError: {}'.format(e.reason))
else:
for term in BeautifulSoup(response,'html.parser').find_all('span',class_='country-capital'):
print(term.get_text())
実行後、コンソールに首都名が出力される。
$ python webscraping.py
Andorra la Vella
Abu Dhabi
Kabul
St. John's
The Valley
Tirana
Yerevan
Luanda
…
目的を達成したので、今回はここで終了です。
テキストファイルやExcelに出力したり、googleSpreadSheetに連携出来たりするととても便利ですが、また今度やってみます。
今回作成したソースコードはこちら。
https://github.com/hoger-san/automate_tbs_with_python