2013-06-17 3 views
0

액세스하려는 API에서 인증을 받으려고합니다. urllib.parse.urlencode를 사용하여 내 URL에있는 매개 변수를 인코딩합니다. urllib.request.urlopen을 사용하여 내용을 가져옵니다.Python Urllib Urlopen은 새 줄 다음에 반환되지 않습니까?

SID=AAAAAAAAAAA 
LSID=BBBBBBBBBBB 
AUTH=CCCCCCCCCCC 

문제는 그것이 첫 번째 값을 반환하고, 후행 줄 바꾸기 문자 :

같은 서버에서 3 개 값을 반환해야합니다.

import urllib.request 
import urllib.parse 

Emailparamx = 'Email' 
Emailparam = Emailparamx.encode('utf-8') 
email = '[email protected]' 
email = email.encode('utf-8') 
Passwdparam = 'Passwd' 
Passwdparam = Passwdparam.encode('utf-8') 
password = 'hidden' 
password = password.encode('utf-8') 
Accounttypeparam = 'accountType' 
Accounttypeparam = Accounttypeparam.encode('utf-8') 
accounttype = 'GOOGLE' 
accounttype = accounttype.encode('utf-8') 
Serviceparam = 'service' 
Serviceparam = Serviceparam.encode('utf-8') 
service = 'adwords' 
service = service.encode('utf-8') 


url = 'https://accounts.google.com/ClientLogin?' 
urlen = url.encode('utf-8') 
data = [(Emailparamx, email), (Passwdparam, password), 
     (Accounttypeparam, accounttype), (Serviceparam, service)] 



auth = '' 

dataurl = urllib.parse.urlencode(data) 


accessurl = (url + "%s" % dataurl) 

fh = urllib.request.urlopen(accessurl) 

equals = '=' 
eqenc = equals.encode('utf-8') 

try: 
    msg = fh.readline().split(eqenc) 
    print (msg) 

그리고 MSG는 인쇄는

[b'SID', b'AAAAAAAAAAAAAAAAA\n'] 

나는 파이썬에서 오래된 약 일주일있어, 그 일부 심각하게 추한 코드를 알고있다. 어떤 도움이라도 대단히 감사하겠습니다.

+0

: 그래서, 함수에서 일을 마무리 할 수 ​​

는, 그 함수를 호출합니다. 예를 들어,'encoding = 'utf-8 ''을 사용하여'str'을'urlencode'로 전달하는 대신에, 왜 각 조각을 하나씩 UTF-8로 인코딩합니까? 그리고 왜''% s "% dataurl' 대신에''dataurl''입니까? 이것으로 여러분은 아마이 코드를 (아주 좋지 않은) 튜토리얼 (아마도 2.x 튜토리얼에서 3.x로 직접 포팅하려 했음)에서 빌린 것처럼 보입니다. 그렇다면 튜토리얼에서 얻은 정보를 알려 주시면 더 많은 정보를 얻을 수 있습니다. – abarnert

+0

또한 [ClientLogin은 1 년 넘게 사용 중지되었습니다] (https://developers.google.com/accounts/docs/AuthForInstalledApps), CL이 아닌 OAuth 또는 OAuth2를 사용하는 방법을 실제로 배우고 있어야합니다. – abarnert

+0

마지막으로, 이것은 실제 코드가 될 수 없습니다. 왜냐하면'except' 나'finally'가없는'try'가'SyntaxError'를 발생시킬 것이기 때문입니다. – abarnert

답변

0

문제는 단지 readline으로 한 번 호출되므로 한 줄만 읽습니다. 당신이 하나 하나 라인을 읽고 싶다면, 작업이 완료 될 때까지 루프에서 readline를 호출 계속해야 :

while True: 
    msg = fh.readline() 
    if not msg: 
     break 
    msg = msg.split(eqenc) 
    print(msg) 
그러나

, 여기 readline를 호출 할 좋은 이유가, 정말이 없기 때문에 모든 파일과 같은 (A urlopen 객체 포함) 개체가 이미 라인의 반복 가능한 전체, 그래서 당신은이 작업을 수행 할 수 있습니다

for msg in fh: 
    print(msg) 

한편, 원래 코드는있습니다 except 또는 finally이없는은 단지 SyntaxError을 발생시킵니다. 우리가에있는 동안

try: 
    for msg in fh: 
     print(msg) 
except Exception as e: 
    print('Exception: {}'.format(e)) 

, 우리는 당신의 코드를 약간 단순화 할 수 있습니다 : 아마도 당신이 뭔가를 원했다.

당신은 the examples 보면 다음과 같습니다

이 URL이 포함 매개 변수를 검색 할 GET 방법을 사용하는 예제 세션입니다 : 당신을 제외하고 (여기하고 싶은 정확히 무엇

마지막 줄). 문자열 인코딩과 함께하는 모든 추가 작업은 불필요 할뿐만 아니라 올바르지 않습니다. UTF-8은 잘못된 인코딩으로 URL에 사용하는 인코딩이 잘못되었습니다 (모든 문자열이 순수한 ASCII이기 때문에 멀리 떨어져 나옵니다). urlopen은 인코딩 된 바이트 문자열이 아닌 문자열을 필요로합니다 (적어도 CPython 3.0-3.3에서는 인코딩 된 바이트 문자열을 제공하면 작동합니다). urlencode은 바이트 문자열을 취할 수 있지만 옳은 일을하지 않을 수도 있습니다 (원래 유니 코드를 지정하여 제대로 인용 할 수 있습니다).

또한 결과 (ASCII로 전송 됨 - 더 복잡한 예제의 경우 fh.getheader('Content-Type')을 구문 분석하거나 API 설명서를 읽어야 함)를 제거하고 새 행을 제거합니다 .

인쇄하는 대신 코드에서 사용할 수있는 구조를 만들 수도 있습니다. 예를 들어 결과를 login_info에 저장하고 이후 요청에서 SID이 필요한 경우 바로는 login_info['SID']입니다. 당신은 여기 초과 코드의 전체를 많이있어

import urllib.request 
import urllib.parse 

def client_login(email, passwd, account_type, service): 
    params = {'Email': email, 
       'Passwd': passwd, 
       'accountType': account_type, 
       'service': service} 
    qs = urllib.parse.urlencode(params) 
    url = 'https://accounts.google.com/ClientLogin?' 
    with urllib.request.urlopen(url + qs) as fh: 
     return dict(line.strip().decode('ascii').split('=', 1) for line in fh) 

email = '[email protected]' 
password = 'hidden' 
accounttype = 'GOOGLE' 
service = 'adwords' 
try: 
    results = client_login(email, password, accounttype, service) 
    for key, value in results.items(): 
     print('key "{}" is "{}".format(key, value)) 
except Exception as e: 
    print('Exception: {}'.format(e)) 
+0

의견을 보내 주셔서 감사 드리며, 오늘 아침에 시도하겠습니다. 이 코드의 대부분은 API 사용에 대한 예제 튜토리얼에서 복사 한 것입니다. 공격적인 부분은 사실 내 창조물입니다. ( –

+0

@RobM : 나중에 참조 할 수 있도록 튜토리얼에서 코드를 복사하면 일반적으로 튜토리얼에 대한 링크를 제공할만한 가치가 있습니다. 예를 들어 자주 읽으면 튜토리얼의 목적을 알 수 있지만 초보자 친화적 인 방식으로 설명하지 못합니다. – abarnert