5
7

More than 5 years have passed since last update.

Python初心者が退屈なことをPythonにやらせる Webスクレイピング編

Last updated at Posted at 2019-05-05

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をリクエストし、返ってきたレスポンスを読む処理を作成する。

webscraping.py
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 のレスポンスが返ってきた理由は、ブラウザとしてリクエストしていなかった事が考えられる。プログラムにブラウザのユーザーエージェントを記載して、ブラウザとして名乗らせる必要がある。
今回はリクエストのヘッダに記載する。

webscraping.py
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」を利用する。

bash/zsh
pip install beautifulsoup4

公式Docを参考に、htmlから必要な要素を取得し、テキストだけ取り出す処理を作成。

webscraping.py
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())

実行後、コンソールに首都名が出力される。

bash/zsh
$ 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

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7