カスタムヘッダーを追加しながら、urlretrieve
を使用してファイルを取得しようとしています。
urllib.request
のコードソースを確認しているときに、urlopen
が文字列だけでなくRequest
オブジェクトをパラメーターに取ることができ、必要なヘッダーを配置できることがわかりました。しかし、urlretrieve
で同じことを実行しようとすると、この他の投稿で言及されているように TypeError:予期される文字列またはバイトのようなオブジェクト が返されます。
私がやったことは、自分のurlretrieveを書き換えて、エラーをスローしている行を削除することです(その行は、私のユースケースでは無関係です)。
それは正常に動作しますが、より良い/より良いかどうか疑問に思っています自分のurlretrieve
を書き換えるのではなく、それを行う方法。カスタムヘッダーをurlopen
に渡すことができる場合、urlretrieve
?
数行のコードを追加するだけでよい方法を見つけました...
import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve("type URL here", "path/file_name")
詳細については、pythonドキュメント: https://docs.python.org/3/library/urllib.request.html を参照してください。 =
urllib.request.urlretrieve()
はurllib.request.urlopen()
内で使用します(少なくともPython 3で)。したがって、urlopen
。
urlopen(params)
が呼び出されると、実際には最初に特別なグローバル変数_urllib.request._opener
_が調べられ、None
の場合はurlopen
がデフォルトのオープナーのセットで変数を設定しますそれ以外の場合はそのままにします。次のステップでは、urllib.request._opener.open(<urlopen_params>)
を呼び出します(次のセクションでは、_urllib.request._opener
_をopener
としてのみ参照します)。
opener.open()
には、さまざまなプロトコルのハンドラーのリストが含まれています。 opener.open()
が呼び出されると、次のアクションが実行されます。
urllib.request.Request
_オブジェクトから作成します(または、Request
を直接指定した場合は、それを使用します)。Request
オブジェクトからプロトコルが抽出されます(URLスキームから推定されます)。protocol_request
_(例:_http_request
_)-接続が開かれる前にリクエストを前処理するために使用されます。protocol_open
_-実際にリモートサーバーとの接続を作成しますprotocol_response
_-サーバーからの応答を処理しますあなた自身のオープナーのために、あなたはそれらの3つのステップをしなければなりません:
urllib.request.build_opener
_)urllib.request._opener
_にインストールします(関数_urllib.request.install_opener
_)_urllib.request.build_opener
_は、カスタムハンドラーを含むオープナーを作成し、カスタムハンドラーが継承されたハンドラーを除くデフォルトオープナーを追加します。
したがって、カスタムヘッダーを追加するには、次のように記述します。
_import urllib.request as req
class MyHTTP(req.HTTPHandler):
def http_request(self, req):
req.headers["MyHeader"] = "Content of my header"
return super().http_request(req)
opener = req.build_opener(MyHTTP())
req.install_opener(opener)
_
この時点から、urllib.request.urlretrieve()
またはurlopen()
を使用しているものを呼び出すと、ハンドラーのHTTP通信に使用されます。デフォルトのハンドラーに戻したい場合は、次のように呼び出すだけです。
_import urllib.request as req
req.install_opener(req.build_opener())
_
正直なところ、それがあなたのソリューションよりも優れている/よりクリーンなソリューションであるかどうかはわかりませんが、urllib
で準備されたメカニズムを使用しています。