0

我正在尝试通过我尝试访问的 API 进行身份验证。我正在使用 urllib.parse.urlencode 对进入我的 URL 的参数进行编码。我正在使用 urllib.request.urlopen 来获取内容。

这应该从服务器返回 3 个值,例如:

SID=AAAAAAAAAAA
LSID=BBBBBBBBBBB
AUTH=CCCCCCCCCCC

问题是它只返回第一个值和尾随的换行符。

import urllib.request
import urllib.parse

Emailparamx = 'Email'
Emailparam = Emailparamx.encode('utf-8')
email = 'myemail@stackoverflow.com'
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)

然后味精打印

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

我知道那是一些非常丑陋的代码,我在 Python 中大约一周大。任何帮助将不胜感激。

4

1 回答 1

0

问题是你只调用readline一次,所以它只读取一行。如果您想逐行阅读,则必须readline循环调用直到完成:

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

然而,在这里调用真的没有很好的理由readline,因为任何类似文件的对象(包括一个urlopen对象)已经是一个充满行的可迭代对象,所以你可以这样做:

for msg in fh:
    print(msg)

同时,您的原始代码有 atry没有 aexcept或 a finally,这只会引发 a SyntaxError。大概你想要这样的东西:

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

当我们这样做时,我们可以稍微简化您的代码。

如果您查看示例

这是一个使用该GET方法检索包含参数的 URL 的示例会话:

这正是您想要在这里做的(最后一行除外)。您对字符串进行编码所做的所有额外工作不仅是不必要的,而且是不正确的。UTF-8 是错误的编码是用于 URL 的错误编码(因为您的所有字符串都是纯 ASCII,所以您可以逃脱惩罚);urlopen需要一个字符串而不是编码的字节字符串(尽管,至少在 CPython 3.0-3.3 中,如果你给它恰好编码正确的字节字符串,它恰好可以工作);urlencode可以接受字节字符串,但可能不会做正确的事情(你想给它原始的 Unicode,以便它可以正确引用);等等

此外,您可能想要解码结果(以 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 = 'myemail@stackoverflow.com'
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))
于 2013-06-18T01:11:19.507 回答