search
LoginSignup
7

More than 3 years have passed since last update.

posted at

updated at

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

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

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
What you can do with signing up
7