今回は、少し解説内容の趣向を変え、ウェブアプリの開発ではなく、ウェブアプリの操作についての説明を行っていきます。
ここまでの Django 入門 においては、ウェブアプリを「ウェブブラウザ」から操作を行うことを前提とした解説を行ってきました。今回は、ウェブブラウザを利用しないウェブアプリの操作について解説していきます。
この操作方法を理解しておけば、自身が開発したウェブアプリを、例えば X や Instagram などのように、ウェブブラウザ以外の iOS アプリ、さらには Android アプリからも操作するようなことができるようになります。
Contents
ウェブアプリの操作とは
まずは、ウェブアプリの操作の仕組みについて解説していきます。
ウェブアプリの操作 = HTTP リクエストの送信
まずは、この Django 入門 の中で開発してきた掲示板アプリの操作について考えていきたいと思います。
ウェブアプリはマウスで操作する?
この掲示板アプリでは、ページ上部にナビゲーションバーが表示されており、このナビゲーションバー内のリンクをマウスでクリックすることで、そのリンク先のページを表示することができるようになっています。例えば コメント一覧
リンクをクリックすれば、コメント一覧が取得され、それらがページに表示されます。
また、この掲示板アプリはコメント投稿フォームからコメントが投稿できるようになっています。このコメント投稿フォームでは、コメントの本文の入力欄と 送信
ボタンが用意されており、入力欄に文字列を入力してから 送信
ボタンをマウスでクリックすれば、その入力した文字列を本文とするコメントがデータベースのテーブルにレコードとして保存され、これによってコメントの投稿が実現されるようになっています。
このように、ここまで私たちが開発してきた掲示板アプリは、マウス操作によって様々な操作を行えるようになっています。
ウェブアプリは HTTP リクエストの送信で操作する
…という風にも考えることができるのですが、ここでは、もう1段階踏み込んで考えてみましょう!
たとえば、コメント一覧
のリンクをクリックすることで、投稿済みのコメント一覧が表示できるのは、なぜでしょうか?
これは、この コメント一覧
をクリックすることで、投稿済みのコメント一覧の取得を要求する HTTP リクエストがウェブブラウザからウェブアプリに対して送信されるからになります。この送信された HTTP リクエストをウェブアプリが受信することで、ウェブアプリが投稿済みのコメント一覧を表示するための HTML を生成し、それをボディとする HTTP レスポンスをウェブブラウザに返却してくれます。さらに、この HTTP レスポンスを受け取ったウェブブラウザが、ボディの HTML に基づいてページを描画することで、投稿済みの一覧が画面に表示されることになります。
また、送信
ボタンのクリックによってコメントを投稿できる理由も同様です。これも、送信
ボタンのクリックによって、コメントの新規登録を要求する HTTP リクエストがウェブブラウザからウェブアプリに対して送信されるからになります。この送信された HTTP リクエストをウェブアプリが受信することで、ウェブアプリが受信したリクエストに応じたレコードをデータベースのコメントを管理するテーブルに新規登録してくれます(この、コメントを管理するテーブルへのレコードの新規登録がコメントの投稿となります)。
このように、ウェブアプリは HTTP リクエストを受信することで、その HTTP リクエストの内容に応じた処理や機能を実行するようになっています。したがって、ウェブブラウザからウェブアプリを操作することができるのは、ウェブブラウザがウェブアプリに対して HTTP リクエストを送信しているからと考えることができます。これは掲示板アプリだけでなく、全てのウェブアプリで共通的に言えることになります。
ということで、ウェブアプリの操作とは、ウェブアプリに対して HTTP リクエストを送信することになります。また、その操作結果は、ウェブアプリから送信されてくる HTTP レスポンスによって得ることができます。
スポンサーリンク
ウェブアプリはウェブブラウザ以外からも操作可能
そのため、ウェブアプリは、HTTP リクエストの送信(および HTTP レスポンスの受信)さえできれば、どんなアプリ・ツール・プログラムからでも操作可能ということになります。ただ、HTTP リクエストの送信を行うアプリで一番有名なものはウェブブラウザです。そのため、この Django 入門 もそうであるように、基本的には、まずウェブアプリをウェブブラウザで操作することを前提に開発・動作確認を行っていくことになります。
ですが、前述の通り、HTTP リクエストの送信さえできれば、ウェブブラウザ以外からもウェブアプリは操作可能です。なので、例えば iOS アプリや Android アプリから、そのウェブアプリに適した HTTP リクエストを送信するようにしてやれば、それらのアプリからウェブアプリを操作することが可能となります。また、同様にして、JavaScript や Python スクリプトからウェブアプリを操作することも可能です。
このように、ウェブアプリは、HTTP リクエストの送信によって操作することが可能なアプリであるため、ウェブブラウザだけでなく、様々なアプリ・ツールからも利用可能となります。
また、このような「ウェブアプリが HTTP リクエストの送信によって操作可能であること」を理解しておくことで、ウェブアプリ開発において様々なメリットが得られます。
まず、先ほどの説明からも分かるように、専用アプリの開発に役立ちます。例えば、X や Instagram は、ウェブブラウザでも操作可能ですが、専用の iOS アプリ・Android アプリからも操作可能ですよね。ウェブアプリに適したリクエストを送信するようアプリを開発することで、X や Instagram 同様に、あなたの開発したウェブアプリ操作用の専用アプリを開発・配信することが可能となります。
また、UI (フロントサイド) の開発の自由度が向上します。基本的に、ウェブブラウザでは、ページやフォーム等の UI は HTML・CSS・JavaScript によって表示されるようになっています。なので、ウェブブラウザに表示される UI は、これらの言語を駆使して開発する必要があります。ですが、ウェブアプリの操作は HTTP リクエストさえ送信できれば実施可能なので、専用のアプリを別の言語を利用して開発しても問題ありません。好きな言語を選んで開発できますので、特に UI (フロントエンド) の開発の自由度が上がります。
さらに、ウェブアプリの動作確認の効率化も図りやすくなります。これまでウェブアプリに対する各種操作の動作確認は全て、ウェブブラウザ上で手動で行ってきました。ですが、HTTP リクエストを送信することでウェブアプリの操作が可能であるため、HTTP リクエストを送信するスクリプトやツールを別途用意しておくことで、それらの実行のみでウェブアプリの動作確認を実施することが可能となります。特に何回も繰り返し動作確認が必要な場合でも、楽に動作確認を実施することが可能です。
こんな感じで、ウェブアプリが HTTP リクエストの送信によって操作可能であることを知っておけば、ウェブアプリを操作するプログラムやアプリの作り方の幅広がりますし、自動でウェブアプリの操作を実現するような発想を持つこともできるようになります。
この、HTTP リクエスト送信によって操作できるという点は、ウェブアプリの重要な特徴となるので是非覚えておきましょう!
HTTP リクエストでのウェブアプリの操作の実現
次に、ウェブブラウザ以外からのウェブアプリの操作の実現方法について解説していきます。
HTTP リクエストの送信
ここまで説明してきたように、ウェブアプリは HTTP リクエストの送信によって操作可能です。
HTTP リクエストのデータフォーマット
簡単に、HTTP リクエストのデータフォーマットについて解説しておきます。
HTTP リクエストのデータフォーマットを図で表すと下図のようなものになります。このように、HTTP リクエストは「リクエストライン」「ヘッダー」「ボディ」の3つの部分から構成され、さらに各部に様々なデータ・フィールドが存在します。
特に、このページの解説の中で重要となるのが、上の図でも示したリクエストラインの メソッド
・URL
、さらにヘッダーの Cookie
・X-CSRFToken
となります。また、ボディが「送信するデータ」となりますので、データの送信を行う場合はボディも必要となります。
HTTP リクエストの送信の実現
ウェブアプリ以外からウェブアプリを操作するためには、先ほど示したような HTTP リクエストの送信を最初に実現する必要があります。
HTTP リクエストの送信さえできれば、どんな手段を使っても良いのですが、HTTP リクエストの送信機能を提供するライブラリも多く存在しますので、それらを利用するのがお手軽だと思います。
例えば、Python であれば、下記のようなライブラリを利用することで簡単に HTTP リクエストの送信を行うことができます。後述の ウェブアプリの操作を行うツールの開発例 の章では、requests
を利用して、実際にウェブアプリの操作を HTTP リクエストの送信で実施できるようにしていきます。
http.client
urllib
requests
送信する HTTP リクエストの内容
とりあえず、上記のようなモジュールを利用すれば HTTP リクエストの送信自体は実施できるようになると思います。
で、次にポイントになるのが、「どんな HTTP リクエストを送信すればよいのか?」という点になります。
基本的には、この送信すべき HTTP リクエストの内容は、ウェブアプリによって異なります。ただ、ウェブアプリの操作は大きく分けると下記の2つで、それぞれで送信すべき HTTP リクエストの内容の大枠は決まりますので、この点については次の節で解説していきます。
- データの取得(HTML の取得)
- データの送信
また、送信すべき HTTP リクエストの内容は、ウェブブラウザが送信する HTTP リクエストから確認することも可能です。
前述の通り、ウェブブラウザは、マウスでの操作時(ボタンやリンクのクリック時)に、その操作に応じた HTTP リクエストをウェブアプリに対して送信するようになっています。なので、そのウェブブラウザから送信される HTTP リクエストを確認し、その内容を真似た HTTP リクエストを送信するようにすれば、ウェブブラウザからの操作時と同じ操作を、ウェブブラウザ以外のアプリやプログラムから実施することができることになります。つまり、送信する HTTP リクエストの内容が同じであれば、それを誰が送信したとしても、同じ操作が行えるということです。
なので、どんな HTTP リクエストを送信すればよいか分からない場合は、実際にウェブブラウザでウェブアプリの操作を行い、その操作時に送信される HTTP リクエストを真似て送信するようにしてやれば良いです。
ただ、ウェブブラウザから送信される HTTP リクエストと全く同じ HTTP リクエストを送信するようにする必要はありません。特に、HTTP リクエストのヘッダーに関しては、ポイントとなる部分のみを真似て送信するようにしてやれば良いです。
また、ウェブブラウザから送信される HTTP リクエストは、Google Chrome の「検証ツール」や Microsoft Edge の「開発者ツール」で確認することも可能ですし、下記ページで紹介している Wireshark というアプリで確認することもできます。後述の ウェブアプリの操作を行うツールの開発例 の章では、Chrome を利用して HTTP リクエストを確認する例を紹介していきます。
Wiresharkのインストール方法と使い方【Windows編】 Wiresharkのインストール方法とChmodBPFでの権限設定【Mac編】スポンサーリンク
HTTP リクエストでのデータの取得
続いて、HTTP リクエストの送信によるデータの取得方法について解説していきます。
ウェブアプリの操作は、大きく分けて2種類に分けられます。1つ目が「データの取得操作」で、2つ目が「データの送信操作」になります。
まずは、1つ目のデータの取得について解説していきます。
本題に入る前に、少し前置きをしておくと、ウェブブラウザのみから操作されることを想定したウェブアプリの場合は、データの取得操作は「HTML の取得操作」と考えて良いです。
このようなウェブアプリでは、ウェブブラウザでページが表示できるよう、データの表示に関するリクエストが送信された際には HTTP レスポンスのボディとして HTML を返却するようになっています。つまり、このようなウェブアプリから取得可能なデータは基本的には HTML のみです。例えば、この Django 入門 の連載を通して開発してきている掲示板アプリもウェブブラウザのみから操作されることを想定しているため、このアプリから取得できるデータは現状 HTML のみになります。
ですが、次回の Django 入門 で説明する API をウェブアプリに搭載することで、HTML 以外のデータをウェブアプリから取得することができるようになります。このページでは、ウェブアプリから取得できるデータが HTML であることを前提に解説を進めますが、ウェブアプリの作り方によっては、HTML 以外のデータを取得することも可能であることは頭の片隅にでも置いておいてください。
GET
メソッドの HTTP リクエストを送信する
では、HTTP リクエストの送信によるデータの取得について解説していきます。
基本的には、データの取得操作は、下記のような HTTP リクエストを送信するだけで実現することができます。
- URL:取得対象を示す URL
- メソッド:
GET
ウェブブラウザからのみ操作されることを想定して開発されたウェブアプリの場合は、URL には「表示対象のページの URL」を指定してやれば良いことになります。
とりあえず、上記のような HTTP リクエストを送信するようにすれば、URL に対応した HTML を取得することができるようにはなります。ですが、ウェブブラウザ以外のツールやアプリが HTML を取得してもページの表示を行うことは困難ですし、HTML にはタグなどの不要なデータが含まれていますので、HTML を取得した後に目当てとなるデータのみを抽出するための HTML の解析を行うことになります。そして、その抽出したデータを利用して目的の処理を実行するようなことが多いと思います。
この HTML の解析の概要に関しては、後述の HTTP レスポンスの解析 の節で解説します。
HTTP リクエストでのデータの送信
また、ウェブアプリではデータの送信を行う操作も多いです。
例えば、掲示板アプリであれば、コメントの投稿操作はデータの送信操作の1つであり、コメントの投稿者やコメントの本文をウェブアプリに対して送信することで、コメントの投稿をウェブアプリに依頼することになります。また、ユーザー登録に関しても、登録するユーザーの情報をウェブアプリに対して送信することで実現される操作となります。
このように、特に下記ページで説明した CRUD 操作における Create や Update 操作を行う場合は、こういったデータの送信が必要となります。
【Django入門16】CRUDの実現(Create・Read・Update・Delete)POST
メソッドの HTTP リクエストを送信する
このようなデータの送信操作を行うには、下記のような HTTP リクエストを送信する必要があります。
- URL:データの送信先の URL
- メソッド:
POST
- ボディ:送信するデータ
- ヘッダー:
Cookie
:Set-Cookie
のcsrftoken
X-CSRFToken
:Set-Cookie
のcsrftoken
この「送信するデータ」は、ウェブブラウザでフォームから送信するデータと同じフォーマットのものである必要があります。このようなデータの送信方法については、後述の ウェブアプリの操作を行うツールの開発例 で説明します。
今回は、ウェブブラウザから操作されることを前提に開発されたウェブアプリを対象としているため、データの送信操作を行う際にはメソッドに POST
を指定することになります
ただし、前述の説明の中でも登場した API が搭載されたウェブアプリの場合は、POST
以外のメソッドの HTTP リクエストの送信が必要になることもあります
Cookie に csrftoken
を設定する
特に、上記で示した HTTP リクエストにおいてポイントになるのが「ヘッダー」になります。
Django で開発したウェブアプリでは、特定の条件を満たさない「データの送信操作に対する HTTP リクエスト」が送信されてきた場合、その HTTP リクエストが CSRF 攻撃であると判断され、エラーが発生するようになっています。そして、この場合はデータの送信操作が実施できないことになります。
このエラーを回避するためには、それが CSRF 攻撃でない、すなわち「安全な HTTP リクエスト」であるとウェブアプリに判断されるような HTTP リクエストを送信する必要があります。そして、そのための条件が2つあって、1つ目が、この節の題名にも書いている通り、csrftoken
を HTTP リクエストの Cookie
に設定しておくことになります。
この csrftoken
は、ウェブアプリから発行されるトークンであり、ウェブアプリに対して GET
メソッドの HTTP リクエストを送信すると、それに対する HTTP レスポンスの Set-Cookie
のフィールドの値として受け取ることができます。
なので、データの送信操作を行うためには、まずウェブアプリに対して GET
メソッドの HTTP リクエストを送信して csrftoken
を受け取り、さらに、その csrftoken
をヘッダーの Cookie
に設定した上で、HTTP リクエストを送信する必要があることになります。
X-CSRFToken
に csrftoken
を設定する
2つ目の条件が、先ほど説明した csrftoken
を HTTP リクエストのヘッダーの X-CSRFToken
に設定しておくことになります。
要は、ウェブアプリに対してデータの送信操作を行うためには、ヘッダーの Cookie
と X-CSRFToken
の両方に、ウェブアプリから発行された csrftoken
を設定した HTTP リクエストを送信する必要があります。
この2つの条件を満たした HTTP リクエストを送信することで、その HTTP リクエストがウェブアプリに安全であると判断されるようになり、データの送信操作を行うことができるようになります。
(参考)csrfmiddlewaretoken
を利用する
また、ヘッダーの X-CSRFToken
に csrftoken
を設定する代わりに、送信するデータに csrfmiddlewaretoken
フィールドを追加し、このフィールドの値としてトークンを設定することでも、データの送信を実現することが可能です。
実は、ウェブブラウザでフォームからデータを送信する場合は、こちらの方法が用いられています。
これは、ウェブブラウザで取得したフォームの HTML を見てみれば確認できることなのですが、Django で開発したウェブアプリから取得したフォームの HTML には、隠れフィールドとして、値をウェブアプリから発行されたトークンとする csrfmiddlewaretoken
フィールドが含まれています。
そのため、フォームからデータを送信したときには、他のフィールドの値に含めて csrfmiddlewaretoken
も送信されことになります。そして、送信されてきたデータに csrfmiddlewaretoken
が存在するため、その HTTP リクエストは安全であるとウェブアプリに判断されることになります。
ちなみに、フォームに csrfmiddlewaretoken
フィールドが存在するのは、Django でウェブアプリを開発する際に、テンプレートファイルの form
タグ内に {% csrf_token %}
を記述することになっているからになります。
<form action="略" method="post">
{% csrf_token %}
略
</form>
この {% csrf_token %}
を記述しておくことで、この部分が csrfmiddlewaretoken
フィールドに置き換えられることになり、それによって CSRF 攻撃と判断されない HTTP リクエストの送信を行うことができるようになっています。
もしかしたら、{% csrf_token %}
の記述を忘れていて、フォームからデータを送信した際に下記のようなエラーが発生した経験のある方もおられるかもしれません。これは、送信するデータに csrfmiddlewaretoken
フィールドが存在しないため、送信されてきた HTTP リクエストが CSRF 攻撃であると判断されたからになります。
CSRF検証に失敗したため、リクエストは中断されました。
ということで、送信するデータに csrfmiddlewaretoken
フィールドを追加することでも、正常なデータの送信操作を実現することは可能です。ただ、この方法では、事前にフォームを取得する HTTP リクエストを送信してフォームを HTTP レスポンスで受け取り、さらに、そのフォームの HTML を解析して csrfmiddlewaretoken
フィールドの値を取得するような処理が必要となって面倒です。先に紹介した HTTP レスポンスの Set-Cookie
で取得した csrftoken
を X-CSRFToken
に設定する方法の方が楽です。そのため、以降では、データの送信時には X-CSRFToken
に csrftoken
を設定する方法を採用することを前提に解説を進めます。
HTTP リクエストでのデータの送信のまとめ
ここまでの内容をまとめると、データ送信操作を行う際には、下記のような HTTP リクエストを送信する必要があります。
- URL:データの送信先の URL
- メソッド:
POST
- ボディ:送信するデータ
- ヘッダー:
Cookie
:Set-Cookie
のcsrftoken
★X-CSRFToken
:Set-Cookie
のcsrftoken
★
ただし、★マークで示したデータに関しては、事前にメソッドが GET
の HTTP リクエストをウェブアプリに送信し、その応答となる HTTP レスポンスから取得する必要があります。
これらを送信するスクリプトの例は、次の章の ウェブアプリの操作を行うツールの開発例 で示していきます。
HTTP レスポンスの解析
ここまで説明してきた通り、HTTP リクエストを送信することでウェブアプリの操作を実現することが可能です。さらに、その操作結果や取得したデータは、操作を実施するために送信した HTTP リクエストの応答となる HTTP レスポンスを解析することで得られることになります。
ここでは、この HTTP レスポンスの解析について解説していきます。
HTTP レスポンスのデータフォーマット
まずは、このウェブアプリから受信する HTTP レスポンスのデータフォーマットについて解説しておきます。
HTTP レスポンスのデータフォーマットを図で表すと下図のようなものになります。このように、HTTP レスポンスは「ステータスライン」「ヘッダー」「ボディ」の3つの部分から構成され、さらに各部に様々なデータ・フィールドが存在します。
特に、このページの解説の中で重要となるのが、上の図でも示したステータスラインの ステータスコード
、さらにヘッダーの Set-Cookie
になります。Set-Cookie
に関しては、ここまでの解説の中でも登場しましたね!
あとは、ボディが「取得したデータ」となりますので、特にデータの取得操作を行う場合はボディが重要となります。
結果を知るために受信した HTTP レスポンスの解析が必要
前述の通り、ウェブアプリの操作結果は HTTP レスポンスとして、HTTP リクエストの送信元に返却されることになります。操作結果の詳細を知りたい場合は、この HTTP レスポンスの解析が必要となります。
例えば、HTTP レスポンスの ステータスコード
には、操作結果の成功・失敗(及び失敗の理由)を表す値がセットされていますので、操作が成功したかどうかを知るために HTTP レスポンスを解析して ステータスコード
を取得する必要があります。
他にも、データの送信操作を実現するためには、HTTP レスポンスを解析して Set-Cookie
の値を取得するようなことも必要となります。こういった、HTTP レスポンスのステータスラインやヘッダーのデータに関しては、前述でも紹介した「HTTP リクエストを送信するライブラリ」を利用することで、簡単に取得することが可能です。
HTML を解析して必要なデータのみを抽出することも必要
また、ウェブブラウザから操作されることを前提に開発されたウェブアプリの場合、HTTP レスポンスのボディは基本的には HTML となります。なので、特にデータの取得操作を実施した場合は、その HTML を解析し、HTML の中から必要なデータのみを抽出するような処理も必要となります。例えば、コメント一覧の取得操作に対しては、そのコメント一覧をページ表示するための HTML が返却されることになるため、その HTML 内から必要なデータ(コメントの本文やコメントの投稿者など)を取得し、その取得後のデータを利用して処理を実施する必要があることが多いです。
HTML の解析の仕方
自力で HTML の解析を行うのは大変なので、この HTML の解析に関してもライブラリを利用して実施するのが良いと思います。Python であれば、HTML の解析用ライブラリとして BeautifulSoup
が存在し、これが利用されることが多いです。後述の ウェブアプリの操作を行うツールの開発例 の章では、BeautifulSoup
を利用した HTML の解析例を示していきます。
ただし、HTML の具体的な解析の仕方は、結局のところウェブアプリが返却してくる HTTP レスポンスの HTML の構造によって異なります。なので、HTML の解析を行うためには、ウェブアプリが返却する HTML の構造を理解しておく必要があります。これに関しても、実際にウェブブラウザで操作を行い、その操作によって取得される HTML を確認するのが手っ取り早いと思います。また、Django で開発するウェブアプリの場合は、テンプレートファイルで HTML の構造が決まりますので、テンプレートファイルから HTML の構造を理解しておくのでも良いです。
ここまでの説明内容で既に感じ取っていただいているかもしれませんが、HTML はウェブブラウザでページを表示するのに適したデータではありますが、ウェブブラウザ以外からは扱いにくいデータです。なぜなら、HTML から必要なデータのみを取得したいような場合、上記で説明したように HTML の解析処理が必要になるからです。
そのため、ウェブブラウザ以外が HTTP レスポンスのボディのデータを利用するケースがあるのであれば、HTTP レスポンスのボディを HTML ではなく、解析が不要 or 簡単な形式のデータ、例えば JSON 等とする API を追加で用意して、それを利用するようにするというのも手です。この API に関しては、次回の連載の中で解説を行いたいと思います。
スポンサーリンク
ウェブアプリの操作を行うツールの開発例
ここからは、ウェブアプリの操作が HTTP リクエストによって実施できることを実感していただくため、実際にウェブアプリの操作を行うツールを作成していきたいと思います。
ウェブアプリの作成と起動
まずは、操作対象となるウェブアプリを開発していきたいと思います。
今回は、コメントの投稿と、投稿済みのコメント一覧の表示機能のみを備えた簡単なウェブアプリをまず開発し、その後、そのウェブアプリとウェブブラウザの間でやりとりする HTTP リクエスト・HTTP レスポンスを調べ、さらに、その調べた結果に基づいて、ウェブアプリを操作するツールを開発する例を示していきます。
プロジェクト・アプリの作成
まずは、プロジェクトとアプリを作成していきます。
ターミナルやコマンドプロンプト等のコンソールアプリで適当な作業フォルダに移動した後、下記を実行して request_test
というプロジェクトを作成してください。
django-admin startproject request_test
これにより、request_test
というフォルダが作成されるはずなので、そのフォルダに移動した後、下記コマンドを実行して forum
というアプリを作成してください。
python manage.py startapp forum
次に、今いる request_test
フォルダの中に、もう1つ request_test
フォルダが存在するはずなので、そのフォルダの中の settings.py
を開き、下記のように INSTALLED_APPS
のリストの先頭に 'forum',
を追加して下さい。
INSTALLED_APPS = [
'forum',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
さらに、settings.py
と同階層に urls.py
が存在するはずなので、この urls.py
を下記のように変更してください。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('forum/', include('forum.urls'))
]
models.py
の作成
次に、forum/models.py
を下記のように変更し、コメントを管理するモデルクラス Comment
を定義します。
from django.db import models
class Comment(models.Model):
author = models.CharField(max_length=32)
text = models.CharField(max_length=256)
forms.py
の作成
続いて、forum/forms.py
を新規作成し、さらにファイルに下記を記述してコメント投稿フォーム CommentForm
を定義します。
from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['author', 'text']
views.py
の作成
さらに、views.py
を下記のように変更し、コメント投稿を行う CommentCreate
と、コメント一覧表示を行う CommentList
のビューを定義します。
from .forms import CommentForm
from .models import Comment
from django.views.generic import ListView, CreateView
from django.urls import reverse_lazy
class CommentCreate(CreateView):
form_class = CommentForm
template_name = 'forum/comment_form.html'
success_url = reverse_lazy('list')
class CommentList(ListView):
model = Comment
template_name = 'forum/comment_list.html'
テンプレートファイルの作成
次は、CommentCreate
から利用するテンプレートファイル comment_form.html
と CommentList
から利用するテンプレートファイル comment_list.html
を次のように作成し、forum/templates/forum
フォルダ内に設置してください。
<h1>コメント投稿</h1>
<form action="{% url 'create' %}" method="post">
{% csrf_token %}
<table >{{ form.as_table }}</table>
<p><input type="submit" value="送信"></p>
</form>
<h1>コメント一覧</h1>
<table>
<thead>
<tr>
<th>本文</th><th>投稿者</th>
</tr>
</thead>
<tbody>
{% for comment in comment_list %}
<tr>
<td>{{ comment.text }}</td>
<td>{{ comment.author }}</td>
</tr>
{% endfor %}
</tbody>
</table>
urls.py
の作成
次は、forum/urls.py
を新規作成し、ファイルの中身を下記のように変更してください。ソースコードの変更は以上となります。
from django.urls import path
from . import views
urlpatterns = [
path('create/', views.CommentCreate.as_view(), name='create'),
path('list/', views.CommentList.as_view(), name='list'),
]
マイグレーションの実行
ソースコードの変更が完了したら、次は、startapp
コマンドを実行したフォルダと同じフォルダで下記の2つのコマンドを実行し、マイグレーションを行ってください。
python manage.py makemigrations
python manage.py migrate
開発用ウェブサーバーの起動
最後に、下記コマンドを実行して開発用ウェブサーバーを起動してください。
python manage.py runserver
HTTP リクエストと HTTP レスポンスを調べる
ここからウェブアプリを操作するツールの開発を行なっていくことになるのですが、まずは、先ほど開発したウェブアプリをウェブブラウザから操作し、操作時に送受信される HTTP リクエストと HTTP レスポンスを調べていきたいと思います。
HTTP リクエストを送信しても意図した通りの操作が実現できない場合、まずはウェブブラウザで操作を行なって HTTP リクエストを調べ、それを真似て送信する HTTP リクエストを修正するのが手っ取り早いです。また、HTTP レスポンスの解析を行うことになるので、事前にウェブブラウザが受信する HTTP レスポンスを調べ、解析の方針決めを事前に行っておくと、スムーズにツールの開発を進めることができます。
このように、ウェブブラウザが送受信する HTTP リクエストと HTTP レスポンスを調べることができれば、ウェブブラウザ以外からのウェブアプリの操作の実現に非常に役に立ちます。というか、ウェブアプリを開発するのであれば、こういたデータの調べ方は理解しておいた方が良いです。ここでは、先ほど開発したウェブアプリを例にして、上記のような通信データの調べ方を簡単に説明していきますので、今後のウェブアプリ開発やウェブアプリの操作の実現時に活用していただければと思います。
Chrome の検証機能を起動する
まずは Chrome を起動してください。さらに、右クリックメニューの 検証
をクリックし、Chrome の検証機能を実行しましょう!
そうすると、Chrome の右側に検証ウィンドウが表示されるはずです。
このウィンドウでは、Chrome が送受信した HTTP リクエストや HTTP レスポンスを確認することが可能です。さらに、ページに表示されている各要素の HTML のタグとの対応や、各要素に適用されているスタイル等も確認することが可能です。
ちなみに、今回は Chrome を利用していますが、Edge でも同様の機能を利用することが可能です。Edge の場合は、右クリックメニューから 開発者ツールで調査する
をクリックすることで、同様のウィンドウを開くことができます。ただし、Chrome の場合と Edge の場合とで、タブ名やメニュー名等の文言が若干異なるので、その点は注意してください。
で、今回調べたいのは HTTP リクエストと HTTP レスポンスといったネットワークに関する情報になるなので、検証ウィンドウの上側の ネットワーク
タブを開いてください。
これで前準備は完了です!
コメント投稿操作時のリクエストとレスポンスを調べる
ここから、実際に Chrome で各種操作を実施し、その時に Chrome が送受信する HTTP リクエストと HTTP レスポンスを調べていきます。
最初に、コメント投稿の操作を行っていきたいと思います。
まず、下記 URL を Chrome のアドレスバーに指定してコメント投稿フォームを表示してみてください。
http://localhost:8000/forum/create/
フォームには、下の図のように Author
フィールドと Text
フィールドが存在しますので、それぞれに適当な投稿者名とコメント本文を入力してください。そして、その後に 送信
ボタンをクリックしてください。
この 送信
ボタンのクリックによって、検証ウィンドウに表示される情報が、送信
ボタンクリック時に送受信された HTTP リクエストと HTTP レスポンスの情報のものに更新されます。次は、これらの情報を確認していきましょう!
まずは、検証ウィンドウ左下の 名前
欄の create/
をクリックし、続けて ヘッダー
をクリックしてヘッダータブを開いてください。この ヘッダー
から、直前の操作時に送受信された HTTP リクエストと HTTP レスポンスを調べることが可能です。
さらに、このヘッダータブにおける、全般
セクションの リクエスト URL
と リクエスト メソッド
を確認してみましょう!
今回の場合は、下記のように表示されているはずで、これは 送信
ボタンがクリックされた時に送信される HTTP リクエストの URL とメソッドとなります。したがって、ウェブブラウザ以外からコメントの投稿を行う際にも、下記のようなリクエストを送信するようにツールを開発する必要があることになります。
リクエスト URL
:http://localhost:8000/forum/create/
リクエスト メソッド
:POST
次は、リクエスト ヘッダー
セクションに存在する Cookie
の欄を確認してみてください。ここには、ウェブブラウザが送信した HTTP レスポンスのヘッダーにおける Cookie
フィールドのデータが表示されています。このデータの中には、 csrftoken=...
の文字列が存在しているはずです。
この csrftoken
は、事前にフォームを表示したときの HTTP レスポンスの Set-Cookie
に設定されていたデータとなります。ウェブブラウザ以外からデータの送信操作を行う際にも、このように事前に取得した csrftoken
を Cookie
に設定した状態の HTTP リクエストを送信する必要があります。
さらに、次は ペイロード
タブを表示してみてください。ここには、送信
ボタンがクリックされた時に送信される HTTP リクエストのボディのデータ、すなわちフォームから送信されたデータが表示されるようになっています。
ここには、下記の3つのフィールドの値が表示されるはずです。
csrfmiddlewaretoken
author
text
author
の値としては、あなたが Author
フィールドに入力した文字列、text
の値としては、あなたが Text
フィールドに入力した文字列がそれぞれ表示されているはずです。これらは、フォームからユーザーに入力してもらった値なので、当然 送信
ボタンのクリック時に送信されるようになっています。そして、このデータをウェブアプリが受け取ることで、コメントのレコードとしてデータベースに保存が行われることになります。
で、それらに加えて、送信されるデータに csrfmiddlewaretoken
フィールドが存在することが確認できると思います。(参考)csrfmiddlewaretoken を利用する で解説したように、ウェブブラウザからデータの送信操作が行われる際には、このような csrfmiddlewaretoken
フィールドが追加された状態のデータが送信されることになります。これは、ウェブアプリに、送信した HTTP リクエストを CSRF 攻撃ではないと判断させるためです。
前述の通り、この csrfmiddlewaretoken
フィールドをデータとして送信する代わりに、HTTP リクエストのヘッダーの X-CSRFToken
フィールドに csrftoken
の値をセットしておくことでも同様のことが実現可能です。このページでは、X-CSRFToken
フィールドに csrftoken
の値をセットする方法を採用してウェブアプリを操作するツールを開発していきます。
続いて、ペイロード
タブの ソースを表示
をクリックしてみてください。実は、先ほど表示されていたのは、ウェブブラウザから送信されたデータそのものではなく、それを辞書のような形式に整形したデータとなります。で、この ソースを表示
をクリックすることで、ウェブブラウザでフォームから実際に送信されたデータを確認することができます。
各種フィールドの値が &
で区切られているところがポイントで、ツールからデータの送信操作を実現する場合も、このような形式のデータをツールから送信する必要があることになります。ちなみに、このようなデータの形式は「URL エンコード」と呼ばれます。
最後に、再度 ヘッダー
タブを表示し、全般
セクションの ステータスコード
欄を確認してみてください。
この ステータスコード
欄の値は 302
となっているはずです。
このコメント投稿フォームでは、コメントの投稿に成功した場合に、HTTP レスポンスとしてリダイレクトレスポンスを返却し、他のページへのリダイレクトを行うようになっています。このリダイレクト先はコメント一覧のページとなっているので、送信
ボタンをクリックした際にコメント一覧が表示されたというわけです。で、このリダイレクトレスポンスのステータスコードは基本的には 302
となります。なので、コメントの投稿に成功したかどうかは、HTTP レスポンスのステータスコードの値が 302
であるかどうかで判断することができます。
ちなみに、コメントの投稿に失敗した場合は、再度コメント投稿フォームが表示されることになり、その時のステータスコードは 200
となります。
ここまでの説明内容をまとめると、先ほど開発したウェブアプリに対するコメント投稿の操作は、下記のような HTTP リクエストを送信することで実現できることになります。
URL
:http://localhost:8000/forum/create/
メソッド
:POST
- ヘッダー:
Cookie
:Set-Cookie
のcsrftoken
★X-CSRFToken
:Set-Cookie
のcsrftoken
★
- ボディ(送信するデータ):
author
フィールド:フォームのAuthor
フィールドに入力された値text
フィールド:フォームのAuthor
フィールドに入力された値
ただし、上記の★マークを付けた項目に関しては、事前にウェブアプリから受け取っておく必要があるため、まず、GET
メソッドの HTTP リクエストを送信し、それに対する HTTP レスポンスとして★マーク部分のデータを取得するようにする必要があります。
そのため、事前に下記の HTTP リクエストを送信して★マーク部分のデータを取得し、その後、上記のような HTTP リクエストを送信してコメントの投稿操作を行うようにツールを開発するようにしたいと思います。
URL
:http://localhost:8000/forum/create/
メソッド
:GET
コメント一覧取得時のリクエストとレスポンスを調べる
次は、コメント一覧取得時の HTTP リクエストと HTTP レスポンスを調べていきたいと思います。
コメント一覧の取得に関しては、コメントが投稿済みである方が内容を理解しやすくなると思いますので、まずは下記ページで複数のコメントを投稿しておいてください。2、3個コメントが投稿されていればオーケーです。
http://localhost:8000/forum/create/
コメントの投稿が完了したら、下記の URL を Chrome のアドレスバーに入力してコメント一覧ページを表示してください。
http://localhost:8000/forum/list/
コメント一覧ページを表示したら、検証ウィンドウの 名前
欄の list/
をクリックし、Chrome が送受信した HTTP リクエストと HTTP レスポンスを調べていきましょう!
ここでは、ヘッダー
をクリックしてヘッダーセクションを表示し、全般
セクションの リクエスト URL
と リクエスト メソッド
を確認してみてください。
これらの欄から、コメント一覧ページの取得操作を行うために、ウェブブラウザが下記のようなリクエストを送信していることが確認できます。したがって、ウェブブラウザ以外からコメント一覧ページの取得操作を実施する際にも、下記のようなリクエストを送信するようにする必要があることになります。
リクエスト URL
:http://localhost:8000/forum/list/
リクエスト メソッド
:GET
今回のウェブアプリの場合、コメント一覧の取得に関しては、上記のように URL とメソッドを指定した HTTP リクエストを送信するだけで実現することができ、その取得結果は HTTP レスポンスのボディとして得られます。
次は、そのボディを確認してみましょう!
検証ウィンドウの レスポンス
タグを開いてみてください。ここに、取得したボディが表示されています。
確認していただければ分かる通り、HTTP レスポンスのボディとして得られるデータは HTML です。もともと、ウェブアプリはウェブブラウザから操作されることを前提とした作りとなっているため、ウェブブラウザでページ表示が行えるよう、HTTP レスポンスのボディは HTML となっています。
そして、この HTML の <table>
~ </table>
の中に、投稿したコメントの情報が含まれており、とりあえずコメント一覧の取得自体は成功していることが確認できると思います。実際に、この HTML をウェブブラウザで表示すれば、コメント一覧のページを表示することができます。
ただ、ウェブブラウザ以外のツール等から取得したコメントを扱うには、この HTML の形式だと不便です。例えば取得したコメントを全て表示するにしても、この HTML の形式のまま出力してしまうと不要なタグ等が表示されてしまいます。
なので、HTML からの必要なデータのみの抽出が必要となります。
今回の場合、下記のような <table>
~ </table>
の中にコメントの投稿者とコメントの本文が存在しますので(少し見やすいように整形しています)、
<table>
<thead>
<tr>
<th>本文</th><th>投稿者</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hello World</td>
<td>Yamada Hanako</td>
</tr>
<tr>
<td>Good bye</td>
<td>Tanaka Jiro</td>
</tr>
<tr>
<td>Nice to meet you</td>
<td>Sato Saburo</td>
</tr>
</tbody>
</table>
下記のように検索を実施していけば、コメントの投稿者とコメントの本文のみを取得することが可能です。そして、これらの取得したデータを扱うようにすれば、不要なタグ等を含まない、必要なデータのみ(コメントの投稿者とコメントの本文のみ)を扱うことができるようになります。
table
タグを検索- 1. で見つかったタグ内から
tbody
タグを検索 - 2. で見つかったタグ内から全ての
tr
タグを検索 - 3. で見つかった各タグ内から全ての
td
タグを検索 - 4. で見つかった各タグのテキストを下記のように取得
- 1つ目の
td
タグのテキスト:「コメント本文」として取得 - 2つ目の
td
タグのテキスト:「コメント投稿者」として取得
- 1つ目の
このデータの取得の具体的な処理に関しては後述で示すスクリプトの中で示していきますが、前述でも紹介した BeautifulSoup
を利用することで、簡単に上記の取得を実現することができます。
ただし、上記のような手順で必要なデータが取得できるのは、今回用意した HTML のような構造である場合のみで、結局 HTML の構造に合わせて取得手順を変更する必要があります。なので、ウェブブラウザ以外からのウェブアプリの操作を実現するためには、例えば先ほど示したような手順で事前にウェブアプリから受信できる HTML の構造を理解しておく必要あります。そして、BeautifulSoup
を利用すれば、それなりに簡単に狙ったデータの取得を実現することができると思います。
コメント一覧の取得の操作についてまとめると、この操作は下記のような HTTP リクエストを送信することで実現できることになります。
URL
:http://localhost:8000/forum/list/
メソッド
:GET
ただし、取得した HTML からコメントの投稿者やコメントの本文等のみを取得したい場合は、別途 HTML の解析を行う必要があります。
少し説明が長くなりましたが、ここまで説明してきたように、HTTP リクエストの送信によってウェブアプリの操作を行うプログラムを開発する際には、ウェブブラウザが実際に送受信している HTTP リクエスト・HTTP レスポンスが参考になります。なので、こういったプログラムを開発する上では、ここで示したような、ウェブブラウザの送受信する HTTP リクエスト・HTTP レスポンスの調べ方は理解しておくとよいと思います!
スポンサーリンク
ツールの開発(CUI)
操作対象のウェブアプリが用意でき、さらにツールが送受信すべき HTTP リクエストや HTTP レスポンスに関しても調べることができましたので、次は、ウェブアプリの操作を行うツールの開発に移りたいと思います。
必要なライブラリのインストール
今回は、HTTP リクエストの送信用のライブラリとして requests
を利用し、さらに HTML 解析用のライブラリとして Beautifulsoup
を利用していきます。
そのため、これらのライブラリが未インストールの方は、事前にライブラリのインストールを行っておいてください。
requests
に関しては下記コマンドで、
python -m pip install requests
Beautifulsoup
に関しては下記コマンドでインストール可能です。
python -m pip install beautifulsoup4
requests
の使い方
一応、簡単に各ライブラリの使い方を説明しておきます。まずは requests
の使い方を解説します。
requests
の基本的な使い方は「HTTP リクエストのメソッドに応じた関数を実行し、その関数の返却値として HTTP レスポンスを受け取る」になります。
この requests
では、HTTP リクエストのメソッド名に応じた関数が定義されています。そして、これらの関数を実行することで、その関数に応じたメソッドの HTTP リクエストを送信することが可能です。今回利用するのは下記の2つの関数になります。
requests.get
:メソッドがGET
の HTTP リクエストを送信するrequests.post
:メソッドがPOST
の HTTP リクエストを送信する
これらの関数の返却値は HTTP レスポンスであり、つまりは、これらの関数は HTTP リクエストの送信だけでなく、その応答となる HTTP レスポンスの受信まで行ってくれます。
また、この返却値の HTTP レスポンスからは、ボディのデータや各種ヘッダーの値を取得することが可能です。例えば、これらの関数の返却値を response
とすれば、HTTP レスポンスの Set-Cookie
の値は response.cookies
で取得できますし、ボディのデータは response.text
で取得可能です。
さらに、これらの関数では url
引数を指定することで、その送信する HTTP リクエストの URL を設定することができます。この url
に指定する URL は、絶対パス形式で指定する必要があります。
他にも、下記のような引数を追加で指定することが可能で、これらの引数の指定によって、送信する HTTP リクエストの内容の詳細を設定することができます。
data
:送信するデータheaders
:ヘッダーにセットするデータcookies
:クッキーにセットするデータ
ウェブブラウザでのフォームからのデータの送信を模擬する場合は、data
には辞書を指定してやれば良いです。それにより、コメント投稿操作時のリクエストとレスポンスを調べる でも示した下図のような、各種フィールドが &
で区切られた形式に変換されたデータが送信されることにになります。
また、allow_redirects
引数によって、HTTP リクエストの送信によってリダイレクトレスポンスを受け取った時に、自動的にリダイレクト先に対する HTTP リクエストを送信するか否かを設定することが可能です。allow_redirects=True
を指定した場合 or デフォルトの場合は、自動的なリダイレクト先への HTTP リクエストの送信が有効となります。この場合は、requests
の関数は、自動的なリダイレクト先への HTTP リクエストに対する HTTP レスポンスを返却することになります。
つまり、allow_redirects=True
を指定した場合 or デフォルトの場合、関数の返却値でリダイレクトレスポンスを受け取ったかどうかを判断できません。それに対し、コメントの投稿の成功 or 失敗は、リダイレクトレスポンスを受け取ったかどうかで判断する必要があるので、コメントの投稿操作を実施する際の HTTP リクエスト送信時には allow_redirects=False
を指定する必要があります。
BeautifulSoup
の使い方
BeautifulSoup
の基本的な使い方は「HTML を解析し、その解析結果から特定のタグを取得する or 特定のタグの情報を取得する」になります。
HTML の解析自体は、BeautifulSoup()
を実行することで実施できます。BeautifulSoup()
は、第1引数に解析対象の HTML を、第2引数に 'html.parser'
を指定して実行します。BeautifulSoup()
の返却値は解析結果のオブジェクトとなり、このオブジェクトに下記のメソッドを実行させることで、HTML から特定のタグを検索して取得することができます。
find
メソッド:引数で指定した条件に合致するタグを HTML の先頭から検索し、最初に見つけたタグのオブジェクトを返却するfind_all
メソッド:引数で指定した条件に合致するタグを HTML から検索し、見つかったタグのオブジェクト全てを要素とするリストを返却する(正確にはリストではないですが、簡単のためリストとして説明します)
さらに、上記のメソッドから返却されるタグのオブジェクトの内側にもタグが存在する場合、取得したタグのオブジェクトに上記のメソッドを実行させることで、その内側のタグのオブジェクトを取得することもできます。これを繰り返すことで、目当てのタグのオブジェクトを取得することができるようになります。
このように、上記のメソッドを駆使して目当てのタグのオブジェクトを取得し、さらに、そのタグのオブジェクトの attrs
データ属性から、そのタグの特定の属性の値を取得したり、get_text
メソッドによって、そのタグのテキストを取得したりする、というのが基本的な BeautifulSoup
の使い方となります。
もちろん、BeautifulSoup
には、もっと様々な使い方で HTML から目当てのデータを取得することが可能なのですが、今回は上記のような基本的な使い方のみで目当てのデータを取得するようにしていきます。
コメントの投稿操作
では、ここから実際にツールを開発していきたいと思います。まずはコメントの投稿操作を実施する関数を定義していきます。
コメント投稿操作時のリクエストとレスポンスを調べる で説明した通り、コメントの投稿操作を実施するためには、下記のような HTTP リクエストを送信する必要があります。
URL
:http://localhost:8000/forum/create/
メソッド
:POST
- ヘッダー:
Cookie
:Set-Cookie
のcsrftoken
★X-CSRFToken
:Set-Cookie
のcsrftoken
★
- ボディ(送信するデータ):
author
フィールド:フォームのAuthor
フィールドに入力された値text
フィールド:フォームのAuthor
フィールドに入力された値
また、上記の★マーク部分の値は、事前に GET
メソッドの HTTP リクエストを送信し、その応答となる HTTP レスポンスから取得する必要があります。そのため、下記の HTTP リクエストを事前に送信し、それに対する HTTP レスポンスを取得してから、上記の HTTP リクエストを送信してコメントの投稿操作を行います。
URL
:http://localhost:8000/forum/create/
メソッド
:GET
このコメントの投稿操作を実施する関数の例は下記の comment_create
となります。comment_create
には、第1引数でコメントの投稿者、第2引数でコメントの本文をそれぞれ文字列で指定する必要があります。
import requests
scheme = 'http://'
hostname = 'localhost:8000'
def comment_create(author, text):
# コメント投稿フォームのURLを作成
url = scheme + hostname + '/forum/create/'
# csrftokenの取得
response = requests.get(url=url)
# 送信するデータを作成
post_data = {
'author': author,
'text': text
}
headers = {
'X-CSRFToken': response.cookies['csrftoken']
}
# コメントの投稿を実施
response = requests.post(
url=url,
data=post_data,
headers=headers,
cookies=response.cookies,
allow_redirects=False
)
# コメント投稿結果を確認
if response.status_code == 302:
result = True
else:
result = False
return result
ここまでの説明の通り、ポイントは最初に requests.get
を実行して response
を取得している点になります。この response
は HTTP レスポンスであり、response.cookies
が、そのレスポンスのヘッダーにおける Set-Cookie
となります。そして、この Set-Cookie
には csrftoken
が設定されていることになります。
そのため、この response.cookies
を、コメントの投稿操作を行う時に実行する requests.post
の cookies
引数にそのまま指定してやれば、下記を満たすことができることになります。
Cookie
:Set-Cookie
のcsrftoken
さらに、response.cookies['csrftoken']
により、Set-Cookie
に設定された csrftoken
の値を取得することが可能です。 そのため、コメントの投稿操作を行う時に実行する requests.post
の headers
引数に {'X-CSRFToken': response.cookies['csrftoken']}
を指定するようにすれば、下記を満たすことができることになります。
X-CSRFToken
:Set-Cookie
のcsrftoken
このように、requests.post
の cookies
引数と headers
引数を指定することで、ウェブアプリに「安全である」と判断される HTTP リクエストを送信することが可能となります。
コメント一覧取得の操作
続いて、コメント一覧の取得の操作を実施する関数を定義していきます。
前述の通り、コメント一覧は下記の HTTP リクエストの送信に対する HTTP レスポンスとして取得することが可能です。
URL
:http://localhost:8000/forum/list/
メソッド
:GET
ただし、このコメント一覧は HTML として取得されることになるので、コメントのみを扱うためには、その HTML を解析して必要なデータのみを抽出することが必要となります。
で、今回取得できる HTML の構造の場合は、下記のように検索を実施していくことで、最終的にコメントの本文とコメントの投稿者を取得することができます。
table
タグを検索- 1. で見つかったタグ内から
tbody
タグを検索 - 2. で見つかったタグ内から全ての
tr
タグを検索 - 3. で見つかった各タグ内から全ての
td
タグを検索 - 4. で見つかった各タグのテキストを下記のように取得
- 1つ目の
td
タグのテキスト:「コメント本文」として取得 - 2つ目の
td
タグのテキスト:「コメント投稿者」として取得
- 1つ目の
今回定義する関数では、投稿済みの全コメントに対して「コメント本文」と「コメント投稿者」のそれぞれを値とする辞書を作成し、それらを要素とするリストを返却するようにしていきたいと思います。
このようなコメント一覧の取得操作を実施する関数の例は、下記の comment_list
となります。また、get_list
は、引数で指定された HTML から各コメントの投稿者と本文のみを抽出し、それらを値とする辞書のリストを返却する関数になります。
import requests
from bs4 import BeautifulSoup
scheme = 'http://'
hostname = 'localhost:8000'
def get_list(html):
# HTMLを解析
soup = BeautifulSoup(html, 'html.parser')
# tableタグを1つ取得
table = soup.find('table')
# 取得したタグ内のtbodyタグを1つ取得
tbody = table.find('tbody')
# 取得したタグ内のtrタグを全て取得
trs = tbody.find_all('tr')
result_list = []
# 各trタグに対するループ
for tr in trs:
# trタグ内のtdタグを全て取得
tds = tr.find_all('td')
# 1つ目のtdタグのテキストを本文として取得
text = tds[0].get_text()
# 2つ目のtdタグのテキストを投稿者として取得
author = tds[1].get_text()
# 投稿者と本文の値をセットした辞書をリストに追加
result_list.append(
{
'author': author,
'text': text
}
)
return result_list
def comment_list():
# コメント一覧のURLを作成
url = scheme + hostname + '/forum/list/'
# コメント一覧を取得
response = requests.get(url=url)
# HTMLを解析してコメントのリストを取得
comments = get_list(response.text)
return comments
コメントの取得自体は requests.get
で実施することになりますが、必要なデータのみを取得するために get_list
関数を実行するようにしています。get_list
関数では、table
→ tbody
→ tr
という風に、目当てのタグまで1段階ずつタグの検索領域を狭める形で必要なデータを抽出するようにしていますが、find
や find_all
を上手く使いこなすことで、もっと簡単に必要なデータのみを抽出することも可能です。また、HTML の各タグに id
を設定すれば、id
を指定して目当てのタグを一度の検索で取得することも可能となり、目当てのタグの取得を楽に実現することができるようになります。
このページでは、このあたりの BeautifulSoup
の使い方の詳細に関しては説明しませんが、まずは BeautifulSoup
を利用することで、HTML の解析・目当てのタグの取得や必要なデータの抽出を行うことが可能であることは是非覚えておいてください。
ツール(CUI)のスクリプト
先ほど示した関数を含め、コメントの投稿操作及びコメント一覧の取得操作を行うツールのスクリプトを下記に示しておきます(分割して示した関数を1つのコードにまとめ、さらに main
関数を追加しただけです)。
import requests
from bs4 import BeautifulSoup
scheme = 'http://'
hostname = 'localhost:8000'
def get_list(html):
# HTMLを解析
soup = BeautifulSoup(html, 'html.parser')
# tableタグを1つ取得
table = soup.find('table')
# 取得したタグ内のtbodyタグを1つ取得
tbody = table.find('tbody')
# 取得したタグ内のtrタグを全て取得
trs = tbody.find_all('tr')
result_list = []
# 各trタグに対するループ
for tr in trs:
# trタグ内のtdタグを全て取得
tds = tr.find_all('td')
# 1つ目のtdタグのテキストを本文として取得
text = tds[0].get_text()
# 2つ目のtdタグのテキストを投稿者として取得
author = tds[1].get_text()
# 投稿者と本文の値をセットした辞書をリストに追加
result_list.append(
{
'author': author,
'text': text
}
)
return result_list
def comment_list():
# コメント一覧のURLを作成
url = scheme + hostname + '/forum/list/'
# コメント一覧を取得
response = requests.get(url=url)
# HTMLを解析してコメントのリストを取得
comments = get_list(response.text)
return comments
def comment_create(author, text):
# コメント投稿フォームのURLを作成
url = scheme + hostname + '/forum/create/'
# csrftokenの取得
response = requests.get(url=url)
csrftoken = response.cookies['csrftoken']
# 送信するデータを作成
post_data = {
'author': author,
'text': text
}
headers = {
'X-CSRFToken': csrftoken
}
# コメントの投稿を実施
response = requests.post(
url=url,
data=post_data,
headers=headers,
cookies=response.cookies,
allow_redirects=False
)
# コメント投稿結果を確認
if response.status_code == 302:
result = True
else:
result = False
return result
def main():
author = input('投稿者:')
comment = input('本文:')
if not comment_create(author, comment):
print('コメント投稿に失敗しました')
return
comments = comment_list()
print(comments)
main()
ツール(CUI)の動作確認
続いて、先ほど作成したツールの動作確認を行っておきましょう!
まず、先ほど示したソースコードを request_tool_cui.py
という名前で保存してください。
続いて、ターミナルやコマンドプロンプト等のコンソールアプリを2つ起動し、一方のコンソールアプリで ウェブアプリの作成と起動 で開発したウェブアプリを起動してください(既に起動済みであれば、この手順は不要です)。ウェブアプリの起動は、プロジェクトフォルダの中で下記を実行することで実施することができます。
% python manage.py runserver
続いて、もう一方のコンソールアプリで、request_tool_cui.py
を保存したフォルダに移動して下記コマンドを実行してください。これにより、先ほど作成したツールが起動することになります。
% python request_tool_cui.py
ツールが起動すると、下記のようにコメント投稿者と本文の入力が促されますので、適当なものを入力してエンターキーを押してください。
投稿者:YamadaHanako 本文:HelloWorld
これにより、これらの入力値を引数として comment_create
が実行され、コメント投稿操作を実施する HTTP リクエストが送信されることになります。さらに、そのコメント投稿操作に成功した場合、続いて comment_list
が実行されてコメント一覧の取得が実施されます。そして、最後に、下記のような各コメントの本文と投稿者を値とする辞書のリストが標準出力に出力されます。この出力されるリストの中に、これまでに投稿したコメントや、先ほどツールから入力したコメントの投稿者・本文が含まれていることが確認できると思います。
[{'author': 'Yamada Taro', 'text': 'こんにちは!'}, {'author': 'Tanaka Jiro', 'text': 'こんばんは!'}, {'author': 'YamadaHanako', 'text': 'HelloWorld'}]
また、下記の URL をウェブブラウザで開いてコメント一覧の内容を確認すれば、先ほど標準出力に出力された結果が、ウェブアプリに表示されるコメント一覧と一致していることが確認できると思います。
http://localhost:8000/forum/list/
つまり、先ほど標準出力に出力されたリストはウェブアプリで管理されているコメントの一覧であり、HTTP リクエストの送信によって、コメントの一覧の取得操作が実施できていることが確認できたことになります。さらに、リストの最後の要素はツールから HTTP リクエストの送信によって投稿したコメントとなりますので、これより、HTTP リクエストの送信によってコメントの投稿操作が実施できたことが確認できたことになります。
このような動作確認結果から、ウェブアプリは、HTTP リクエストの送信によって操作することが可能であることを実感していただけたのではないかと思います。
ウェブアプリ操作用 GUI アプリの開発
次は、先ほど開発したツールを GUI 化(ユーザーインターフェースをグラフィカルにする)していきたいと思います。
ウェブアプリを操作する GUI アプリを開発し、それでウェブアプリを実際に操作してみることで、ウェブブラウザ以外の GUI アプリからウェブアプリを操作可能であること、さらに、それを簡単に自身の手で開発できることを、より深く実感していただけると思います。
今回は、GUI 化は tkinter
によって行います。tkinter
に関しては下記ページで紹介していますので、興味のある方は下記ページを参照してください。
簡単な例を示したいため、今回はコメントの投稿操作のみを行うアプリを開発することとしたいと思います。また、先ほど示した comment_create
はそのまま利用します。なので、プログラムの形態は異なりますが、結局は先ほど動作確認したツールと同様の HTTP リクエストの送信によってウェブアプリの操作を行うことになります。
ウェブアプリ操作用 GUI アプリのソースコード
早速、ウェブアプリ操作用 GUI アプリのソースコードを紹介したいと思います。上記のようなアプリは、次のソースコードにより実現することができます。
import requests
import tkinter
from tkinter import messagebox
scheme = 'http://'
hostname = 'localhost:8000'
def comment_create(author, text):
# コメント投稿フォームのURLを作成
url = scheme + hostname + '/forum/create/'
# csrftokenの取得
response = requests.get(url=url)
csrftoken = response.cookies['csrftoken']
# 送信するデータを作成
post_data = {
'author': author,
'text': text
}
headers = {
'X-CSRFToken': csrftoken
}
# コメントの投稿を実施
response = requests.post(
url=url,
data=post_data,
headers=headers,
cookies=response.cookies,
allow_redirects=False
)
# コメント投稿結果を確認
if response.status_code == 302:
result = True
else:
result = False
return result
class RequestTest:
def __init__(self, master):
self.master = master
self.create_widgets()
def create_widgets(self):
self.label_author = tkinter.Label(
self.master,
text='投稿者',
font=('', 20)
)
self.label_author.grid(column=0, row=0, padx=10, pady=10)
self.label_text = tkinter.Label(
self.master,
text='本文',
font=('', 20)
)
self.label_text.grid(column=0, row=1, padx=10, pady=10)
self.entry_author = tkinter.Entry(
self.master,
font=('', 20)
)
self.entry_author.grid(column=1, row=0, padx=10, pady=10)
self.entry_text = tkinter.Entry(
self.master,
font=('', 20)
)
self.entry_text.grid(column=1, row=1, padx=10, pady=10)
self.send_button = tkinter.Button(
self.master,
text='送信',
font=('', 20),
command=self.post
)
self.send_button.grid(column=0, columnspan=2, row=3, padx=10, pady=10)
def post(self):
author = self.entry_author.get()
text = self.entry_text.get()
if comment_create(author, text):
messagebox.showinfo(
title='コメントの投稿結果',
message='コメントの投稿に成功しました!'
)
else:
messagebox.showerror(
title='コメントの投稿結果',
message='コメントの投稿に失敗しました...'
)
main_window = tkinter.Tk()
app = RequestTest(main_window)
main_window.mainloop()
前述の通り、コメントの投稿操作を行う comment_create
は、コメントの投稿操作 で示したものと同じです。
この関数を、tkinter
を利用して、送信
ボタンがクリックされたときに 投稿者
の入力欄と 本文
の入力欄に入力された文字列を引数に指定して実行するようにしています。
このページでは tkinter
に関する説明は省略させていただきますが、tkinter
の使い方に関しては本サイトの下記で詳しく解説していますので、興味のある方は是非読んでみてください。
https://daeudaeu.com/category/python/tkinter/tkinter_tutorial/
ウェブアプリ操作用 GUI アプリの動作確認
続いて、このスクリプトで起動する GUI アプリの動作確認を行っていきたいと思います。
上記のソースコードを request_tool_gui.py
という名前で保存し、ツール(CUI)の動作確認 のとき同様に、ウェブアプリを起動した状態でコンソールアプリから下記コマンドでスクリプトを実行してみてください。
% python request_tool_gui.py
すると、下図のようなウィンドウが表示されると思います。
そして、このウィンドウの各種フィールドに文字列を入力し、さらに 送信
ボタンをクリックすれば、ウェブアプリに対して HTTP リクエストが送信されてコメントの投稿操作を実施することができます。
ただ、このアプリでは、投稿したコメントを確認することができないので、コメントが投稿できたかどうかはウェブブラウザで下記 URL を開いて確認してみてください。おそらく、各種フィールドに入力したコメントが投稿されていることを確認できるはずです。
http://localhost:8000/forum/list/
今回開発したアプリは見た目も悪く、機能的にも陳腐なものになりますが、それでも、上記の動作確認を通じて、ウェブアプリがウェブブラウザ以外の GUI アプリからも操作可能だという点を感じ取っていただけたのではないかと思います。
また、今回は tkinter
を利用して GUI アプリを開発しましたが、もちろん他のライブラリ・さらには他の言語を利用したアプリからもウェブアプリの操作は可能です。なので、適切な HTTP リクエストの送信を行うようにさえすれば、当然 iOS アプリや Android アプリからも、あなたが開発したウェブアプリの操作が可能ということになります。
ウェブアプリの特徴の1つは、ここまで説明してきたように、HTTP リクエストの送信によって操作できるという点にあります。なので、リクエストの送信さえ行えば、好きなようにフロントサイド(UI)を開発することが可能です。ウェブブラウザからしか操作できなくて物足りなさを感じていた方もおられるかもしれませんが、そうではないので安心してください。
ただし、ウェブアプリは、ウェブブラウザから操作できるという点も重要な特徴の1つであり、これによってユーザーの使用する環境に関わらずウェブアプリの操作が行えるようになっています。なので、まずは、ウェブブラウザから操作されることを前提にウェブアプリを作りこんでいき、ある程度ウェブアプリが開発できたタイミングで、ウェブブラウザ以外からウェブアプリを操作するツールやアプリの開発に取り組んでいけば良いのではないかと思います。
掲示板アプリを HTTP リクエストで操作する
先ほども簡易的な掲示板アプリを作成し、それを HTTP リクエストで操作するツール・アプリを開発してきましたが、次は Django 入門 の連載を通じて開発してきている「掲示板アプリ」を HTTP リクエストで操作する例を示していきたいと思います。
どちらも掲示板アプリであり、ここでも実現するのは、基本的にはコメントの投稿操作とコメント一覧の取得操作となります。なので、Django 入門 の連載を通じて開発してきている「掲示板アプリ」においても、今まで説明してきた内容と同様の手順で、HTTP リクエストでの操作を実現することが可能です(送受信する HTTP リクエストや HTTP レスポンスが多少異なるので、それに合わせた変更は必要となります)。
ただ、今回の操作対象とする掲示板アプリはログイン機能を備えており、このログインを実施しないとコメントの投稿操作やコメント一覧の取得は実施できません。なので、これらの操作を行う前にログイン操作が必要となります。そして、このログインした状態を維持しながら、コメントの投稿操作やコメント一覧の取得を実施する必要があるという点がポイントとなります。
また、今回操作対象とするウェブアプリは、前回の連載の 掲示板アプリで静的ファイルを扱う で開発した掲示板アプリとなります。この掲示板アプリのプロジェクトは下記で公開していますので、必要に応じてこちらからプロジェクトを取得して動作確認に利用してください。
https://github.com/da-eu/django-introduction/releases/tag/django-staticfile
スポンサーリンク
掲示板アプリを操作するツール
ということで、早速掲示板アプリの操作を行うツールのソースコードを紹介していきます。前述の通り、今回ツールから実施できるようにする操作はコメントの投稿とコメント一覧の取得、さらに、これらを行うために事前に実施するログインとなります。
ツールのスクリプト
このツールのスクリプトは下記のようになります。
import requests
from bs4 import BeautifulSoup
scheme = 'http://'
hostname = 'localhost:8000'
def get_list(html):
# HTMLを解析
soup = BeautifulSoup(html, 'html.parser')
# tableタグを1つ取得
table = soup.find('table')
# 取得したタグ内のtbodyタグを1つ取得
tbody = table.find('tbody')
# 取得したタグ内のtrタグを全て取得
trs = tbody.findAll('tr')
result_list = []
# 各trタグに対するループ
for tr in trs:
# trタグ内のtdタグを全て取得
tds = tr.findAll('td')
# 1つ目のtdタグのテキストを本文として取得
text = tds[0].get_text()
# 2つ目のtdタグのテキストを投稿者として取得
author = tds[1].get_text()
# 投稿者と本文の値をセットした辞書をリストに追加
result_list.append(
{
'author': author,
'text': text
}
)
return result_list
def comment_list(session):
# コメント一覧のURLを作成
url = scheme + hostname + '/forum/comments/'
# コメント一覧を取得
i = 1
while True:
url_p = url + '?p=' + str(i+1)
response = session.get(url=url_p)
status_code = response.status_code
if status_code != 200:
break
html = response.text
i += 1
# HTMLを解析してコメントのリストを取得
comments = get_list(html)
return comments
def comment_create(session, text):
# コメント投稿フォームのURLを作成
url = scheme + hostname + '/forum/post/'
# csrftokenを取得
response = session.get(url=url)
headers = {
'X-CSRFToken': response.cookies['csrftoken']
}
# 送信するデータを作成
post_data = {
'text': text
}
# コメントの投稿を実施
response = session.post(
url=url,
data=post_data,
headers=headers,
allow_redirects=False
)
# コメント投稿結果を確認
if response.status_code == 302:
result = True
else:
result = False
return result
def login(session, username, password):
# ログインフォームのURLを作成
url = scheme + hostname + '/forum/login/'
# csrftokenを取得
response = session.get(url=url)
headers = {
'X-CSRFToken': response.cookies['csrftoken']
}
# 送信するデータを作成
post_data = {
'username': username,
'password': password
}
# ログインを実施
response = session.post(
url=url,
data=post_data,
headers=headers,
allow_redirects=False
)
# ログイン結果を確認
if response.status_code == 302:
result = True
else:
result = False
return result
def main():
# セッションオブジェクトを生成
session = requests.Session()
# ログインを最初に実施
username = input('ユーザー名:')
password = input('パスワード:')
if not login(session, username, password):
print('ログインに失敗しました')
return
comment = input('本文:')
# クッキーを保持したセッションオブジェクトでコメント投稿
if not comment_create(session, comment):
print('コメント投稿に失敗しました')
return
# クッキーを保持したセッションオブジェクトでコメント一覧取得
comments = comment_list(session)
print(comments)
main()
ログイン状態を維持したままのリクエストの送信
ウェブアプリの操作を行うツールの開発例 で開発したツールとの決定的な違いは、HTTP リクエストを送信するのを Session
クラスのオブジェクトから実施するようにした点になります。
ウェブアプリの操作を行うツールの開発例 では、下記のように requests
ライブラリが提供する関数を実行するようにしていましたが、
GET
メソッドの HTTP リクエストの送信:requests.get
POST
メソッドの HTTP リクエストの送信:requests.post
今回は下記のように Session
クラスのインスタンスである session
から Session
クラスのメソッドを実行するようにしています。
GET
メソッドの HTTP リクエストの送信:session.get
POST
メソッドの HTTP リクエストの送信:session.post
Django で開発したウェブアプリのログインでは、ログインに成功した場合、ログイン操作を行う HTTP リクエストに対する HTTP レスポンスの Set-Cookie
に、ログイン中であることを示すための sessionid
がセットされるようになります。なので、その sessionid
を Cookie
にセットした HTTP リクエストを送信することで、そのリクエストの送信者がログイン中であると判定され、ログイン中でないと実施不可な操作も実施できるようになります。
ただ、ログイン後の全ての HTTP リクエストの送信時に上記のような Cookie
の設定が必要となって面倒です。
この面倒さを解消するために、上記のスクリプトでは Session
クラスのオブジェクトからメソッドを実行して HTTP リクエストを送信するようにしています。
Session
クラスのインスタンスは、受け取った HTTP レスポンスの Set-Cookie
の値を保持し、次以降の HTTP リクエストの送信時には、その保持した Cookie
を送信するようになっています。なので、ウェブアプリの操作を行うツールの開発例 で示したスクリプトのように、HTTP リクエストの送信時に実行する関数の cookies
引数に、事前に受け取った HTTP レスポンスの Set-Cookie
を指定するような実装が不要となります。
つまり、Session
クラスのインスタンスからメソッドを実行させてログインを実施すれば、後は、そのインスタンスから HTTP リクエストを送信すれば、Cookie
引数を指定しなくても、Cookie
に sessionId
がセットされた状態のリクエストが送信されることになります。そして、HTTP リクエストの送信者はログイン中であるとウェブアプリに判断されることになります。
また、Session
クラスのインスタンスでは、sessionId
だけでなく、HTTP レスポンスで受け取った Set-Cookie
そのものが保持されるため、 csrftoken
の値も保持されることになります。なので、ウェブアプリの操作を行うツールの開発例 で示したスクリプトも、Session
クラスのインスタンスを利用することでもっとシンプルなものにすることが可能です。
ウェブアプリに合わせた変更
後は、ウェブアプリの操作を行うツールの開発例 で示したスクリプトとの違いを簡単に説明しておくと、まずログイン操作を実施しているのは login
関数で、送信するデータは異なるものの、基本的にはコメントの投稿時と同様の処理でログインも実現することができます。
さらに、掲示板アプリでは、コメントの投稿者に関しては「リクエストを送信してきたユーザー」が自動的にセットしてデータベースに保存されるようになっているため、コメント投稿時に送信するデータには author
フィールドは不要となります。
また、掲示板アプリでは、下記ページで解説しているページネーションを利用し、コメントを複数のページに分割して表示するようにしています。最後に投稿したコメントは最後のページに表示されるため、コメントの取得は、最後のページに表示されるコメントに対して実施するようにしています(HTTP リクエストを、404
エラーの HTTP レスポンスが返却されてくるまで繰り返し行い、最後のページに表示されるコメントの一覧のみを取得している)。
このように、ウェブアプリの操作を行うツールの開発例 で開発したウェブアプリと、今回操作対象としているウェブアプリとで、受信することを期待している HTTP リクエストや送信する HTTP レスポンスが違うため、この違いに応じて、ウェブアプリを操作する側のプログラムも、送信する HTTP リクエストや HTTP レスポンスの扱い方の変更が必要となります。
ツールの動作確認
次に、ツールを使って実際にウェブアプリを操作してみましょう!
動作確認の準備
まず、先ほど示したスクリプトを forum_request.py
というファイル名で保存してください。
続いて、コンソールアプリを2つ起動し、一方のコンソールアプリで掲示板アプリを起動してください。掲示板アプリの test_project
フォルダ(上側の階層の test_project
)に移動し、下記コマンドを実行することで掲示板アプリが起動することになります。
% python manage.py runserver
ただし、初めて掲示板アプリを利用するという方は、データベースおよびテーブルを作成するため、上記のコマンドを実行する前に次の2つのコマンドを実行しておく必要があります。
% python manage.py makemigrations
% python manage.py migrate
また、ツールで操作を行うためには、事前にユーザー登録を実施しておく必要があります。このユーザー登録の手順については、下記ページの 動作確認 の節で解説していますので、この節を参考にしてユーザー登録を行っておいてください。
【Django入門10】ログイン機能の実現ログイン
掲示板アプリが起動したら(必要に応じてマイグレーションとユーザー登録も必要)、次は、もう一方のコンソールアプリで forum_request.py
を保存したフォルダに移動し、下記コマンドを実行してください。
% python forum_request.py
このコマンドを実行すると、まずログインを行うためのユーザー名とパスワードが入力されるようになっています。ここには、掲示板アプリで登録したユーザーのユーザー名とパスワードを入力してください。
ユーザー名:username パスワード:password
入力したユーザー名とパスワードでログインに成功した場合は、下記のように、コメントの本文の入力受付が行われるようになっています。
本文:
ログインに失敗した場合は、下記のように、ログインに失敗したことを示すメッセージが出力されてツールが終了するようになっていますので、この場合はユーザー名とパスワードの見直しを行ってください(パスワード等を忘れた場合は、ウェブブラウザから新たにユーザーを登録し、その登録したユーザーでログインするのが早いと思います)。
ログインに失敗しました
また、下記のような例外が発生した場合、そもそも掲示板アプリが起動していない可能性があるので、前述で示した runserver
コマンドが実行中であるかどうかを確認してみてください。
対象のコンピューターによって拒否されたため、接続できませんでした。
コメントの投稿とコメント一覧の取得
前述の通り、ログインに成功した場合は、下記のように投稿するコメント本文の入力受付が行われます。次は、ここに文字列を入力し、実際にコメントの投稿を行ってみてください。
本文:
本文を入力してエンターキーを押せば、コメント投稿操作を行う HTTP リクエストが送信され、コメントの投稿が行われることになります。さらに、続けてコメント一覧の取得操作を行う HTTP リクエストが送信され、取得したコメントの一覧が、辞書を要素とするリストとして標準出力に出力されます。
[{'author': 'TanakaJiro', 'text': 'Good bye'}, {'author': 'YamadaHanako', 'text': 'Hello world'}]
この出力されるリストの最後が、投稿したコメントのものと一致していれば、コメントの投稿操作及びコメントの一覧取得操作を HTTP リクエストの送信によって実施できたことが確認できたことになります。
前述の通り、この掲示板アプリでは、投稿済みコメントが複数のページに分割して表示されるようになっており、先ほど作成したツールからは最後のページに表示されるコメントの一覧のみの取得が行われることになります。なので、投稿済みのコメントに対して取得できるコメントの数が少ない場合がありますが、そういう作りとしているだけで、ツールやウェブアプリに不備があるというわけではないので安心してください。
また、今回はコメントの投稿とコメント一覧の取得(&ログイン)のみを実施するツールの紹介を行いましたが、もちろん、掲示板アプリに実装されている機能(例えばコメントの更新やコメントの削除など)であれば、それらも HTTP リクエストの送信によって実施することが可能です。
現状の掲示板アプリの課題
ということで、Django 入門 の連載を通じて開発してきている「掲示板アプリ」も HTTP リクエストの送信によって操作可能であることが確認できました。もちろん、この掲示板アプリだけでなく、どんなウェブアプリでも HTTP リクエストの送信によって操作可能です。そもそも、HTTP リクエストの送信によって操作可能でなければ、ウェブブラウザからの操作も行えないことになりますので…。
ただ、この掲示板アプリのように、HTTP リクエストの応答となる HTTP レスポンスによって取得できるデータが HTML の場合、その HTML を解析して必要なデータを抽出する処理が必要となり、ウェブブラウザ以外からのウェブアプリの操作の実装が複雑になります。
なので、ウェブブラウザ以外からの操作を想定するウェブアプリでは、HTML 以外のデータを取得可能な API を用意しておくことが多いです。例えば、その API から JSON 形式のデータを返却できるようにしておき、さらに必要なデータのみをそのデータに含ませるようにしておけば、HTML の解析が不要になってウェブブラウザ以外からの操作が容易になります。また、データの送信を行う API においては、送信するデータも JSON 形式とすることで、ウェブアプリの入力と出力のデータの形式が統一され、さらに操作しやすいウェブアプリとなります。
そして、このような API を公開することで、そのウェブブラウザ操作用のツールや iOS アプリ・Android アプリも開発が容易になりますし、ウェブブラウザでのページ表示においても、JavaScript を導入して API を利用することで、ページ内の特定のデータを定期的に更新したり、さらに JavaScript からのデータの送信も容易に実現できるようになります。要は、API を提供することで、ウェブブラウザ以外からの操作が容易となります。
ということで、次は、この API を Django で開発するウェブアプリから提供する方法について解説していきたいと思います!
スポンサーリンク
まとめ
このページでは、ウェブアプリのウェブブラウザ以外からの操作について解説しました!
ウェブアプリは、HTTP リクエストの送信によって操作することが可能で、この特徴を利用することで、ウェブアプリを iOS アプリや Android アプリ等からも操作することができるようになります。このページの内容で一番覚えておいていただきたいのは、この点になります。
また、特に Django で開発するウェブアプリは CSRF 対策が施されているため、データの送信操作を行う際にはヘッダー・クッキーを適切に設定して HTTP リクエストを送信する必要があります。このあたりのポイントもしっかり覚えておきましょう!
ただし、特にウェブアプリに対してデータの取得操作を行う場合、取得できるデータが HTML だと、その操作側でのデータの扱いが複雑になります。具体的には、その HTML を解析して必要なデータを取得する処理が必要となります。
なので、ウェブブラウザ以外からの操作を想定したウェブアプリでは API を提供し、その API を使ってウェブアプリを操作してもらうようにすることが多いです。次は、この API について解説していきますので、是非次回の連載も読んでみてください!