Pythonロボティクスコース レッスン 42

テーマ.11-1 ネットワーク通信やインターネットの仕組み

Studuino:bitをインターネットへ接続しよう!

このレッスンで学ぶこと

このレッスンではStuduino:bitをインターネットへ接続し、Webページから情報を取得する方法を学習します。インターネットが普及した経緯やその仕組みについても簡単に見ていきましょう。

インターネットの世界

インターネットは、世界中の情報端末が通信回線でつながった最大規模のネットワークです。インターネットを利用することで、いつでもどこでもすぐに自分の欲しい情報にアクセスすることができます。

最近は、次世代の通信技術「5G」が登場し、通信速度の高速化や同時接続可能な情報端末数の大幅な増加、遅延の改善によって、自動車や生活家電のようにこれまでインターネットとは関係がなかった様々なものがインターネットにつながる「IoT(Internet of Things)」の実現が期待されています。

2. 1 インターネットの普及に貢献したWebの開発

インターネットは、1990年代に欧州原子核研究機構(cern)に所属していた、コンピューター技術者のティム・バーナーズ=リーによって「World Wide Web(WWW)」(いわゆるWeb)というハイパーメディアシステムが開発されたことで急速に普及しました。ハイパーメディア(Hyper Media)はリンクによって相互に参照できる文書のことで、つまりはWebサイトです。

ティム・バーナーズ=リーは、WWWの中で、ハイパーメディアを記述するための様式として「HTML(Hyper Text Markup Language)」と、ハイパーメディアを転送するための方式である「HTTP(Hyper Text Transfer Protocol)」、それから世界中にあるWebサイトの中から一意に指定するための規約「URL(Uniform Resource Locator)」を開発しています。また、Webサイトを閲覧するための「WWWクライアント」(いわゆるWebブラウザ)を開発し、無償で公開しました。

1991年8月に彼によって世界で初めて公開されたWebサイトの復刻版が、今でも欧州原子核研究機構のWebサイト内で閲覧できます。

世界初のWebサイトの復刻ページ(http://info.cern.ch/hypertext/WWW/TheProject.html)

現在は、ティム・バーナーズ=リーを中心に組織されたWeb技術の標準化団体「W3C」によりWebの標準仕様が策定されています。

2. 2 インターネットの通信網

ここからは少し詳しくインターネットの仕組みを見ていきましょう。

インターネットの通信網は、「LAN(Local Area Network)」と「WAN(Wide Area Network)」の2つの分けられます。

LANは、家庭や企業、大学など限られた範囲で情報端末を相互に接続して構築されるネットワークです。これに対して、地理的に離れた場所をつなぐ広域なネットワークがWANです。

一般的な家庭では、回線事業者やプロバイダーが設置したルーターにコンピュータやスマートフォン、ゲーム機を接続しています。そして、それらの端末からインターネットにアクセスするときは、ルーターを通して外部のネットワークに接続します。

プロバイダーは、他のプロバイダーや規模の大きな企業や大学と通信回線をつないでいます。また、それだけでなく、インターネットエクスチェンジという施設と接続することで、他に接続しているすべてのプロバイダーと相互に接続できるようになっており、世界中のどこにでもつながる大規模なネットワークが構築されています。

2. 3 インターネットの階層構造

インターネット上でデータをやり取りする仕組みを理解する上で、アメリカの国防高等研究計画局(DARPA)から提唱されている「DARPAモデル」が参考になります。DARPAモデルでは、インターネットに必要な通信機能を、4つの階層構造に分割して説明しています。

【 DARPAモデル 】
  • アプリケーション層
    アプリケーションプログラムの間で、どのような形式や手順でデータをやり取りするのかを定めています。文字コードや画像フォーマット、データの暗号化などもこの層で扱います。
  • トランスポート層
    トランスポート層では、アプリケーションプログラム間でのデータ伝送を実現します。必要に応じて行われるデータの誤り検出や送信元へのデータの再送要求もこの層で扱います。
  • インターネット層
    インターネットに接続された複数の機器間でのデータの伝送を実現します。ネットワークの中から対象の機器を特定するために使用されるIPアドレスはインターネット層で扱います。
  • ネットワークインタ―フェイス層
    ネットワークインターフェイス層は、最もハードウェアに近い階層で、有線LANや無線LANを使用して通信するために、データを物理的な電気信号へ変換する役割があります。

DARPAモデルの他に、国際標準化機構(ISO)によって策定された「OSI参照モデル」があります。OSI参照モデルでは、コンピュータにとって必要な通信機能を7つの階層に分けて定義しています。

  • アプリケーション層
    ファイルの転送や、Webサイトのデータの取得など、具体的に行われる通信サービス。
  • プレゼンテーション層
    文字コードや暗号化など通信するデータの表現形式や変換方法。
  • セッション層
    通信の開始から終了までの手順についての取り決め。
  • トランスポート層
    エラーの訂正やデータの再送要求など、通信の信頼性を担保するための仕組み。
  • ネットワーク層
    ネットワーク上で目的の相手との通信するための経路を確保するための仕組み。
  • データリンク層
    ルーターなど直接近くに接続されている機器との間で信号の受け渡しを行うための仕組み。
  • 物理層
    ケーブルなど物理的な接続や電気信号への変換を行うための仕組み。

DARPAモデルとOSI参照モデルは、どちらも通信に必要な機能を階層別に定義したという意味では同じです。OSI参照モデルはより高位の抽象的な概念になっており、DARPAモデルは現在のインターネットの通信機能を実装する上で現実的な仕様を策定しているという違いがあります。

Studuino:bitをインターネットへ接続する

それでは実際に、Wi-Fiを使用してStuduino:bitをインターネットへ接続してみましょう。

3. 1 networkモジュールを使ったWi-Fiの利用

Wi-Fiを利用してインターネットへの接続を行うときは、networkモジュールのWLANクラスを使用します。

※ 「WLAN」は「Wireless LAN(無線LAN)」を省略した表記です。

■ WLANクラスのオブジェクトの作成

WLANクラスはコンストラクタで動作モードを引数として受け取ります。この引数に「network.STA_IF」を指定した場合、作成されたオブジェクトはステーション(別名:クライアント)として機能します。「network.AP_IF」を指定した場合は、アクセスポイントとして機能します。

  • ステーションnetwork.STA_IF
    無線LANの子機として動作するモード
  • アクセスポイントnetwork.AP_IF
    無線LANの親機として動作するモード

ここでは、教室や学校に設置されているWi-Fiのアクセスポイントに接続するため、ステーションとしてStuduio:bitを動作させましょう。

以下のコードで、ステーションとしてWLANオブジェクトを新たに作成します。

■ ネットワークインタフェースの有効化/無効化

WLANクラスのほとんどのメソッドは、ネットワークインターフェースが有効化されていないと使用できません。有効化と無効化を行う場合、次のactive()メソッドを実行します。

  • ネットワークインターフェースを有効化するとき
    active()メソッドの引数に"up"またはTrueを渡して実行します。
  • ネットワークインターフェースを無効化するとき
    active()メソッドの引数に"down"またはFalseを渡して実行します。

以下のコードを追加して、ネットワークインターフェースを有効化しましょう。

追加【4行目】

■ アクセスポイントの一覧の取得

WLANクラスのscan()メソッドを実行すると、利用可能なアクセスポイントの一覧を取得できます。このメソッドはアクセスポイントの情報を以下のタプルで返します。

(SSID、MACアドレス、チャンネル数、受信信号強度、認証モード、可視/非可視)
  • SSID
    Wi-Fiのアクセスポイントを識別するための名前。最大で32文字までの英数字で設定されています。
  • MACアドレス
    ネットワークに接続する機器に付けられた固有の識別番号。メーカーが製造する段階で「FF-FF-FF-FF-FF-FF」や「00:00:00:00:00:00」のように16進数を用いた表現で必ず付けられています。
  • チャンネル数
    最大でチャンネル数と同じ数の情報端末をアクセスポイントに接続できます。
  • 受信信号強度
    アクセスポイントから発信されている信号の受信強度。
  • 認証モード
    無線LANのデータ通信で利用する暗号化方式。
  • 可視/非可視
    可視設定の場合、他の機器からSSIDの検索ができますが、非可視設定の場合はできません。

実際に以下のコードを追加してプログラムを実行し、近くのアクセスポイントの一覧を表示しましょう。また、その中に教室で用意されているアクセスポイントがあることを確認しましょう。

追加【6行目~8行目】
(実行結果の例)

■ アクセスポイントへの接続と通信の切断

アクセスポイントへ接続するときは、connect()メソッドを実行します。このメソッドは、第1引数に「アクセスポイントの識別名(SSID)」を、第2引数に「パスワード(PASSWORD)」を取ります。

反対に、アクセスポイントとの通信を切断する場合はdisconnect()メソッドを実行します。connect()メソッドを一度実行すると、このdisconnect()メソッドが実行されるか、もしくはネットワークインターフェースが無効化されるまで、繰り返し接続が試みられます。

以下のようにコードを変更して、教室や学校のアクセスポイントに接続しましょう。

変更【5行目】
※ アクセスポイントの一覧を表示するコードは削除します。
(接続に成功した場合のターミナルの表示例) ※↓表示されません。
(接続に失敗した場合のターミナルの表示例)

■ 接続の有無の確認

アクセスポイントに接続できているかどうかは、isconnected()メソッドで調べることができます。is_connected()メソッドは接続できている場合はTrueを返し、未接続の場合はFalseを返します。

上で説明したように、connect()メソッドはアクセスポイントに接続できるまで、裏側で繰り返し接続を試みます。しかし、必ずしもネットワークに接続する必要がないプログラムを実行する場合、これでは他の処理を妨げてしまうことになります。

そこで以下のコードでは、isconnected()メソッドを利用して、connect()メソッドを実行してから、10秒以上が経過してもアクセスポイントへ接続できなかったときに、途中で断念するようにしています。

追加・変更【2行目、6行目~20行目】

■ インターネット層レベルのネットワークに関するパラメータの取得

アクセスポイントへ接続すると、Studuino:bitには自動的に「IPアドレス」が割り当てられます。

IPは、Internet Protocolの略で、DARPAモデルのインターネット層にあたります。IPでは、ネットワーク上で互いに通信する相手を特定できるように、ネットワーク上の住所を表すIPアドレスが各情報端末に割り当てられます。

IPアドレスにはLAN(ローカルエリアネットワーク)内で割り当てられる「ローカルIPアドレス」と、WAN(ワイドエリアネットワーク)内で割り当てられる「グローバルIPアドレス」があります。

IPアドレスを含むインターネット層レベルのパラメータは、ifconfig()メソッドで取得できます。このメソッドの返り値は以下のタプルです。

(IPアドレス、サブネットマスク、ゲートウェイ、DNSサーバー)
  • IPアドレス
    インターネット層にある情報端末を識別するために割り振られた識別番号。このIPアドレスは、ローカルIPアドレスです。
  • サブネットマスク
    ネットワークの範囲を定義するために使われる数値。サブネットマスクを使うことで、もともと同じネットワークにある情報端末をいくつかのグループに分割して管理することができます。
  • ゲートウェイ
    外部のネットワークとの通信の出入口となっているアクセスポイントのIPアドレス。
  • DNSサーバー
    DNSとして機能しているサーバーのIPアドレス。DNSは「Domain Name System」の略で、例えば「artec-kk.co.jp」のようなインターネット上のドメイン名とIPアドレスの関係を管理するために開発されたシステムです。本来はIPアドレスを指定して他の情報端末にアクセスする必要がありますが、それでは分かりにくいため、代わりにドメイン名が用いられています。

実際に以下のコードを追加して、各パラメータをターミナルに表示してみましょう。

追加【15行目、22行目】
(実行結果の例)

3. 2 アクセスポイントへの接続機能をモジュール化する

ここまでで確認したnetoworkモジュールを用いたWi-Fiのアクセスポイントへの接続機能を、独自のクラス「MyWifi」を作成してまとめましょう。

【 MyWifiクラスのメソッド 】
メソッド名処理内容
__init__(self)WLANクラスのオブジェクトを作成し、ネットワークインタフェースを有効化する。
connect(self, ssid, password)指定されたSSIDとパスワードでアクセスポイントに接続する。接続に成功した場合はTrueを返し、IPアドレスなどのパラメータを表示する。接続に失敗した場合はFalseを返す。
disconnect(self)アクセスポイントとの接続を解除する。
isconnected(self)アクセスポイントと接続されているかどうかを返す。
get_aps(self)接続可能なアクセスポイントの一覧をターミナルに表示する。

■ MyWifiクラスの定義

新しくプログラムファイルを作成し、以下のコードを書きましょう。

【 MyWifiクラスのコード 】 ※def connect のssid、pwはそのままに!

■ クラスの動作確認とモジュール化

定義したクラスの動作を確認します。上のMyWifiクラスを定義したプログラムを実行します。実行後にターミナルでMyWifiクラスのインスタンスを作成し、SSIDとパスワードを指定してconnect()メソッドを実行しましょう。

(プログラムの実行例) ※SSID、PWに情報を入れること

残りのメソッドも問題なく実行できることを確認した上で、このプログラムファイルをモジュール化します。

mywifi」と名前を付けてパソコンにファイルを保存します。メニューから「ファイル」を選択して、Studuino:bit内に保存したファイルをコピーしましょう。

Studuino:bit内への保存方法の詳細は、レッスン20 チャプター3の「■ PCのファイルをStuduino:bitの内部に保存する」を参考にして下さい。

インターネットからWebページの情報を取得する

ここまでで、Wifiのアクセスポイントを経由して、インターネットに接続する方法を確認してきました。ここからは、実際にインターネット上のWebページから情報を取得する方法を見ていきます。

4. 1 インターネットを利用した通信の規約

インターネットを利用して、コンピュータ間の通信を成立させるためには、お互いが共通のルールに従ってデータの転送と受信ができる仕組みが必要です。コンピューターの世界では、このルールのことを「通信プロトコル(または通信規約)」といいます。

上で紹介した、インターネットの階層構造を定義した「DARPAモデル」では、各階層ごとに様々な通信プロトコルが存在しています。上位層の通信プロトコルは、下位層の通信プロトコルによって実装されています。最上位のアプリケーション層では次の通信プロトコルが使われています。

※ 他の階層については、テーマ.11-3で詳しく解説します。
【 DARPAモデルにおけるアプリケーション層での通信プロトコルの例 】
プロトコル名正式名称説明
HTTPHyper Text Transfer ProtocolWebブラウザがWebサーバーと通信するときに使われる通信プロトコル。HTMLで書かれたWebページ内のコンテンツの送受信を行うことができます。
SMTPSimple Mail Transfer Protocolインターネットを利用して、電子メールを転送するときに使われる通信プロトコル。
POP3Post Office Protocol利用者がメールサーバーに保管されている自分宛の電子メールを取り出すときに使われる通信プロトコル。
FTPFile Transfer Protocolクライアントとサーバーの間でファイルの転送を行うときに使われる通信プロトコル。
TelnetTeletype networkインターネットを利用して、遠隔地にあるサーバーやルーターなどの情報端末を制御するときに使われる通信プロトコル。すべてのデータ通信は暗号化されていないテキスト(Plane text)で行われるため、安全性に問題があり、代わりとしてSSHが使われることも多い。
SSHSecure Shell暗号化や認証の技術を利用して、遠隔地にある情報端末と安全に通信するためのプロトコル。

このレッスンでは、Webページの情報を取得するために、「HTTP」を利用します。

4. 2 HTTPについて

HTTPは、「HTML(HyperText Markup Language)」や「XML(Extensible Markup Language)」で書かれたWebページのデータを転送するために開発された通信プロトコルです。テキストデータ以外にも、画像や音声などWebページ内に埋め込まれた様々なコンテンツ(リソースといいます)を扱うことができます。

HTTPを用いた通信は、クライアント(Webブラウザ)からサーバーへ「リクエスト(request)」を送ることで開始されます。サーバーはクライアントから送られてきたリクエストに応じて、Webページのコンテンツを含む結果を返します。これを「レスポンス(response)」といいます。

クライアントから送るリクエストには、様々な情報が含まれています。その情報の中心にあるのが、次に説明する「URL」と「HTTPメソッド」です。

■ URLとは

URL(Uniform Resource Locator)とは、簡単に説明すると、インターネット上の情報がどこに存在しているのかを示した住所のことです。Webブラウザでは、上部に以下のような文字列でURLが表示されています。

http://www.artec-kk.co.jp/artecrobo2/pdf/jp/studuinobit_class_reference.pdf
※ 上のURLは、ArtecRobo2.0をPythonで制御するためのリファレンス(参照資料)の場所を表しています。

このURLに含まれる文字列は、それぞれ次の意味を表しています。

  • スキームhttp:
    と呼ばれ、主に通信プロトコルの名前が使われることが多いです。この場合はHTTPを利用することを表しています。
  • ホスト名/ドメイン名//www.artec-kk.co.jp
    リクエストの送信先のサーバーを表す「ホスト名(www)」と「ドメイン名(artec-kk.co.jp)」です。
  • パス/artecrobo2/pdf/jp/studuinobit_class_reference.pdf
    取得するデータやWebページの名前(studuinobit_class_reference.pdf)と、それがサーバー内のどのディレクトリ(/artecrobo2/pdf/jp/)に存在しているかを表しています。これを「パス(Path)」といいます。

■ HTTPメソッドとは

HTTPメソッドは全部で9つあり、URLで指定したリソースに対して、どのような操作を行うのかを定めています。今は全てを覚える必要はありませんので、次の5つのメソッドを押さえておきましょう。

  • GET
    リソースを取得するメソッド。GETメソッドを実行することで、サーバーのリソースが変更されることはありません。
  • HEAD
    GETメソッドと同じレスポンスを求めますが、レスポンスの本体(リソース本体)は取得しません。
  • POST
    データを送信するメソッド。サーバーは受信したデータを元に、リソースを書き換えたり、新たなリソースを作成したりして、レスポンスを送ります。
  • PUT
    リソースをアップロードしたり、既に存在しているリソースを上書きするメソッド。
  • DELETE
    リソースを削除するメソッド。

■ HTTPのリクエストとレスポンスの内容

また、HTTPのリクエストやレスポンスは、内部で次のように情報が分かれています。

例えば、リクエストの先頭は、以下のようなメソッド名とURLから構成されています。最後の「HTTP/1.1」はHTTPのバージョンを表していて、最新は「HTTP/2」です。

GET https://www.artec-kk.co.jp/school/cl/textbooks/sample/ HTTP/1.1

その下のヘッダには、以下のようにクライアント自身の情報やサーバーへ要求する様々な情報が書かれています。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Host: www.artec-kk.co.jp
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36

|ヘッダの種類|意味|
|:—|:—|
|Accept|レスポンスとして受け入れ可能なリソースの種類|
|Accept-Encoding|Webブラウザでデコードが可能なデータのエンコーディングの種類|
|Accept-Language|Webブラウザが予期している言語の種類|
|Cache-Control|キャシュを制御するための情報。キャッシュは、一度アクセスしたサイトのデータをWebブラウザで一時的に保管し、次回以降に同じページへアクセスしたときの表示速度を上げる仕組みです。|
|Connection|サーバーとのコネクションを切断する場合は「close」を指定し、コネクションを維持する場合は「keep-alive」を指定。HTTP/1.1以降のデフォルトは「keep-alive」です。|
|Host|URLに含まれているホスト名やドメイン名。|
|User-Agent|リクエストを送信するWebブラウザやOSの種類とそのバージョン情報。|

上のヘッダ情報は一例で、他にも様々なヘッダが存在しています。サーバーはこれらのヘッダ情報を読み取り、必要な処理を行います。

そして、リクエストのボディには、サーバーにリソース(テキストデータや画像、音声などのファイル)を送信する場合のみ、その情報が書かれています。

レスポンスの情報については、実際にWebページへリクエストを送るプログラムを作成して、内容を確認していきましょう。

4. 3 HTTP通信の実践

MicroPythonでは、urequestsモジュールでHTTP通信を簡単に行うことができます。urequestsモジュールにはHTTPメソッドに対応した以下の関数が用意されています。

【 urequestsモジュールの関数 】
関数名処理内容
get(url, headers={})GETメソッドでリクエストを送る
post(url, data, json, headers={})POSTメソッドでリクエストを送る
put(url, data)PUTメソッドでリクエストを送る
delete(url)DELETEメソッドでリクエストを送る
head(url, headers={})HEADメソッドでリクエストを送る
request(method, url, data=None, json=None, headers={})メソッド名を指定してリクエストを送る

上記の関数はすべて、responseオブジェクトを返します。このresponseオブジェクトにサーバーから送られてきたレスポンスの情報が格納されています。responseオブジェクトは、以下のプロパティとメソッドを持ちます。

【 responseオブジェクトのプロパティとメソッド 】
プロパティ名/メソッド名内容
status_codeHTTPステータスコード
reasonHTTPステータスコードのリーズンフレーズ
encoding文字エンコード
contentデコード前のレスポンスデータ
textcontentencodingに従ってデコードしたテキスト
json()contentをJSONとして解釈し、辞書型のデータとして返すメソッド

「ステータスコード」や「JSON」という言葉が初めて出てきましたが、これらについては、後の解説や次のレッスンで詳しく説明をしていきます。まずは、シンプルなWebページに対して、GETメソッドでリクエストを送り、返ってきたレスポンスを確認してみましょう。

■ GETメソッドでWebページのデータを取得する

GETメソッドで次のURLからWebページのデータを取得します。

https://www.artec-kk.co.jp/school/cl/textbooks/sample

このURLをWebブラウザで開くと、次のようなとてもシンプルなページが表示されます。

このWebページは、HTMLで書かれていて、元の文書は「ソース(Source)」と呼ばれます。ソースはWebブラウザ上の表示とは異なります。

※ よく誤解されがちですが、HTMLはプログミング言語ではありません。章・節・項のような階層構造と相互に参照可能なリンクを持つ文書を表すための言語です。

Webブラウザには、元のHTMLの文書を表示する機能が備わっています。例えばChromeの場合は、Webページ上で右クリックをし、表示された項目の中から「ページのソースを表示」を選択します。他のブラウザも手順は同じで、Edgeの場合は「ソースを表示」、Safariの場合はメニューバーの「開発」の中から「ページのソースを表示」を選択します。

上の手順で表示したソースが以下になります。

HTMLでは、文書内での役割や意味を「タグ」と呼ばれる表現で囲んで示します。例えば、5行目の<title></title>というタグは、このWebページのタイトルを表しています。Googleなどの検索エンジンを利用したときに、検索結果の一覧に表示されるタイトルです。また、8行目の<h1></h1>は大見出しを、9行目の<p></p>は段落をそれぞれ表しています。

他にも、HTMLには表や画像、音声、動画など様々なコンテンツに対応したタグが用意されています。すべてのタグについて説明すると1冊の本になってしまいますので、この講座では取り扱いませんが、Webサイトの制作に興味がある人は書籍や他の講座で学習してみてください。

では、以下のサンプルコードを実行して、GETメソッドでこのWebページの情報を取得してみましょう。

【 サンプルコード 4-3-1 】
(実行結果の例)

実行結果から、さきほど確認したものと同じHTMLのソースが取得できていることが分かります。

そして、ソースの上に表示した「200」と「OK」は、それぞれステータスコードとそのリーズンフレーズです。これらは、上で確認したレスポンス構造の先頭の行(ステータス行)に書かれています。

ステータスコードは、HTTPのリクエストが正常に処理されたのかを表す3桁の番号です。「200」は正常に完了したことを表しています。ステータスコードとリーズンフレーズはセットになっていて、ステータスコードが「200」のときのリーズンフレーズは「OK」です。

以下の表は、ステータスコードとリーズンフレーズの一例です。

【 HTTPのステータスコードとリーズンフレーズの一例 】
ステータスコードリーズンフレーズ意味
200OKリクエストが成功したことを表します。
301Moved PermanentlyリクエストされたURLが永久的に別のURLに変更されたことを表します。このときは、レスポンスで変更後のURLが送信されます。
304Not Modifiedキャッシュを使用している場合に、前回のアクセスからレスポンスが変更されていないことを表します。そのため、クライアントはキャッシュに残っているリソースを使用してページを表示します。
404Not Foundサーバーがリクエストされたリソースを発見できない(リソースが存在しない)ことを表します。
405Method Not Allowedリクエストされたメソッドがサーバーで許可されていないことを表します。ただし、GETやHEADに対して、このステータスコードが返されることはありません。
501Not Implementedリクエストされたメソッドにサーバーが対応していないことを表します。ただし、GETやHEADに対して、このステータスコードが返されることはありません。

例えば、【 サンプルコード 4-3-1 】を変更し、GETメソッドに代わり、PUTメソッドでリクエストを送ってみましょう。

【 サンプルコード 4-3-2 】
変更【8行目】
(実行結果の例)

ステータスコードが「405」、リーズンフレーズが「Method Not Allowed」になっています。これは、サーバーでPUTメソッドによるリソースの上書きが禁止されているためです。このように、ステータスコードやリーズンフレーズを確認することによって、正常にリクエストが処理されなかった場合の理由が分かるようになっています。

インターネットから取得したデータを用いたLEDディスプレイの制御

サーバー上のWebページには、クライアントからのリクエストに対して常に同じレスポンスを返すものと、リクエストに含まれる情報によって異なるレスポンスを返すものがあります。

さきほどのサンプルコードで利用したWebページは前者で、以下のWebページは後者です。

https://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php

このWebページは、リクエストで送られてきた色名の情報によって、対応するRGB値をレスポンスとして返します。実際に、次の2つのURLを開き、表示内容が異なることを確かめてみましょう。

https://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=red

https://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=green

上の2つのURLは、どちらも元のURLの末尾に「?」が追加されています。その後ろに続く「color=red」や「color=green」を「クエリパラメータ」といい、GETメソッドを利用してサーバーに情報を送るときに使われます。

5. 1 クエリパラメータをURLに追加する

クエリパラメータは、URLの末尾に「?」を付け、その後ろに「パラメータ(変数)の名前=パラメータ(変数)の値」の形式で指定します。複数のパラメータを送りたい場合は、以下のように「&」でつなぎます。

http://www.****.com/***/***.php?パラメータ名=値&パラメータ名=値&...

上で紹介したWebページは、次のパラメータが送られてくると、それに応じたレスポンスを返すようになっていました。つまり、このWebページは色名からRGB値を検索できる機能を提供していると言えます。

【 対応しているクエリパラメータ 】
クエリパラメータURLレスポンス
color=redhttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=red(31, 0, 0)
color=greenhttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=green(0, 31, 0)
color=bluehttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=blue(0, 0, 31)
color=yellowhttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=yellow(31, 31, 0)
color=cyanhttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=cyan(0, 31, 31)
color=magentahttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=magenta(31, 0, 31)
color=whitehttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=white(31, 31, 31)
該当なしhttps://www.artec-kk.co.jp/school/cl/textbooks/sample/getrgb.php?color=orangeNot Found

それでは、このWebページを利用して、ユーザーがターミナルに入力した色名からRGB値を取得し、Studuino:bitのLEDディスプレイを点灯するプログラムを作成してみましょう。

5. 2 Webページで色名に対応するRGB値を調べてLEDディスプレイを点灯するプログラムの作成

以下の処理を順番に行うlight_up()という関数をつくり、この関数をターミナルから呼び出して実行します。

  1. Wi-Fiへの接続
  2. ユーザーからの入力の受け付け
  3. Webページからの情報の取得
  4. 取得した情報の安全性の確認
  5. LEDディスプレイの点灯

順番にコードを書いていきましょう。

■ Wi-Fiへの接続

light_up()関数が呼び出されたとき、Wi-Fiに未接続の場合は接続を試みます。接続に失敗した場合は続きの処理が実行できないため、return文を実行して処理を終えるようにしましょう。

■ ユーザーからの入力の受け付け

次に、input()関数でユーザーから色名の入力を受け付けます。以下のコードを追加しましょう。

追加【11行目】

■ Webページからの情報の取得

ユーザーが入力した色名をパラメータの値としてURLを作成し、GETメソッドでサーバーにリクエストを送ります。レスポンスのステータスコードを確認し、成功しなかった場合は、ステータスコードとリーズンフレーズを表示して、ここで関数の処理を終えます。

追加【1行目、7行目、14~17行目】

■ 取得した情報の安全性の確認

リクエストが成功した場合、サーバーからは以下のタプル形式の文字列をボディにもつレスポンスが返されます。

(31,31,31)

そこで、これをeval()関数で式として評価し、タプル型のオブジェクトを得ることができます。

しかし、インターネットから取得した情報の中には、悪意のあるコードが埋め込まれている場合もあります。(※もちろんレッスンで紹介しているWebページにはそのようなコードは埋め込まれていません。)eval()関数は、文字列をそのままPythonで書かれた式として解釈して評価するため、悪意のあるコードによってプログラムが不具合を起こす可能性もあります。

※ 文字列を式ではなく、プログラム文として解釈して実行するexec()関数を使用する場合は、さらに危険性が高く、ウィルスが埋め込まれたり、個人情報を盗み取られたりする可能性があります。

そこで、情報の安全性を担保するために、事前に正規表現を利用したマッチングを行い、求めているフォーマットに適合しているかどうかをチェックする対策が取られることがあります。ここでも、この方法を採用してみます。

このプログラムでは、「3つの2桁までの数値を要素にもつタプル型文字列」をレスポンスとして期待しています。このパターンにマッチする正規表現は以下になります。

(」や「)」の丸括弧は、正規表現でグループを表すという特別な意味をもつため、そのまま文字として解釈させるためには、直前にエスケープ文字である「\」を付ける必要があります。

それでは、上記のことを踏まえた上で次のコードを追加しましょう。

追加【2行目、9・10行目、21~25行目】

■ LEDディスプレイの点灯

最後に取得したRGB値でLEDディスプレイを点灯します。以下のコードを追加しましょう。これでプログラムの完成です。

【 サンプルコード 5-2-1 】
追加【3行目、11・12行目、26行目】

5. 3 プログラムの動作確認

利用するWebページは以下の色名に対応しています。

red、green、blue、yellow、cyan、magenta、white

完成したプログラムを実行して、上記の色名をターミナルから入力し、動作を確認しましょう。

(プログラムの実行例)

課題:インターネットから取得したデータを用いたブザーの制御

この課題用に、イギリスの作曲家エドワード・エルガーが作曲した「威風堂々(Pomp and Circumstance)」の楽譜の中から数小節を選び、その音を上から順番に表へまとめたWebページを用意しています。

【 WebページのURL 】

https://www.artec-kk.co.jp/school/cl/textbooks/sample/melody.html

【 Webブラウザの画面 】

そして、このページのHTMLのソースは次のようになっています。

【 Webページのソース 】
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Pomp and Circumstance</title>
</head>

<style>
table{
	border-collapse: collapse;
	border:1px solid;
}
th,td{
	border:1px solid;
	padding:0.5em 0.3em;
}
th{
	background-color: #eee;
}
</style>
	
<body>
	<h1>Pomp and Circumstance</h1>
	<table>
		<thead>
			<tr>
				<th>tone(MIDI)</th><th>duration</th>
			</tr>
		<thead>
		<tbody>
			<tr><td>72</td><td>1200</td></tr>
			<tr><td>71</td><td>300</td></tr>
			<tr><td>72</td><td>300</td></tr>
			<tr><td>74</td><td>600</td></tr>
			<tr><td>69</td><td>1200</td></tr>
			<tr><td>67</td><td>1200</td></tr>
			<tr><td>65</td><td>1200</td></tr>
			<tr><td>64</td><td>300</td></tr>
			<tr><td>65</td><td>300</td></tr>
			<tr><td>67</td><td>600</td></tr>
			<tr><td>62</td><td>2400</td></tr>
			<tr><td>64</td><td>1200</td></tr>
			<tr><td>66</td><td>300</td></tr>
			<tr><td>67</td><td>600</td></tr>
			<tr><td>69</td><td>300</td></tr>
			<tr><td>74</td><td>1200</td></tr>
			<tr><td>67</td><td>1200</td></tr>
			<tr><td>72</td><td>1200</td></tr>
			<tr><td>72</td><td>300</td></tr>
			<tr><td>71</td><td>600</td></tr>
			<tr><td>69</td><td>300</td></tr>
			<tr><td>67</td><td>2400</td></tr>
		</tbody>
	</table>
</body>
</html>

24行目から54行目の<table></table>タグで囲まれた文書が表にまとめられた音の情報です。GETメソッドで取得したこのソースから、正規表現や文字列のメソッドを使って音の情報だけを取り出し、ブザーから再生するプログラムを次のヒントを踏まえて自分で作成してみましょう。

6. 1 HTMLで書かれたソースから必要な情報だけを取り出す方法

上のソースを詳しくみていくと、次のかたまりが1つの音を表していることが分かります。

<tr><td>72</td><td>1200</td></tr>

<tr></tr>タグは表の1行を、<td></td>タグは表の1セルをそれぞれ表しています。

そこで、次の正規表現と正規表現オブジェクトのsearch()メソッドを用いてセル単位で検索を行います。

"<td>\\d+</td>"

search()メソッドでマッチした文字列は、返り値のマッチオブジェクトのgroup()メソッドで取得できます。この2つのメソッドと文字列オブジェクトのreplace()メソッドを次のように組み合わせることで、元のソースからマッチする文字列を取り出すことができます。

【 組み合せの例 】
(実行結果)

以上をヒントにして、できるだけ自分で考えてプログラムを作成しましょう。

6. 2 サンプルプログラムの作成手順

Webページのリソースを取得するところまでの手順は、【 サンプルコード 5-2-1 】と同じです。以下のサンプルプログラムでは、play_melody()と名前を付けた関数に処理をまとめています。

上で確認した方法を応用して、取得したソースから音の情報だけを正規表現を利用して取り出します。ここで気を付けなければならないのは、「音の高さ」と「音の長さ」の2つの情報を区別しなければならないということです。

<tr><td>72</td><td>1200</td></tr>
左の<td>72</td>が音の高さで、右の<td>1200</td>が音の長さを表しています。

しかし、以下の正規表現で検索するだけでは、2つを区別できません。

"<td>\\d+</td>"

そこで、検索回数をカウントし、その回数が奇数の場合はマッチした文字列が音の高さを表していて、偶数の場合は音の長さを表しているということで区別してみます。そして、取り出した音の情報は順番にリストに格納します。

この方法を実践したプログラムが以下になります。

追加【2行目、9行目、19~35行目】

ここまでで、Webページから音の情報を抽出してリストに格納できたので、最後にブザーから順番に鳴らすようにしてプログラムの完成です。

【 サンプルコード 6-2-1 】
追加【3行目、37・38行目】

完成したプログラムを実行して、関数名をターミナルから入力し、動作を確認しましょう。

(プログラムの実行例)
>>> play_melody()

おわりに

7. 1 このレッスンのまとめ

このレッスンでは、インターネットの仕組みとWebの歴史、それからWebブラウザが行っているHTTP通信について新たに学習しました。

また、MicroPythonのnetworkモジュールを使って、Studuino:bitをWi-Fiへ接続する方法を確認し、その機能をまとめたモジュールを自作しました。さらに、インターネットにつながったStuduino:bitから、urequestsモジュールを用いてHTTPのGETメソッドでリクエストを送り、シンプルなWebページの情報を取得する方法も見てきました。

そしてレッスンの後半では、学習したことの応用として、インターネットから取得した情報からLEDディスプレイやブザーを制御するプログラムを作成しました。

このレッスンの内容は、次回以降のレッスンを学ぶ上での基礎になりますので、時間のあるときに改めて振り返りを行ってください。

7. 2 次のレッスンについて

次回のレッスンでは、HTTPの「POSTメソッド」の実践と「JSON」というデータ形式について新たに学習します。そして、世界気象機関のWebサイトで公開されている世界の各都市の気象予報データを取得するプログラムを作成します。

TOP