20.5。 urllib —URLで任意のリソースを開く
ノート
urllib モジュールはパーツに分割され、Python3ではurllib.request
、urllib.parse
、およびurllib.error
に名前が変更されました。 2to3 ツールは、ソースをPython 3に変換するときに、インポートを自動的に適応させます。 また、Python3のurllib.request.urlopen()
関数は urllib2.urlopen()と同等であり、 urllib.urlopen()は削除されていることに注意してください。
このモジュールは、ワールドワイドウェブ全体でデータをフェッチするための高レベルのインターフェイスを提供します。 特に、 urlopen()関数は組み込み関数 open()に似ていますが、ファイル名の代わりにユニバーサルリソースロケーター(URL)を受け入れます。 いくつかの制限が適用されます—読み取り用にURLを開くことしかできず、シーク操作は使用できません。
バージョン2.7.9で変更: HTTPS URIの場合、 urllib はデフォルトで必要なすべての証明書とホスト名のチェックを実行します。
警告
2.7.9より前のバージョンのPythonの場合、urllibはHTTPSURIのサーバー証明書の検証を試みません。 自己責任!
20.5.1。 高レベルのインターフェース
- urllib.urlopen(url[, data[, proxies[, context]]])
読み取り用のURLで示されるネットワークオブジェクトを開きます。 URLにスキーム識別子がない場合、またはスキーム識別子として
file:
がある場合、これによりローカルファイルが開きます(ユニバーサルニューラインなし)。 それ以外の場合は、ネットワーク上のどこかにあるサーバーへのソケットを開きます。 接続できない場合、IOError
例外が発生します。 すべてがうまくいけば、ファイルのようなオブジェクトが返されます。 これは、次のメソッドをサポートします:read()
、 readline()、readlines()
、fileno()
、close()
、info()
、getcode()
およびgeturl()
。 また、 iterator プロトコルも適切にサポートしています。 注意点:read()
メソッドは、size引数が省略されているか負の場合、データストリームが終了するまで読み取られない可能性があります。 一般的なケースでは、ソケットからのストリーム全体が読み取られたことを確認する良い方法はありません。info()
、getcode()
、およびgeturl()
メソッドを除いて、これらのメソッドはファイルオブジェクトの場合と同じインターフェイスを備えています。このマニュアルのセクションファイルオブジェクトを参照してください。 (ただし、これは組み込みファイルオブジェクトではないため、真の組み込みファイルオブジェクトが必要ないくつかの場所では使用できません。)info()
メソッドは、URLに関連付けられたメタ情報を含むクラス mimetools.Message のインスタンスを返します。 メソッドがHTTPの場合、これらのヘッダーは、取得したHTMLページの先頭にあるサーバーによって返されるヘッダーです(Content-LengthおよびContent-Typeを含む)。 メソッドがFTPの場合、(現在は通常どおり)サーバーがFTP取得要求に応答してファイル長を返した場合、Content-Lengthヘッダーが存在します。 MIMEタイプを推測できる場合は、Content-Typeヘッダーが表示されます。 メソッドがlocal-fileの場合、返されるヘッダーには、ファイルの最終変更時刻を表すDate、ファイルサイズを示すContent-Length、およびファイルのタイプの推測を含むContent-Typeが含まれます。 mimetools モジュールの説明も参照してください。geturl()
メソッドは、ページの実際のURLを返します。 場合によっては、HTTPサーバーはクライアントを別のURLにリダイレクトします。 urlopen()関数はこれを透過的に処理しますが、場合によっては、呼び出し元はクライアントがリダイレクトされたURLを知る必要があります。geturl()
メソッドを使用して、このリダイレクトされたURLを取得できます。getcode()
メソッドは、応答とともに送信されたHTTPステータスコードを返します。URLがHTTP URLでない場合は、None
を返します。url が
http:
スキーム識別子を使用する場合、オプションの data 引数を指定して、POST
リクエストを指定できます(通常、リクエストタイプは[ X168X] )。 data 引数は、標準の application / x-www-form-urlencoded 形式である必要があります。 以下の urlencode()関数を参照してください。urlopen()関数は、認証を必要としないプロキシで透過的に機能します。 UnixまたはWindows環境では、Pythonインタープリターを起動する前に、
http_proxy
、またはftp_proxy
環境変数をプロキシサーバーを識別するURLに設定します。 。 例('%'
はコマンドプロンプトです):% http_proxy="http://www.someproxy.com:3128" % export http_proxy % python ...
no_proxy
環境変数を使用して、プロキシ経由で到達してはならないホストを指定できます。 設定する場合は、ホスト名サフィックスのコンマ区切りリストにする必要があります。オプションで、:port
を追加します(例:cern.ch,ncsa.uiuc.edu,some.host:8080
)。Windows環境では、プロキシ環境変数が設定されていない場合、プロキシ設定はレジストリの[インターネット設定]セクションから取得されます。
Mac OS X環境では、 urlopen()はOS Xシステム構成フレームワークからプロキシ情報を取得します。これは、ネットワークシステム環境設定パネルで管理できます。
または、オプションのプロキシ引数を使用して、プロキシを明示的に指定することもできます。 これは、スキーム名をプロキシURLにマッピングするディクショナリである必要があります。空のディクショナリではプロキシは使用されず、
None
(デフォルト値)では上記のように環境プロキシ設定が使用されます。 例えば:# Use http://www.someproxy.com:3128 for HTTP proxying proxies = {'http': 'http://www.someproxy.com:3128'} filehandle = urllib.urlopen(some_url, proxies=proxies) # Don't use any proxies filehandle = urllib.urlopen(some_url, proxies={}) # Use proxies from environment - both versions are equivalent filehandle = urllib.urlopen(some_url, proxies=None) filehandle = urllib.urlopen(some_url)
使用するために認証を必要とするプロキシは現在サポートされていません。 これは実装上の制限と見なされます。
context パラメーターを ssl.SSLContext インスタンスに設定して、 urlopen()がHTTPS接続を行う場合に使用されるSSL設定を構成できます。
バージョン2.3で変更: プロキシのサポートが追加されました。
バージョン2.6で変更:返されたオブジェクトに
getcode()
を追加し、no_proxy
環境変数をサポートします。バージョン2.7.9で変更: context パラメーターが追加されました。 必要なすべての証明書とホスト名のチェックは、デフォルトで実行されます。
バージョン2.6以降非推奨: urlopen()関数はPython 3で削除され、 urllib2.urlopen()が優先されます。
- urllib.urlretrieve(url[, filename[, reporthook[, data[, context]]]])
必要に応じて、URLで示されるネットワークオブジェクトをローカルファイルにコピーします。 URLがローカルファイルを指している場合、またはオブジェクトの有効なキャッシュコピーが存在する場合、オブジェクトはコピーされません。 タプル
(filename, headers)
を返します。ここで、 filename はオブジェクトを見つけることができるローカルファイル名であり、 headers はinfo()
メソッドのいずれかです。 urlopen()によって返されたオブジェクトが返されました(リモートオブジェクトの場合、キャッシュされている可能性があります)。 例外は urlopen()の場合と同じです。2番目の引数は、存在する場合、コピー先のファイルの場所を指定します(存在しない場合、場所は生成された名前の一時ファイルになります)。 3番目の引数は、存在する場合、ネットワーク接続の確立時に1回呼び出され、その後各ブロックが読み取られた後に1回呼び出される呼び出し可能オブジェクトです。 呼び出し可能オブジェクトには3つの引数が渡されます。 これまでに転送されたブロックの数、バイト単位のブロックサイズ、およびファイルの合計サイズ。 3番目の引数は、取得要求に応答してファイルサイズを返さない古いFTPサーバーでは
-1
である可能性があります。url が
http:
スキーム識別子を使用する場合、オプションの data 引数を指定して、POST
リクエストを指定できます(通常、リクエストタイプは[ X168X] )。 data 引数は、標準の application / x-www-form-urlencoded 形式である必要があります。 以下の urlencode()関数を参照してください。context パラメーターを ssl.SSLContext インスタンスに設定して、 urlretrieve()がHTTPS接続を行う場合に使用されるSSL設定を構成できます。
バージョン2.5での変更: urlretrieve()は、使用可能なデータの量が予想量(報告されたサイズ)より少ないことを検出すると、 ContentTooShortError を発生させます Content-Length ヘッダーによる)。 これは、たとえば、ダウンロードが中断された場合に発生する可能性があります。
Content-Length は下限として扱われます。読み取るデータが多い場合、 urlretrieve()はより多くのデータを読み取りますが、使用可能なデータが少ない場合は例外が発生します。
この場合でも、ダウンロードしたデータを取得できます。データは、例外インスタンスの
content
属性に保存されます。Content-Length ヘッダーが指定されていない場合、 urlretrieve()はダウンロードしたデータのサイズを確認できず、データを返すだけです。 この場合、ダウンロードが成功したと想定する必要があります。
バージョン2.7.9で変更: context パラメーターが追加されました。 必要なすべての証明書とホスト名のチェックは、デフォルトで実行されます。
- urllib._urlopener
パブリック関数 urlopen()および urlretrieve()は、 FancyURLopener クラスのインスタンスを作成し、それを使用して要求されたアクションを実行します。 この機能をオーバーライドするために、プログラマーは URLopener または FancyURLopener のサブクラスを作成し、目的の関数を呼び出す前にそのクラスのインスタンスを
urllib._urlopener
変数に割り当てることができます。 たとえば、アプリケーションは、 URLopener が定義するものとは異なる User-Agent ヘッダーを指定したい場合があります。 これは、次のコードで実行できます。import urllib class AppURLopener(urllib.FancyURLopener): version = "App/1.7" urllib._urlopener = AppURLopener()
- urllib.urlcleanup()
- urlretrieve()への以前の呼び出しによって構築された可能性のあるキャッシュをクリアします。
20.5.2。 ユーティリティ機能
- urllib.quote(string[, safe])
%xx
エスケープを使用して、 string の特殊文字を置き換えます。 文字、数字、および文字'_.-'
が引用されることはありません。 デフォルトでは、この関数はURLのパスセクションを引用することを目的としています。 オプションの safe パラメーターは、引用符で囲まない追加の文字を指定します。デフォルト値は'/'
です。例:
quote('/~connolly/')
は'/%7econnolly/'
を生成します。
- urllib.quote_plus(string[, safe])
- quote()と同様ですが、URLに入力するクエリ文字列を作成するときにHTMLフォーム値を引用するために必要な場合は、スペースをプラス記号に置き換えます。 safe に含まれていない限り、元の文字列のプラス記号はエスケープされます。 また、 safe のデフォルトは
'/'
ではありません。
- urllib.unquote(string)
%xx
エスケープを同等の1文字に置き換えます。例:
unquote('/%7Econnolly/')
は'/~connolly/'
を生成します。
- urllib.unquote_plus(string)
- unquote()と同様ですが、HTMLフォーム値の引用符を解除するために必要な場合は、プラス記号をスペースに置き換えます。
- urllib.urlencode(query[, doseq])
- マッピングオブジェクトまたは2要素タプルのシーケンスを「パーセントエンコード」文字列に変換します。これは、オプションの data 引数として上記の urlopen()に渡すのに適しています。 これは、フォームフィールドのディクショナリを
POST
リクエストに渡すのに役立ちます。 結果の文字列は、'&'
文字で区切られた一連のkey=value
ペアです。ここで、キーと値の両方が quote_plus()を使用して引用されます。上記の。 2要素タプルのシーケンスが query 引数として使用される場合、各タプルの最初の要素はキーであり、2番目の要素は値です。 値要素自体はシーケンスにすることができ、その場合、オプションのパラメーター doseq がTrue
と評価されると、'&'
で区切られた個々のkey=value
ペアになります。 ]は、キーの値シーケンスの要素ごとに生成されます。 エンコードされた文字列内のパラメーターの順序は、シーケンス内のパラメータータプルの順序と一致します。 urlparse モジュールは、クエリ文字列をPythonデータ構造に解析するために使用される関数parse_qs()
およびparse_qsl()
を提供します。
- urllib.pathname2url(path)
- パス名 path を、パスのローカル構文からURLのパスコンポーネントで使用される形式に変換します。 これは完全なURLを生成しません。 戻り値は、 quote()関数を使用してすでに引用されています。
- urllib.url2pathname(path)
- パスコンポーネント path をパーセントエンコードされたURLからパスのローカル構文に変換します。 これは完全なURLを受け入れません。 この関数は、 unquote()を使用してパスをデコードします。
- urllib.getproxies()
このヘルパー関数は、スキームのディクショナリをプロキシサーバーのURLマッピングに返します。 大文字と小文字を区別しない方法で、最初にすべてのオペレーティングシステムの
<scheme>_proxy
という名前の変数について環境をスキャンし、見つからない場合は、Mac OSXのMacOSXシステム構成およびWindowsシステムレジストリからプロキシ情報を探します。ウィンドウズ。 小文字と大文字の両方の環境変数が存在する(そして同意しない)場合は、小文字が優先されます。ノート
環境変数
REQUEST_METHOD
が設定されている場合、これは通常、スクリプトがCGI環境で実行されていることを示し、環境変数HTTP_PROXY
(大文字の_PROXY
)は無視されます。 これは、その変数が「Proxy:」HTTPヘッダーを使用してクライアントによって挿入できるためです。 CGI環境でHTTPプロキシを使用する必要がある場合は、ProxyHandler
を明示的に使用するか、変数名が小文字(または少なくとも_proxy
サフィックス)であることを確認してください。
ノート
urllibは、splittype、splithostなど、URLをさまざまなコンポーネントに解析する特定のユーティリティ関数も公開します。 ただし、これらの関数を直接使用するのではなく、 urlparse を使用してURLを解析することをお勧めします。 Python 3は、urllib.parse
モジュールからこれらのヘルパー関数を公開しません。
20.5.3。 URLオープナーオブジェクト
- class urllib.URLopener([proxies[, context[, **x509]]])
URLを開いて読み取るための基本クラス。
http:
、ftp:
、またはfile:
以外のスキームを使用したオブジェクトのオープンをサポートする必要がない限り、おそらく FancyURLopener を使用することをお勧めします。デフォルトでは、 URLopener クラスは
urllib/VVV
の User-Agent ヘッダーを送信します。ここで、 VVV は urllib バージョンです。番号。 アプリケーションは、 URLopener または FancyURLopener をサブクラス化し、クラス属性 version を適切な文字列値に設定することにより、独自の User-Agent ヘッダーを定義できます。サブクラスの定義。オプションの proxies パラメーターは、スキーム名をプロキシURLにマッピングするディクショナリである必要があります。この場合、空のディクショナリはプロキシを完全にオフにします。 デフォルト値は
None
です。この場合、上記の urlopen()の定義で説明されているように、環境プロキシ設定が存在する場合はそれが使用されます。context パラメーターは、 ssl.SSLContext インスタンスである可能性があります。 指定した場合、オープナーがHTTPS接続を確立するために使用するSSL設定を定義します。
x509 で収集された追加のキーワードパラメータは、
https:
スキームを使用する場合のクライアントの認証に使用できます。 キーワード key_file および cert_file は、SSLキーと証明書を提供するためにサポートされています。 クライアント認証をサポートするには、両方が必要です。URLopener オブジェクトは、サーバーがエラーコードを返した場合、
IOError
例外を発生させます。バージョン2.7.9で変更: context パラメーターが追加されました。 必要なすべての証明書とホスト名のチェックは、デフォルトで実行されます。
- open(fullurl[, data])
適切なプロトコルを使用して fullurl を開きます。 このメソッドは、キャッシュとプロキシの情報を設定し、入力引数を使用して適切なopenメソッドを呼び出します。 スキームが認識されない場合、 open_unknown()が呼び出されます。 data 引数は、 urlopen()の data 引数と同じ意味です。
- open_unknown(fullurl[, data])
不明なURLタイプを開くためのオーバーライド可能なインターフェース。
- retrieve(url[, filename[, reporthook[, data]]])
url の内容を取得し、ファイル名に配置します。 戻り値は、ローカルファイル名と、応答ヘッダー(リモートURLの場合)または
None
(ローカルURLの場合)を含む mimetools.Message オブジェクトのいずれかで構成されるタプルです。 次に、呼び出し元はファイル名の内容を開いて読み取る必要があります。 filename が指定されておらず、URLがローカルファイルを参照している場合、入力ファイル名が返されます。 URLが非ローカルで、 filename が指定されていない場合、ファイル名は tempfile.mktemp()の出力であり、サフィックスはの最後のパスコンポーネントのサフィックスと一致します。入力URL。 reporthook を指定する場合は、3つの数値パラメーターを受け入れる関数である必要があります。 データの各チャンクがネットワークから読み取られた後に呼び出されます。 reporthook はローカルURLでは無視されます。url が
http:
スキーム識別子を使用する場合、オプションの data 引数を指定して、POST
リクエストを指定できます(通常、リクエストタイプは[ X168X] )。 data 引数は、標準の application / x-www-form-urlencoded 形式である必要があります。 以下の urlencode()関数を参照してください。
- version
オープナーオブジェクトのユーザーエージェントを指定する変数。 urllib を取得して、サーバーに特定のユーザーエージェントであることを通知するには、基本コンストラクターを呼び出す前に、これをクラス変数としてサブクラスまたはコンストラクターに設定します。
- class urllib.FancyURLopener(...)
FancyURLopener サブクラス URLopener は、次のHTTP応答コードのデフォルト処理を提供します:301、302、303、307、および401。 上記の30x応答コードの場合、 Location ヘッダーを使用して実際のURLを取得します。 401応答コード(認証が必要)の場合、基本HTTP認証が実行されます。 30x応答コードの場合、再帰は maxtries 属性の値によって制限されます。デフォルトは10です。
他のすべての応答コードについては、メソッド
http_error_default()
が呼び出されます。このメソッドをサブクラスでオーバーライドして、エラーを適切に処理できます。ノート
RFC 2616 の書簡によると、POST要求に対する301および302の応答は、ユーザーの確認なしに自動的にリダイレクトされてはなりません。 実際には、ブラウザはこれらの応答の自動リダイレクトを許可し、POSTをGETに変更し、 urllib はこの動作を再現します。
コンストラクターのパラメーターは、 URLopener のパラメーターと同じです。
ノート
基本認証を実行する場合、 FancyURLopener インスタンスはその prompt_user_passwd()メソッドを呼び出します。 デフォルトの実装では、制御端末で必要な情報をユーザーに要求します。 サブクラスは、必要に応じて、より適切な動作をサポートするためにこのメソッドをオーバーライドできます。
FancyURLopener クラスは、適切な動作を提供するためにオーバーロードする必要がある1つの追加メソッドを提供します。
- prompt_user_passwd(host, realm)
指定されたセキュリティレルム内の指定されたホストでユーザーを認証するために必要な情報を返します。 戻り値は、基本認証に使用できるタプル
(user, password)
である必要があります。実装は、端末でこの情報の入力を求めます。 アプリケーションは、ローカル環境で適切な相互作用モデルを使用するために、このメソッドをオーバーライドする必要があります。
- exception urllib.ContentTooShortError(msg[, content])
この例外は、 urlretrieve()関数が、ダウンロードされたデータの量が予想される量より少ないことを検出した場合に発生します( Content-Length ヘッダーで指定)。
content
属性は、ダウンロードされた(そしておそらく切り捨てられた)データを格納します。バージョン2.5の新機能。
20.5.4。 urllib 制限
現在、サポートされているプロトコルは、HTTP(バージョン0.9および1.0)、FTP、およびローカルファイルのみです。
urlretrieve()のキャッシュ機能は、有効期限の時間ヘッダーの適切な処理をハックする時間が見つかるまで無効になっています。
特定のURLがキャッシュにあるかどうかを照会する関数が必要です。
下位互換性のために、URLがローカルファイルを指しているように見えてもファイルを開くことができない場合、URLはFTPプロトコルを使用して再解釈されます。 これにより、紛らわしいエラーメッセージが表示される場合があります。
urlopen()および urlretrieve()関数は、ネットワーク接続がセットアップされるのを待つ間、任意に長い遅延を引き起こす可能性があります。 これは、スレッドを使用せずにこれらの関数を使用してインタラクティブなWebクライアントを構築することは困難であることを意味します。
urlopen()または urlretrieve()によって返されるデータは、サーバーによって返される生データです。 これは、バイナリデータ(画像など)、プレーンテキスト、または(たとえば)HTMLの場合があります。 HTTPプロトコルは、応答ヘッダーでタイプ情報を提供します。これは、 Content-Type ヘッダーを調べることで調べることができます。 返されるデータがHTMLの場合、モジュール htmllib を使用して解析できます。
FTPプロトコルを処理するコードは、ファイルとディレクトリを区別できません。 これにより、アクセスできないファイルを指すURLを読み取ろうとすると、予期しない動作が発生する可能性があります。 URLが
/
で終わる場合、それはディレクトリを参照していると見なされ、それに応じて処理されます。 ただし、ファイルを読み取ろうとすると550エラーが発生する場合(多くの場合、アクセス許可の理由でURLが見つからないかアクセスできないことを意味します)、ディレクトリが指定されている場合を処理するために、パスはディレクトリとして扱われます。 URLによるものですが、末尾の/
は省略されています。 これにより、読み取り権限によってアクセスできないファイルをフェッチしようとすると、誤解を招く結果が生じる可能性があります。 FTPコードはそれを読み取ろうとし、550エラーで失敗し、読み取り不可能なファイルのディレクトリリストを実行します。 きめ細かい制御が必要な場合は、 ftplib モジュールの使用、 FancyURLopener のサブクラス化、または _urlopener の変更を検討してください。このモジュールは、認証を必要とするプロキシの使用をサポートしていません。 これは将来実装される可能性があります。
20.5.5。 例
GET
メソッドを使用してパラメーターを含むURLを取得するセッションの例を次に示します。
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params)
>>> print f.read()
次の例では、代わりにPOST
メソッドを使用しています。
>>> import urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> f = urllib.urlopen("http://www.musi-cal.com/cgi-bin/query", params)
>>> print f.read()
次の例では、明示的に指定されたHTTPプロキシを使用して、環境設定をオーバーライドします。
>>> import urllib
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.FancyURLopener(proxies)
>>> f = opener.open("http://www.python.org")
>>> f.read()
次の例では、プロキシをまったく使用せず、環境設定をオーバーライドしています。
>>> import urllib
>>> opener = urllib.FancyURLopener({})
>>> f = opener.open("http://www.python.org/")
>>> f.read()