2

私はPythonを初めて使用するので、明らかな何かが欠けている場合はご容赦ください。

urllib.FancyURLopenerを使用してWebドキュメントを取得しています。Webサーバーで認証が無効になっている場合は正常に機能しますが、認証が有効になっている場合は失敗します。

私の推測では、get_user_passwd()メソッドやprompt_user_passwd()メソッドをオーバーライドするには、urllib.FancyURLopenerをサブクラス化する必要があります。だから私はしました:

class my_opener (urllib.FancyURLopener):

    # Redefine
    def get_user_passwd(self, host, realm, clear_cache=0):
        print "get_user_passwd() called; host %s, realm %s" % (host, realm)
        return ('name', 'password')

次に、ページを開こうとします。

try:
    opener = my_opener()
    f = opener.open ('http://1.2.3.4/whatever.html')
    content = f.read()
    print "Got it:  ", content

except IOError:
    print "Failed!"

FancyURLopenerが401を処理し、get_user_passwd()を呼び出して、リクエストを再試行することを期待しています。

そうではありません。「f=opener.open()」を呼び出すと、IOError例外が発生します。

Wiresharkは、リクエストが送信され、サーバーが2つの対象ヘッダーを含む「401Unauthorized」応答を送信していることを通知します。

WWW-Authenticate: BASIC
Connection: close

その後、接続が閉じられ、例外が発生しました。これですべてです。

IOErrorの後で「f=opener.open()」を再試行しても、同じように失敗します。

単純な「print'Got401 error'」でhttp_error_401()メソッドをオーバーライドすることにより、my_opener()クラスが機能していることを確認しました。また、prompt_user_passwd()メソッドをオーバーライドしようとしましたが、それも発生しません。

ユーザー名とパスワードを積極的に指定する方法がわかりません。

では、どうすればurllibにリクエストを再試行させることができますか?

ありがとう。

4

1 に答える 1

0

Webサーバー(nginx)でコードを試しましたが、期待どおりに機能します。

  • urllibクライアントから取得
  • HTTP /1.1401ヘッダー付きのサーバーから許可されていません

    Connection: close
    WWW-Authenticate: Basic realm="Restricted"
    
  • クライアントはAuthorizationヘッダーで再試行します

    Authorization: Basic <Base64encoded credentials>
    
  • サーバーは200OK+コンテンツで応答します

したがって、コードは正しいと思います(Python 2.7.1で試しました)。おそらく、アクセスしようとしているWebサーバーが期待どおりに機能していません。無料のhttp基本認証テストサイトbrowserspy.dkを使用してテストされたコードは次のとおりです(apacheを使用しているようです-コードは期待どおりに機能します):

import urllib

class my_opener (urllib.FancyURLopener):

    # Redefine
    def get_user_passwd(self, host, realm, clear_cache=0):
        print "get_user_passwd() called; host %s, realm %s" % (host, realm)
        return ('test', 'test')

try:
    opener = my_opener()
    f = opener.open ('http://browserspy.dk/password-ok.php')
    content = f.read()
    print "Got it:  ", content

except IOError:
    print "Failed!"
于 2011-07-15T21:08:01.177 に答える