2010-03-04 1 views
2

저는 Python을 처음 사용합니다. 너무 분명한 사실을 놓친다면 용서해주십시오.FancyURLopener, 401 및 "Connection : close"에 Python 문제가 발생했습니다.

urllib.FancyURLopener를 사용하여 웹 문서를 검색하고 있습니다. 웹 서버에서 인증이 비활성화되면 제대로 작동하지만 인증이 활성화되면 실패합니다.

내 생각 엔 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 예외가 발생합니다.

와이어 샤크는 요청이 전송되는 것을 저에게 말한다, 서버는이 관심의 헤더는 "401 권한"응답 전송하고 있음 :

WWW-Authenticate: BASIC 
Connection: close 

닫힙니다 연결, 나는 내 예외를 잡을를 모든 끝났어.

IOError 후에 "f = opener.open()"을 다시 시도해도 같은 방식으로 실패합니다.

간단한 "print 'Got 401 오류' '로 http_error_401() 메서드를 재정 의하여 my_opener() 클래스가 작동하는지 확인했습니다. 나는 또한 prompt_user_passwd() 메소드를 오버라이드하려고 시도했으나 일어난다.

사용자 이름과 암호를 사전에 지정할 방법이 없습니다.

요청을 다시 시도하려면 urllib을 어떻게 받습니까?

감사합니다.

+0

는 그냥 add_password() 메소드 urllib2.HTTPBasicAuthHandler()를 사용했습니다.이 경우 서버는 401 Unauthorized를 반환하지 않습니다. 대신 오류 메시지와 함께 200 OK를 반환합니다. 차이점 : urllib2의 경우 요청에 "Connection : close"헤더가 포함됩니다. urllib.FancyURLopener는이 헤더를 포함하지 않습니다. –

답변

0

난 그냥 내 웹 서버 (의 nginx)에 코드를 시도하고 예상대로 작동합니다

  • 이 URLLIB 클라이언트
  • HTTP/헤더

    Connection: close 
    WWW-Authenticate: Basic realm="Restricted" 
    
  • 와 서버에서 1.1 401 권한에서 가져 오기
  • 클라이언트가 인증 헤더를 사용하여 다시 시도합니다.

    Authorization: Basic <Base64encoded credentials> 
    
  • 서버

그래서 난 당신의 코드가 어쩌면 액세스하려는 웹 서버가 예상대로 작동하지 않습니다 (내가 파이썬 2.7.1와 함께 그것을 시도) 바로 추측 200 OK + 내용으로 응답합니다. 여기에 코드가 무료로 HTTP 기본 인증의 실험 사이트의 browserspy.dk를 사용하여 테스트입니다 (그들은 아파치를 사용하는 것 - 코드는 예상대로 작동) :

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!" 
관련 문제