クラスオブジェクトを使ってみよう-その1
記事の内容
この記事では、クラスオブジェクトの使用例を説明します。
オブジェクト指向プログラミング言語の良いところは、プログラムで定義されたクラスの中身がよくわかっていなくても、自分のプログラムに取り入れて簡単に再利用できることです。Pythonでは、あらゆる用途のクラスが公開されており、簡単に自分のプログラムに取り入れる方法が用意されています。
この記事と次の記事で、まずはクラスオブジェクトの使い方をしっかり押さえましょう。
前の記事でオブジェクトとは何かについて説明しました。オブジェクト指向プログラミングにおいて、オブジェクトは重要な概念です。「オブジェクトって何だろう?」という方は、先に前の記事を読むことをお勧めします。
***わからない用語があるときは索引ページへ***
1.urlopen関数の紹介
urlopen関数を使ってウェブコンテンツをダウンロードする例を紹介します。
urlopen関数は、Pythonの標準ライブラリで提供されている関数で、urllibパッケージの中のrequestモジュールで提供されています。
「クラスオブジェクトの使用例で関数の使い方?」と思われるかもしれませんが、そうではありません。urlopen関数は、HTTPResponseクラスのインスタンスを返します。サンプルプログラムurllib_ex1.pyは、HTTPResponseクラスの使い方も説明します。
HTTPResponseクラスは、Pythonの標準ライブラリで提供されているクラスで、httpパッケージのclientモジュールで提供されています。
2.ulropen関数のサンプルプログラム
サンプルプログラムの動きを見てみましょう。記事の後ろでサンプルプログラムの動きを説明しています。
##urllib_ex1.py
##urllibパッケージのrequestモジュールから、urlopen関数をインポートする
from urllib.request import urlopen
##urlopen関数を使って、yahooのトップページをダウンロード
url = "https://www.yahoo.co.jp"
http_response = urlopen(url)
##urlopenの戻り値インスタンスのclass(型)を確認
print("http_responseのクラス(型)を見てみる:",type(http_response),"\n")
##http_responseのインスタンス変数statusを読み込んで
##httpリクエストに対するステータスコードを表示
##通信エラーの場合はhttpのエラーコードが表示される
response_status = http_response.status
print("status:", response_status, "\n")
##http_responseのインスタンスメソッドgeturl()を実行してurlを取得
response_url = http_response.geturl()
print("response url:", response_url, "\n")
##http_responseのインスタンス変数headersを読み込んでhttpヘッダを表示
response_headers = http_response.headers
print("headders:\n", response_headers, "\n")
##http_responseのインスタンスのread()メソッドを使って、htmlを取得。
##read()メソッドの戻り値raw_contentははマルチバイト文字(日本語)がエンドードされているので、
##yahooサイトの文字コードutf-8(デフォルト値なので引数省略)でデコードして出力
raw_content = http_response.read()
html = raw_content.decode()
print("html content:\n",html)
出力結果
http_responseのクラス(型)を見てみる: <class 'http.client.HTTPResponse'>
status: 200
response url: https://www.yahoo.co.jp
headders:
Accept-Ranges: none
Cache-Control: private, no-cache, no-store, must-revalidate
Content-Type: text/html; charset=UTF-8
以下、省略
html content:
<!DOCTYPE html><html lang="ja"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><title>Yahoo! JAPAN</title><meta name="description" content="あなたの毎日をアップデートする情報ポータル。検索、ニュース、天気、スポーツ、メール、ショッピング、オークションなど便利なサービスを展開しています。"/><meta name="robots" content="noodp"/><meta name="viewport" content="width=1010"/><link rel="dns-prefetch" href="//s.yimg.jp"/><link rel="dns-prefetch" href="//yads.c.yimg.jp"/><meta name="google-site-verification" content="fsLMOiigp5fIpCDMEVodQnQC7jIY1K3UXW5QkQcBmVs"/><link rel="alternate" href="android-app://jp.co.yahoo.android.yjtop/yahoojapan/home/top"/><link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.yahoo.co.jp/"/><link rel="canonical" href="https://www.yahoo.co.jp/"/><link rel="shortcut icon" href="https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico" type="image/vnd.microsoft.icon"/><link rel="icon" href="https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico" type="image/vnd.microsoft.icon"/><meta property="og:title" content="Yahoo! JAPAN"/><meta property="og:type" content="website"/><meta property="og:url" content="https://www.yahoo.co.jp/"/><meta property="og:image" content="https://s.yimg.jp/images/top/ogp/fb_y_1500px.png"/><meta property="og:description" content="あなたの毎日をアップデートする情報ポータル。検索、ニュース、天気、スポーツ、メール、ショッピング、オークションなど便利なサービスを展開しています。"/><meta property="og:site_name" content="Yahoo! JAPAN"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:site" content="@Yahoo_JAPAN_PR"/><meta property="twitter:image" content="https://s.yimg.jp/images/top/ogp/tw_y_1400px.png"/><meta property="fb:app_id" content="472870002762883"/><link rel="stylesheet" href="//s.yimg.jp/images/top/orion/20200616/bundle_20200616.css"/><script>window.onbeforeunload = function() {}</script><script>(function () {
var tagjs = document.createElement("script");
var s = document.getElementsByTagName("script")[0];
以下、省略
以下、サンプルプログラムに沿って、説明します。
3.urlopen関数のimport
urlopen関数のインポート。標準ライブラリのモジュールはモジュールのパスを気にする必要がありません。
##urllibパッケージのrequestモジュールから、urlopen関数をインポートする
from urllib.request import urlopen
import文でモジュールのクラスや関数を読み込む場合は、以下の形式でインポートします。
from <モジュール名> import <関数名またはクラス名または変数名>
ここで、パッケージの中のモジュールを指定する場合は、以下の形式でモジュールを指定します。
<パッケージ名>.<モジュール名>
4.HTTP GETリクエストの送信とレスポンス
urlopen関数の引数にurlを渡して呼び出すと、urlopen関数は指定したurlのウェブサイトにGETリクエストを送信し、ウェブサイトレスポンスを受信し、これをHTTPResponseクラスのインスタンスとして返します。
##urlopen関数を使って、yahooのトップページをダウンロード
url = "https://www.yahoo.co.jp"
http_response = urlopen(url)
次の行では、ウェブサイトからのレスポンスを格納しているhttp_responseのオブジェクトの型を出力しています。
##urlopenの戻り値インスタンスのclass(型)を確認
print("http_responseのクラス(型)を見てみる:",type(http_response),"\n")
出力結果は、
http_responseのクラス(型)を見てみる: <class 'http.client.HTTPResponse'>
となっています。
出力結果であるhttp.client.HTTPResponseは、httpパッケージの、clientモジュールの中で定義されているHTTPResponseクラスであることを表しています。
つまり、http_responseはHTTPResponseクラスのインスタンスとなります。
import文は、クラスを呼び出すときのみ必要となります。すでに実体となっているインスタンスのみをプログラムの中で利用するときは、import文を書く必要はありません。上記urllibe_ex1.pyでも、HTTPResponseクラスはインスタンスのみの利用となっています。プログラムの中でHTTPResponseクラスを呼び出していないので、インポートは不要です。
5.HTTPResponseクラスのインスタンス変数とインスタンスメソッド
サンプルプログラムの次の行からは、HTTPResponseクラスのいくつかのインスタンス変数の読み込みと、インスタンスメソッドの呼び出しをしています。
5.1.HTTPResponseクラスのインスタンス変数
HTTPResponseクラスのインスタンス変数statusの値は、http通信のステータスコードがセットされます。
##http_responseのインスタンス変数statusを読み込んで
##httpリクエストに対するステータスコードを表示
##通信エラーの場合はhttpのエラーコードが表示される
response_status = http_response.status
print("status:", response_status, "\n")
出力結果
status: 200
結果の200は、Webサイトから正常にコンテンツが取得できたことを表しています。通信エラーなどでコンテンツの取得し失敗した場合は、エラー原因別のステータスコードが返され、デバッグに利用することができます。
5.2.HTTPResponseクラスのインスタンスメソッド
read()メソッドは、HTTPResponseクラスのインスタンスから、htmlコンテンツを文字列で取得するインスタンスメソッドです。ただし、日本語文字はエンコードされたままのバイト文字列として返します。
そこで、サンプルプルグラムでは、文字列オブジェクトのメソッドである、decodeを使って、バイト文字列をデコードしました。
##http_responseのインスタンスのread()メソッドを使って、htmlを取得。
##read()メソッドの戻り値raw_contentははマルチバイト文字(日本語)がエンドードされているので、
##yahooサイトの文字コードutf-8(デフォルト値なので引数省略)でデコードして出力
raw_content = http_response.read()
html = raw_content.decode()
print("html content:\n",html)
補足1:
文字のエンコードとは、文字や記号を文字コードに変換することです。変換対象は主に日本語文字などのマルチバイト文字です。文字コードにはいくつか種類があり、インターネットやUNIX系のシステムではutf-8が、windowsではshift-jis(後継はcp932)がよく利用されています。
文字のデコードとは、エンコードされた文字を元の文字に戻すことをいいます。デコードの際、エンコードされた方式でデコードしないと文字化けが起きてしまいます。また、特殊文字等に対応できていない古いバージョンのものでデコードした場合も、拡張文字(後から追加された文字や記号)等の文字化けの原因となります。
補足2:
yahooサイトのマルチバイト文字(日本語文字等)の文字コードは、utf-8なので、サンプルプログラムではutf-8でデコードしています。decodeメソッドに引数を設定していませんが、これは、decodeメソッドの引数のデフォルト値が
decode(encoding='utf-8')
で、utf-8となっているからです。
出力結果
html content:
<!DOCTYPE html><html lang="ja"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/><title>Yahoo! JAPAN</title><meta name="description" content="あなたの毎日をアップデートする情報ポータル。検索、ニュース、天気、スポーツ、メール、ショッピング、オークションなど便利なサービスを展開しています。"/><meta name="robots" content="noodp"/><meta name="viewport" content="width=1010"/><link rel="dns-prefetch" href="//s.yimg.jp"/><link rel="dns-prefetch" href="//yads.c.yimg.jp"/><meta name="google-site-verification" content="fsLMOiigp5fIpCDMEVodQnQC7jIY1K3UXW5QkQcBmVs"/><link rel="alternate" href="android-app://jp.co.yahoo.android.yjtop/yahoojapan/home/top"/><link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.yahoo.co.jp/"/><link rel="canonical" href="https://www.yahoo.co.jp/"/><link rel="shortcut icon" href="https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico" type="image/vnd.microsoft.icon"/><link rel="icon" href="https://s.yimg.jp/c/icon/s/bsc/2.0/favicon.ico" type="image/vnd.microsoft.icon"/><meta property="og:title" content="Yahoo! JAPAN"/><meta property="og:type" content="website"/><meta property="og:url" content="https://www.yahoo.co.jp/"/><meta property="og:image" content="https://s.yimg.jp/images/top/ogp/fb_y_1500px.png"/><meta property="og:description" content="あなたの毎日をアップデートする情報ポータル。検索、ニュース、天気、スポーツ、メール、ショッピング、オークションなど便利なサービスを展開しています。"/><meta property="og:site_name" content="Yahoo! JAPAN"/><meta property="twitter:card" content="summary_large_image"/><meta property="twitter:site" content="@Yahoo_JAPAN_PR"/><meta property="twitter:image" content="https://s.yimg.jp/images/top/ogp/tw_y_1400px.png"/><meta property="fb:app_id" content="472870002762883"/><link rel="stylesheet" href="//s.yimg.jp/images/top/orion/20200616/bundle_20200616.css"/><script>window.onbeforeunload = function() {}</script><script>(function () {
var tagjs = document.createElement("script");
var s = document.getElementsByTagName("script")[0];
以下、省略
HTMLコンテンツのダウンロードは、スクレイピングの第一歩です。HTMLの中から必要なデータを抜き出すときは、Beautiful Soup(外部オブジェクトです)などの別のクラスオブジェクトを使います(いつか、別の記事で説明しようと思います)。
補足
urlopen関数は、httpのPOSTリクエストも送信することができます。
最近はurllibモジュールよりも、外部モジュールのRequestsモジュールの方がよく利用されているようです。外部モジュールの取り込み方は別の記事で説明します。