このページでは Python の requests
モジュールについて解説していきます。
まず、requests
モジュールを使いこなす上で必要となる知識に関するに説明を行い、その後に requests
モジュールの使い方について解説していきます。
requests
モジュール
まずは、requests
モジュールの概要について説明しておきます。
requests
モジュールの概要
requests
とはズバリ、HTTP リクエストを送信し、それに対する HTTP レスポンスを受信する機能を提供するモジュールとなります。
サーバーとクライアントの関係で考えれば、requests
は HTTP クライアントの開発に適したモジュールとなります。Python スクリプトから requests
モジュールを利用すれば、HTTP サーバーに対して HTTP リクエストを送信し、さらに HTTP サーバーから HTTP レスポンスを受信する処理が簡単に実現できます。
以降では、HTTP リクエストのことを単に “リクエスト”、HTTP レスポンスのことを単に “レスポンス”、HTTP クライアントのことを “クライアント”、HTTP サーバーのことを “サーバー” と示します。
例えばウェブページの表示は、リクエストの送信とレスポンスの受信を行うことによって実現されています。このウェブページの表示の場合、ユーザーのウェブブラウザへの操作に応じてウェブブラウザが自動的にサーバーへリクエストを送信してくれます。そして、そのリクエストに対するレスポンスをウェブブラウザがサーバーから受信し、それをウェブブラウザがページとして描画することでページの表示が行われることになります。
また、表示だけでなくウェブサーバーへのデータの登録などもリクエストの送信によって実現されています。例えば掲示板への投稿に関しても投稿内容を含むデータとしてリクエストを送信することで実現されます。
そして、requests
モジュールは、こういったリクエストの送信とレスポンスの受信の機能を提供するモジュールであり、Python スクリプトから requests
の関数を実行するだけで、これらの送信・受信を実現することが可能となります。
ただ、requests
モジュールにはページを描画するような機能は存在しません。リクエストを生成して送信し、そのレスポンスを受信するまでが requests
モジュールの役割となります。
スポンサーリンク
requests
モジュールの用途
続いて、この requests
モジュールの用途について説明します。
ウェブスクレイピング
この requests
モジュールの用途の1つはウェブスクレイピングです。上記のようにページを表示するためのデータの取得をリクエストすると、レスポンスとして HTML を受信することができます。そして、その HTML を解析して必要な情報を収集することを「ウェブスクレイピング」と呼びます。
ウェブアプリの動作確認
また、用途の2つ目としては「ウェブアプリの動作確認」が挙げられます。ウェブアプリは、ユーザーの操作内容をリクエストとしてサーバーに送信し、その応答をレスポンスとして受信することを繰り返すことで、ユーザーとのインタラクティブなやりとりを実現するアプリとなります。
一般的には、ウェブブラウザをユーザーが操作し、その操作内容に応じたリクエストをウェブブラウザがサーバーに送信することになるのですが、その時に送信されるリクエストと同じものを requests
モジュールから直接送信しても同様の結果が得られることになります。なので、ユーザー操作なしにウェブアプリを動作させることも可能となります。
requests
モジュールを利用するメリット
特に requests
モジュールを利用することで、これらが自動的に実行できるようになるというメリットが得られます。
例えばウェブスクレイピングであれば、ウェブブラウザからリクエストを送信して目的のページを表示し、そのページの表示内容から自身が収集したい情報をメモ帳などにコピペすることで実現することも可能です。ですが、これを行うためには人手が必要になります。
それに対し、Python スクリプトからリクエストを送信してレスポンスを受信し、その受信したレスポンスを解析して自身が収集したい情報をテキストファイルなどに出力するようにすれば、ウェブスクレイピングが Python スクリプトを実行するだけで自動で行えるようになります(ただし、レスポンスを解析するためには requests
モジュールとは別のモジュールを利用する必要があります)。
ウェブアプリの動作確認に関しても同様で、通常はテスト担当者がウェブブラウザを手動で操作して目視で結果を確認するような作業を、requests
モジュールを利用して自動的にリクエストの送信とレスポンスの解析を行うようにすることで自動化するようなことも可能です。
こんな感じで、requests
モジュールを利用するメリットはウェブブラウザの操作なしにサーバーとのリクエストやレスポンスのやりとりを実行できるようになるという点になります。そして、それによって様々な作業の自動化を行うことが可能です。
リクエストとレスポンス
続いて、ここまで何度も登場してきた「リクエスト」と「レスポンス」について解説していきます。この辺りの知識を身につけておけば、自然と requests
モジュールを使いこなすために必要なことが理解できるようになります。
スポンサーリンク
リクエスト
まず、リクエストとは “特定のフォーマットのデータ” のことを言います。そして、リクエストとは、日本語に直訳すると分かるように「要求」のことを言います。
リクエストのデータフォーマット
つまり、リクエストとはサーバーに対して要求するための特定のフォーマットの単なるデータです。そして、そのデータの中身で「要求する内容」をサーバーに伝えます。サーバーはリクエストを受け取ると、その要求する内容に応じた結果を表すデータをサーバーに返却します。このデータが、後述で解説するレスポンスになります。
そして、リクエストは下の図のようなフォーマットのデータとなります。requests
モジュールを使いこなす上で一番重要になるのがリクエストラインです。
リクエストライン
「リクエストライン」は下記のようなフォーマットのデータとなります。このデータが大まかな「要求する内容」を表しており、パス
でリクエスト先、メソッド
でリクエストの目的を指定します(HTTP/1.1
の 1.1
部分で HTTP のバージョンも指定可能ですが、このページでは 1.1
固定で考えていきます)。
メソッド パス HTTP/1.1
この パス
は URL をルートパス形式で表したものになります。例えば、今現在開いているページを表示する場合、このページの URL は https://daeudaeu.com/python-requests/
なので、リクエストラインのパス部には /python-requests/
を指定することになります。実は、このサイトには今表示しているページだけでなく、様々なページが存在しています。その中からどのページを要求するのかを /python-requests/
で指定するというわけです。
メソッド
また、メソッド
には下記のようなものが存在します。まず覚えておくべきは GET
とPOST
です。この2つは利用する機会が非常に多いです。特にウェブスクレイピングを行う上では GET
は必須です。他のメソッドに関しては API などを実行する際やウェブアプリを開発する際などに利用することもあるかもしれませんが、それ以外は現状あまり利用する機会はないのではないかと思います。
GET
:パス
のデータの取得を要求HEAD
:リクエストライン&ヘッダーフィールドの取得のみを要求POST
:送信したデータを新規登録することを要求(送信データに応じた処理の実行を要求)PUT
:送信したデータでパス
のデータを置き換えることを要求PATCH
:送信したデータでパス
のデータの一部をき換えることを要求DELETE
:パス
のデータを削除することを要求OPTIONS
:許可されているオプションの一覧(メソッドの一覧)を要求
まずは、データの取得を行うメソッドが GET
で、データの送信を行うメソッドが POST
であるくらいで覚えておくと良いです。他のメソッドに関しては、今後必要に応じて覚えていくスタンスで良いと思います。
例えばウェブブラウザが単にページの表示を行うような場合、ページを表示するためのデータの取得を行うためのリクエストが送信されることになりますので、メソッド
には GET
を指定されることになります。そして、パス
には表示したいページの URL に対応するパスが設定されます。
特にメソッドが GET
の場合、このリクエストラインによってリクエストの要求内容の大部分が決まることになり、そのリクエストラインがセットされたデータを受信したサーバーは、そのデータをリクエストとみなし、そのリクエストに応じた処理を実施してレスポンスを返却することになります。
ヘッダーフィールドとボディ
また、リクエストにはリクエストラインだけでなく「ヘッダーフィールド」や「ボディ」も存在します。ヘッダーフィールドは簡単に言ってしまえばリクエストのデータの詳細を伝えるためのデータです。
ボディはウェブアプリ等に登録するデータやアップロードするデータ等に相当します。分かりやすい例で言えば、掲示板へのコメントの投稿は、投稿するコメントの本文をこのボディにセットしたリクエストを送信することで実現されます。
特に POST
メソッドや PUT
メソッド、PATCH
メソッドのリクエストは “データの登録” や “データの置き換え” 等を要求するリクエストになりますので、登録するデータや置き換え先のデータを指定するために、こういったデータをボディにセットしたリクエストを送信することが必要になることが多いです。
リクエストの送信先
さて、ここまでリクエストのデータに注目して解説してきましたが、このデータはどこに送信されるのでしょうか?
このリクエストの送信先はサーバーとなります。もう少し具体的に言えば HTTP サーバーやウェブサーバーのソフトが動作しているサーバーマシンとなります。そして、送信先となるサーバーは IP アドレスやドメイン名によって指定されることになります。例えば、ウェブブラウザで https://google.com
のページを表示する場合には下記のようなリクエストラインを持つ HTTP リクエストがウェブブラウザから送信されることになります。
GET / HTTP/1.1
そして、送信先となるサーバーは google.com
というドメイン名によって決まります。もっと正確にいうと、このドメイン名を DNS という仕組みによって IP アドレスに変換し、その IP アドレスのサーバーに対して上記リクエストが送信されることになります。
ここで説明したようなリクエストのデータの送信を requests
モジュールで実現する手順については後述で解説していきますが、まずここで覚えておいていただきたい点は、リクエストを送信するためにはパスやメソッド、送信先のドメイン(IP アドレス)等の様々な情報が必要になるという点になります。要求したいことによってはボディも必要となります(ヘッダーフィールドも)。
こういった情報は、当然 requests
モジュールを利用してリクエストを送信する際にも必要となりますので、これらの情報を何らかの方法で requests
モジュールに対して指定する必要があります。そのため、リクエストのデータの構成やリクエストを送信するために必要な情報を大雑把でも良いので覚えておくと、requests
モジュールを利用したスクリプトを記述する際に、どういった情報を引数にセットしたりする必要があるのかが自然と思いつくようになると思います。
レスポンス
次はレスポンスについて解説していきます。
レスポンスのデータフォーマット
レスポンスはリクエストに対する返事であり、リクエストのデータで指定された要求に対する応答を表すデータとなります。このレスポンスも、リクエストと同様に結局は特定のフォーマットのデータとなります。
そして、このレスポンスは下の図のようなフォーマットのデータとなります。
このレスポンスのデータでポイントになるのが「ステータスライン」と「ボディ」になると思います。ヘッダーに関しては HTTP リクエストと同様でレスポンスのデータの詳細を伝えるためのデータとなります。
ステータスライン
まず、ステータスラインではリクエストに対する結果が伝えられます。このステータスラインは下記のようなフォーマットのデータとなります。
HTTP/1.1 ステータスコード 理由
サーバーはどんなリクエストも受け付けられるわけではありません。リクエストの内容によってはエラーになることもあります。そのため、リクエストの結果をステータスラインの ステータスコード
で示されるようになっています。例えば ステータスコード
には下記のようなものが存在します。コロンの右側にはそのステータスコードに対応する 理由
を示しています。
200
:OK
301
:Moved Permanently
400
:Bad Request
401
:Unauthorized
404
:Not Found
500
:Internal Server Error
この ステータスコード
や 理由
によってレスポンスの受信者はエラーの理由を知ることができます。例えば 400
エラーが発生したのであれば、リクエストのボディが不正であると判断されている可能性が高いため、ボディの見直しをして再度リクエストを送信すれば良いことになります。
ボディ
また、レスポンスのボディはクライアントからリクエストされたデータそのものであったり、リクエストに応えられたかどうかを示すメッセージのデータなどがセットされます。分かりやすいのが GET
メソッドのリクエストに対するレスポンスのボディで、GET
の場合はデータの要求を目的にリクエストが送信され、その要求されたデータがレスポンスのボディとして返却されることになります。
例えばウェブページを表示するために GET
メソッドのリクエストを送信した場合、レスポンスのボディとして、そのページを表示するための HTML を受け取るような感じです。
requests
とリクエスト / レスポンス
ここまで説明してきたように、リクエストとレスポンスは単に特定のフォーマットのデータです(このフォーマットは HTTP というプロトコルによって定められています)。
つまり、どんなクライアント(アプリやツールやモジュール)から送信されるのかに関わらず、その特定のフォーマットのデータを作成してサーバーに送信さえすれば、サーバーはリクエストの内容に応じた処理を行いますし、サーバーからレスポンスを受信することもできます。
そして、そのレスポンスも前述で紹介したフォーマットのデータになっています。ですので、ウェブブラウザを利用しなくても、リクエストのフォーマットのデータを生成してサーバーに送信してやれば、サーバーからレスポンスのフォーマットのデータを受信することができ、そのボディからウェブブラウザがウェブページを表示するためのデータを取得するようなことも可能です。
ウェブブラウザを利用する場合、どうしても手動で操作を行うケースが多くなってしまいますが、Python スクリプトからリクエストを生成するようにしてやれば、サーバーへのリクエストの送信からレスポンス受信までを自動的に行うようなことも可能となります(レスポンスを受信するだけではあまり意味がないので、受信したデータの解析までを自動化することの方が多いです)。
ですが、フォーマットがややこしく、自身でリクエストのデータを生成するのは大変そうですね…。特にプログラミング初心者の方がプログラムでこういったデータを作成しようと思うと結構苦労するのではないかと思います..。
ただ、安心してください!こういった大変そうな作業を簡単に行うためのモジュールが Python にはたくさん用意されています。そして、そのモジュールの1つが requests
になります。
requests
の関数を利用すれば、関数や引数に応じてリクエストのフォーマットのデータが自動的に生成され、引数に応じたサーバーに自動的に送信されるようになっています。
また、サーバーからのレスポンスの受信も関数の中で行われ、そのレスポンスのデータを Python から扱いやすい形式のデータ、具体的には Response
というクラスのインスタンスとして返却してくれます。requests
を利用する Python スクリプトでは、そのインスタンスのデータ属性から、レスポンス で説明したレスポンスのデータに含まれる情報を取得するようなことができます。
そのため、リクエストの生成及び送信からレスポンスの受信までの処理は requests
の関数の実行のみで実現可能です。あとはリクエストの内容に応じて関数に指定する引数を指定したり、実行する関数を使い分けてやれば良いだけです。
そして、requests
モジュールから Response
のインスタンスを受け取りさえすれば、あとはそのインスタンスのデータ属性を利用して、例えばウェブスクレイピングやウェブアプリの動作確認など、あなたの目的に応じた処理を実施してやれば良いことになります。
スポンサーリンク
requests
の使い方
前置きが長くなってしまいましたが、次は requests
モジュールの使い方について解説していきます。
requests
モジュール使用時の手順は下記のようになります。
- (初回のみ:
requests
のインストール) requests
のimport
requests
の関数実行requests
の関数の返却値を利用した処理
requests
のインストール
requests
は Python の標準モジュールではありません。インストールの仕方やインストールしたパッケージ等によっても異なるかもしれませんが、基本的には Python をインストールするだけでは requests
モジュールは利用できないため、別途インストールから実施する必要があります。
ただ、requests
のインストールは簡単で、他のモジュール同様に pip
コマンドからインストールすることが可能です。
具体的には下記のコマンドでインストールが可能です。
% python -m pip install requests
requests
の import
requests
の使い方に関してもシンプルで、requests
を import
し、さらに requests
から提供される関数を実行することで requests
を利用することになります。
import
に関しては、下記のように単純に requests
モジュールを import
すれば良いだけです。
import requests
スポンサーリンク
requests
の関数の実行
続いて requests
から提供される関数の実行を行っていきます。requests
から提供される関数を実行することでリクエストのデータの生成および送信が行われ、さらにレスポンスが返却値として返却されることになります。
ただ、リクエストしたい内容やリクエスト先のサーバーに応じた引数の指定や関数の使い分けが必要となりますので、この辺りについて説明していきます。
まず、バージョン 2.31.0 の requests
から提供される関数には下記のようなものが存在します。
get
:GET
メソッドの HTTP リクエストを送信するpost
:POST
メソッドの HTTP リクエストを送信するput
:PUT
メソッドの HTTP リクエストを送信するpatch
:PATCH
メソッドの HTTP リクエストを送信するoptions
:OPTIONS
メソッドの HTTP リクエストを送信するhead
:HEAD
メソッドの HTTP リクエストを送信するdelete
:DELETE
メソッドの HTTP リクエストを送信するrequest
:引数で指定されたメソッドの HTTP リクエストを送信する
メソッドに応じて関数を呼び分ける
このように、request
関数を除いて、requests
の関数はメソッドに対応する形で用意されています。なので、送信したいメソッドに応じて関数を使い分ければ良いことになります。
前述の通り、requests
から提供される関数を実行することでリクエストのデータの生成が行われますが、このデータのリクエストラインのメソッド部分は実行する関数に応じて設定されるようになっています。
例えば GET
メソッドのリクエストを送信したいのであれば get
関数を実行すれば良いことになります。これにより、リクエストラインのメソッド部分が GET
に設定されたリクエストのデータが get
関数の中で生成されることになります。
import requests
requests.get(引数)
また、request
関数に関しては第1引数でメソッドを指定することが可能となっており、この関数を利用して特定のメソッドの HTTP リクエストを送信することも可能となっています。中身的な話をすると、request
以外の関数が実行された際には、その関数の中から結局 request
関数が呼び出されるようになっていますので、request
以外の関数を利用した場合も、request
関数を利用した場合も、結局は実行される処理に大きな違いはありません。
送信先とパスを指定する
さらに、request
関数を除く全関数において、第1引数では URL を指定することになっています(request
関数では第2引数で指定する)。
ここで指定する URL の基本的な形式は下記となります。ドメイン名
の部分は IP アドレスになったりポート番号を追加で指定したりする必要がある場合もありますが、基本的には下記の形式と考えて良いと思います。
スキーム://ドメイン名/パス
スキーム
には http
と https
のどちらかを指定します。一般的にはスキームには http
や https
以外にも ftp
などの様々な種類のものが存在しますが requests
モジュールが対応しているのは http
or https
のみになります。どちらを指定すべきかは、リクエストの送信先のサーバーやサイト等によって異なります。例えば、http
のみに対応しているウェブアプリの場合は必然的にスキームに http
を指定する必要があることになります。
ドメイン名
にはリクエスト送信先となるドメインの名前を指定します。このドメイン名が IP アドレスに変換され、その IP アドレスのサーバーにリクエストが送信されることになります。前述の通り、ここには IP アドレスを直接指定することも可能です。
パス
にはリクエストラインのパス部分に設定するためのパスを指定します。
つまり、requests
モジュールの関数の第1引数に URL を指定すれば、下記のようにリクエストラインのパス部分に URL の パス
が設定されることになります。
そして、このリクエストラインを含むリクエストのデータが、第1引数に指定された URL の ドメイン名
に対応するサーバーに送信されることになります。
例えば、今現在表示しているページの表示を行うデータを取得するためにリクエストを送信するのであれば、get
関数を下記のように実行することになります。
import requests
url = 'https://daeudaeu.com/python-requests/'
requests.get(url)
これにより、下図のように daeudaeu.com
のドメインに対応する IP アドレスのサーバーに対して下図で示すリクエストが送信されることになります。
返却値としてレスポンスを取得する
requests
モジュールの関数を実行した際には、返却値としてレスポンスに対応するデータが取得できることになります。単にリクエストを送信したいだけであれば requests
モジュールの関数から返却値を受け取る必要はありませんが、リクエストの送信結果として得られるレスポンスを利用したいような場合、requests
モジュールの関数から返却値を受け取り、その返却値に対して処理を行う必要があります。
import requests
url = 'https://daeudaeu.com/python-requests/'
response = requests.get(url)
# responseを利用した処理
requests
モジュールの関数の返却値は、具体的には Response
というクラスのインスタンスとなります。
そして、このインスタンスのデータ属性から、レスポンスとして受け取ったデータにセットされている各種情報を取得することができます。このインスタンスの持つデータ属性の例を下記に示します。
status_code
:ステータスコードreason
:エラーが発生した理由(status_code
が200
の場合は'ok'
となる)headers
:ヘッダーの情報(辞書データ)content
:ボディ(バイトデータ)text
:content
を文字列に変換した結果
例えばウェブページの HTML を解析したい場合、GET
メソッドでリクエストを送信し、その送信結果として得られるレスポンスのボディのデータを解析することになります。したがって、上記における content
や text
からデータを取得し、そのデータを解析することになります。
また、リクエスト自体が成功したかどうかは status_code
から確認することが可能です。レスポンスの情報の詳細を知りたい場合は headers
の辞書データを参照することも可能です。
このように、requests
モジュールの関数では関数の返却値としてレスポンスを受け取ることが可能で、その返却値のデータ属性からレスポンスのデータの様々な情報を取得することができるようになっています。
必要に応じて他の引数を指定する
特に GET
メソッドや HEAD
メソッドのリクエストを送信する場合は、すなわち requests.get
や requests.head
を実行する場合は、ここまで説明してきたように関数の第1引数に URL を指定してやれば多くの場合で上手くレスポンスの受信までを実現することができると思います。
それに対し、POST
メソッドや PUT
メソッド等のリクエストを送信する場合、すなわち requests.post
や requests.put
を実行する場合は、関数の第1引数に URL を指定するだけでなく、送信対象のデータも用意し、そのデータを data
引数に指定することも必要となることが多いです。
これらのメソッドはデータの新規登録や置き換えをリクエストするためのメソッドであり、その新規登録対象や置き換え対象となるデータもボディとして送信してやる必要があります。そしてこの場合、そのボディとなるデータを関数実行時に引数として指定してやる必要があります。
このサーバーに送信されるデータの型は一般的にバイナリとなります。ただし、requests
モジュールは data
引数に指定されたデータをバイナリに変換する機能を所持しており、data
引数には辞書やリスト等を指定することが可能となっています。そして、data
引数を指定することで、指定された引数のデータのバイナリ変換後のデータがボディにセットされた状態でリクエストが送信されることになります。
例えば下記のように post
関数を実行すれば、data
引数に指定した辞書がバイナリに変換され、それがリクエストのデータのボディにセットされた状態でリクエストとしてサーバーに送信されることになります(url
はてきとうになっているので注意してください)。
import requests
url = 'http://127.0.0.1:8000/'
data = {
'username': 'YamadaTaro',
'email': 'taro@example.com'
}
response = requests.post(url, data=data)
post
関数等で送信するデータの中身のフォーマットはサーバー上で動作するウェブアプリ等によって異なるので注意してください。フォームからのデータの送信を post
関数で代替したいような場合は上記のように辞書を data
引数に指定することが多いと思いますが、REST API で JSON を受け付けるような IF になっている可能性もあります。そのため、どういったデータをウェブアプリが受け付けるようになっているかをあらかじめ調べてからスクリプトを記述した方が良いと思います。
こういった post
関数の利用例については別途ページを用意して紹介しようと思いますので、まずは上記のように data
引数の指定によってボディを設定できることは是非覚えておいてください。
requests
の利用例
続いて簡単な requests
モジュールの利用例を示しておきたいと思います。
実現すること
今回は、下記 URL のページに表示される「記事のタイトル一覧」を取得する例を示していきたいと思います。
https://daeudaeu.com/?s=python
上記 URL は、このサイトのページの右上にある検索バーから「python
」と検索したときに表示されるページで、要はタイトルに python
が含まれる記事の一覧を示すページとなります。
このページに表示される記事のタイトルを抽出する例を示していきます。
スポンサーリンク
送信するリクエストのリクエストライン
ちなみに、上記で示した URL の ?
以降の部分はクエリパラメーターと呼ばれるパラメーターになります。例えば Google で検索した際にもクエリパラメーター ?q=検索文字列
が付加されるようになっており、このクエリパラメーターでリクエストの内容の詳細をサーバーに伝えられるようになっています。
で、今回の場合のクエリパラメーター s
は検索文字列を指定するパラメーターとなっています。このクエリパラメーターはリクエストラインのパスに付加される形でリクエストのデータにセットされることになります。つまり、上記の URL をウェブブラウザで開いた場合、GET
メソッドのリクエストが daeudaeu.com
のサーバーに送信され、そのリクエストラインは下記のようになります。
GET /?s=python HTTP/1.1
こういったクエリパラメーターも requests
では関数の引数で指定できるようになっており、上記のようなリクエストラインを含むリクエストも requests
の関数から送信可能となっています。今回はページの HTML を取得し、それを解析して記事のタイトル一覧を抽出することになるため、GET
メソッドのリクエストを送信する get
関数を利用して上記のリクエストを送信するようにしていきます。
そして、その get
関数の返却値としてレスポンスのデータを取得し、そのボディの HTML の解析を行なって記事のタイトル一覧を抽出していく例を示していきます。
解析するページの HTML 構造
その解析手順の概略について説明しておきます。
先ほど示した URL のページの HTML では、検索結果として表示されている記事のタイトルは全て <h2>記事のタイトル</h2>
という形式のタグで表現されるようになっています。この HTML の構造を簡略化したものが下記となります。
<article>
<a>
<div>
<h2>記事のタイトル1</h2>
</div>
</a>
</article>
<article>
<a>
<div>
<h2>記事のタイトル2</h2>
</div>
</a>
</article>
<article>
<a>
<div>
<h2>記事のタイトル3</h2>
</div>
</a>
</article>
〜略〜
そのため、レスポンスのボディとして得られる HTML の中から <h2>
と </h2>
で囲まれる文字列を全て抽出してやれば、やりたことが実現できることになります。
requests
の利用例のスクリプト
そして、これらを実現するためのスクリプトの例は下記となります。
import requests
import re
url = 'https://daeudaeu.com/'
query = {
's' : 'python'
}
response = requests.get(url, params=query)
if response.status_code != 200:
print(response.reason + 'のためリクエストに失敗しました...')
else:
titles = re.findall(r'<h2>([^<>]+)</h2>', response.text)
print(titles)
スポンサーリンク
スクリプトの解析
スクリプトの解説を行なっておきます。
requests
の import
まず、requests
モジュールの利用箇所に注目していくと、最初に requests
の import
を行なっていることが確認できると思います。requests
を利用する場合は、他のモジュール同様に最初に requests
の import
を行なっておく必要があります。
URL の設定
続いて、url
の設定を行なっています。url
は https://daeudaeu.com/
で、https
部分がスキーム、daeudaeu.com
がドメイン名 /
がパスとなります。ちなみに、私のサイトの場合はスキームが http
の場合はリダイレクトされてスキームが https
に自動的に変更されるようになっているため、urls
に http://daeudaeu.com/
を指定しても同様の結果が得られると思います。
クエリパラメーターの設定
さらに、query
変数にクエリパラメーターとなる辞書データをセットしています。この辞書データを get
関数の params
引数に指定してやれば、その辞書データのキー名がクエリパラメーターの変数名、値がその変数の値として扱われることになります。従って、上記のような query
を params
引数に指定した場合、クエリパラメーターとして s=python
がセットされることになります。ちなみに、辞書に複数の要素を持たせておくことで複数のクエリパラメーターを指定することも可能です。
リクエストの送信
ここまでが関数を実行するまでの準備で、準備が整った後に用意した変数を引数に指定して get
関数の実行を行っています。ここで送信されるリクエストのリクエストラインは下記のようなものになります。そして、送信先は daeudaeu.com
のサーバーとなります。
レスポンスの受信
このリクエストラインを受け取ったサーバーがリクエストに応じた処理を実行し、リクエストされたデータをレスポンスとして返却します。そして、そのレスポンスの受信も get
関数の中で実施され、受信したレスポンスのデータは get
関数の返却値として受け取ることができます。上記の場合は response
がレスポンスを参照することになり、この参照するデータ(get
から返却されるデータ)の実体は Response
というクラスのインスタンスとなります。
レスポンスのステータスコードの確認
そして、そのインスタンスのデータ属性 status_code
から受信したレスポンスのステータスコードを確認し、OK を示す 200
以外の場合はデータ属性 reason
よりエラーの理由を示してプログラムを終了するようにしています。
status_code
が 200
の場合はデータ属性 text
の解析を実施しています。
ここまでが主に requests
モジュールを利用した処理の流れとなります。こんな感じで requests
モジュールの役割はリクエストを送信し、さらにリクエストを受信して Response
というクラスのインスタンスとして関数実行元に返却することが役割となります。それ以外は別のモジュールの役割となり、今やろうとしている HTML の解析も別のモジュールを利用して実施する必要があります。
レスポンスのボディの解析
そして、今回は res
という正規表現を扱うモジュールにより、その HTML の解析を実施しています。
前述の通り、今回解析対象となる HTML では「タイトルに python
が含まれる記事」のタイトルが下記のように <h2>
〜 </h2>
の間に記載されていることになります。
<article>
<a>
<div>
<h2>記事のタイトル1</h2>
</div>
</a>
</article>
<article>
<a>
<div>
<h2>記事のタイトル2</h2>
</div>
</a>
</article>
<article>
<a>
<div>
<h2>記事のタイトル3</h2>
</div>
</a>
</article>
〜略〜
そのため、HTML から <h2>([^<>]+)</h2>
のパターンと一致する部分を検索し、(
〜 )
に囲まれる文字列のみを全て取得するような処理を上記のスクリプトで行うようにしています。
res
で扱う正規表現において、[^<>]
は <
と >
以外の文字のパターンを表します。また、+
は、+
の前に記述された文字が 1
つ以上存在するパターンを表します。そして、res
の findall
は、第1引数で指定されたパターンに一致する文字列を第2引数で指定された文字列から全て取得する関数になります。
したがって、下記を実行すれば、response.text
から、すなわちレスポンスのボディを文字列化したデータから、<h2>
と <h2>
とで囲まれる "<と>以外"の文字から構成される
が全て取得できることになります。1
文字以上の文字列
titles = re.findall(r'<h2>([^<>]+)</h2>', response.text)
ちょっとややこしいですが、このように正規表現を利用することで HTML を解析することができます。今回は res
を利用しましたが、HTML の解析という点で言えば他のモジュール、例えば Beautiful Soup
などを利用する方が楽に解析できると思います。
また、今回は下記ページの HTML の構造に合わせて HTML の解析を行う処理を実装しましたが、解析対象のページに合わせて HTML の解析を行う処理の実装が必要であるという点に注意してください。
https://daeudaeu.com/?s=python
ここまで解説してきたように、正直 requests
モジュールの使い方は簡単で、要はメソッドに応じた関数を利用し、さらにリクエスト内容に応じた引数の指定を行うだけで良いです。これにより、リクエストの送信からレスポンスの受信までを自動的に行うことができます。
ですが、レスポンスとして受け取ったデータの解析は正直ややこしいです。今回は h2
タグの本文のみを取得する例だったので比較的楽に行うことができますが、解析の目的などによってはもっと複雑な処理を実装する必要も出てきます。他のモジュールも積極的に利用して解析を実現していくことをオススメします。
今回紹介した例は GET
リクエストによるものだけでしたが、post
関数を利用することで POST
リクエストも送信することが可能です。また、別の関数を実行することで他のメソッドのリクエストを送信することも可能です。ただ、このようなリクエストを実際に送信して動作確認を行うことができるようなサイトなどが見つけられなかったため、今回は実際の利用例の紹介に関しては省略させていただいています。
ただ、自身でウェブアプリを開発してやれば、そのウェブアプリを利用して POST
リクエスト送信時の動作確認なども容易に行うことができるようになります。実際に Django で簡単なウェブアプリを用意して POST
リクエスト送信時の動作確認を行う例も紹介していきたいと考えていますので、そのページが出来上がるまで少々お待ちいただければと思います。
他のモジュールとの違い
最後に、requests
モジュールと他のモジュールとの違いを解説しておきます。
requests
と socket
の違い
データの送受信を行うという意味では、requests
は socket
と似ています。
この2つの決定的な違いは、requests
は HTTP に特化しているのに対し、socket
は他のプロトコルにも対応可能という点になります。
socket
は Python の標準モジュールの1つであり、他の端末(PC やサーバーなど)との通信を実現することが可能です。ですが、socket
は低水準な通信モジュールであり、様々なプロトコルの通信を実現可能である代わりに、そのプロトコルに合わせた実装を開発者自身が行う必要があります。
例えば、socket
でも HTTP リクエストの送信を行うことは可能ですが、リクエストのデータは開発者自身が生成する必要があります。つまり、開発者自身がリクエストのデータのフォーマットを意識し、そのフォーマットに合わせたリクエストライン・ヘッダー・ボディを含むデータを生成する必要があって実装が大変です。また、レスポンスに関しても受信したバイナリデータが得られるだけなので、そのデータを解析して必要な情報、例えばステータスコードなどを取得するような処理も必要となります。
ですが、requests
の場合は HTTP に特化しており、requests
の関数を実行するだけでリクエストのデータの生成と送信、およびレスポンスのデータの受信まで行うことができます。関数の引数に応じてリクエストのフォーマットに合わせたデータの生成が行われるため、開発者自身がリクエストのデータを作成数量な実装は右葉になります。レスポンスに関しても、Response
クラスのインスタンスというスクリプトから扱いやすい型のデータとして受け取ることができ、受信したバイナリデータをわざわざ解析して取得するような処理も不要になります。
このように、socket
は様々な用途に対応可能な分、HTTP 等のプロトコルに合わせたデータの生成など HTTP 通信を行うための準備等を開発者自身が行う必要がありますが、requests
はモジュールが関数の呼び出しのみで HTTP 通信が可能であり、HTTP 通信を行うのであれば確実に requests
を使う方が楽で確実です。
スポンサーリンク
requests
と Selenium
の違い
また、Selenium
を利用することでも HTTP 通信を行うことが “結果的に” 可能となります。
ただし、わざわざ “結果的に” と記載しているように、Selenium
は requests
や socket
等とは違って通信を実現するためのモジュールではありません。Selenium
は Python スクリプト等からウェブブラウザの操作を実行するためのモジュールとなります。Selenium
を利用することで Python スクリプトからウェブブラウザを操作することができるようになり、ウェブブラウザの操作を自動化することが可能となります。
そして、ウェブブラウザでページを表示したりフォームを送信したりする操作を行うことで、結果的に HTTP リクエストの送信や HTTP レスポンスの受信が行われることになります。
つまり、Selenium
はウェブブラウザの操作を行うためのモジュールであり、ウェブブラウザの操作を介して HTTP リクエストの送信を行うことになります。それに対し、requests
はウェブブラウザを介さずに直接 HTTP リクエストの送信を行うモジュールとなります。この辺りが2つのモジュールの違いとなります。
全然違うモジュールのようにも思えますが、Selenium
も requests
同様にウェブスクレイピングやウェブアプリの動作確認等に用いられます。
Selenium
に関しては下記ページで解説していますので興味があれば読んでみてください。
まとめ
このページでは Python の requests
モジュールについて解説しました!
requests
モジュールは HTTP リクエストの送信及び HTTP レスポンスの受信を行うモジュールであり、これによりウェブスクレイピングやウェブアプリの動作確認を自動的に行うことができるようになります。
requests
モジュールは使い方もシンプルで直感的なコーディングで利用可能なモジュールで、基本的には送信したいリクエストに応じた引数を指定し、メソッドに応じた関数を実行すれば良いだけです。これだけでリクエストの送信からレスポンスの受信までを行うことができます。
特に、HTTP リクエストのデータフォーマットを理解しておけば requests
モジュールを利用する上で必要なことがイメージしやすくなると思いますので、是非こちらも一緒に覚えておきましょう!
また、requests
モジュールはウェブブラウザを介すことなく HTTP リクエストの送信が実現できるモジュールですが、ウェブブラウザの操作を介して HTTP リクエストの送信を行いたいような場合もあると思います。その場合は下記ページで紹介している Selenium
も使ってみてください。お互いの特徴を理解した上で目的に使い分けることが重要です!