Python3で、urllibとBeautifulSoupを使ってWebページを読み込む


このエントリーをはてなブックマークに追加

Python3で、urllibとBeautifulSoupを使ってWebページを読み込む方法についてまとめます。

urllibを使ったページの取得

まず、Python3の標準ライブラリであるurllibを使ってページを取得します。Python2から書き方が変わっているので注意が必要です。

import urllib.request
url = 'http://www.rekibun.or.jp/grutto/museum2015.html'
response = urllib.request.urlopen(url)
data = response.read()

ここで、response.read()はbytesオブジェクトを返します。以下はその抜粋です。日本語がバイト列として表現されてしまっています。

b'<!DOCTYPE html> (中略)  <title>\x8c\xf6\x89v\x8d\xe0\x92c\x96@\x90l\x93\x8c\x8b\x9e\x93s\x97\xf0\x8ej\x95\xb6\x89\xbb\x8d\xe0\x92c</title> (中略)'

以下では、バイト列を適切にデコードする方法を2つご紹介します。

方法1: urllibで明示的にデコード

Webページのエンコード方式がわかっている場合は、そのエンコード方式を明示的に指定してデコード可能です。例えば、WebページがShift_Jisで記述されていることが既知な場合、

import urllib.request
url = 'http://www.rekibun.or.jp/grutto/museum2015.html'
response = urllib.request.urlopen(url)
data = response.read()
decoded_data = data.decode('shift_jis')

とすると、decoded_dataには

'(中略)<title>公益財団法人東京都歴史文化財団</title>(中略)'

と、デコードされた文字列が入ります。

方法1の欠点は、Webページごとに適切なエンコード方式を見つけてデコードしないといけないことです。

方法2: Beautiful Soup 4を使ってエンコード方式を自動推測してデコード

方法2では、サードパーティのライブラリであるBeautiful Soup 4(以下bs4)を使います。bs4はWebページのパースを行うのによく使うライブラリで、Webページのエンコード方式を推測して自動でデコードすることにも使えます。

pipを使う場合、以下でインストールできます。

pip install beautifulsoup4

早速bs4を用いてWebページをデコードしてみます。

import urllib.request
import bs4
url = 'http://www.rekibun.or.jp/grutto/museum2015.html'
soup = bs4.BeautifulSoup(urllib.request.urlopen(url).read())

ここで、soup.original_encoding には推測したエンコード方式が入っています。この場合は

shift_jis

と正しく推測できています。

デコードした文字列を得るには

str(soup)

とします。しかしながら、もし目的がWebページの文字列化そのものではなく、Webページをパースして情報を得ることであるならば、bs4の多彩な機能を使ってパースまでやってしまうほうがよいでしょう。