我正在尝试通过我尝试访问的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)
然后msg打印
[b'SID', b'AAAAAAAAAAAAAAAAA\n']
我知道这是一些非常难看的代码,我在Python中已经有一周了。任何帮助将不胜感激。
答案 0 :(得分: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)
与此同时,您的原始代码的try
没有except
或finally
,只会引发SyntaxError
。大概你想要这样的东西:
try:
for msg in fh:
print(msg)
except Exception as e:
print('Exception: {}'.format(e))
虽然我们正在努力,但我们可以稍微简化您的代码。
如果你看the examples:
以下是使用
GET
方法检索包含参数的网址的示例会话:
这正是你想要做的(除了最后一行)。你用编码字符串做的所有额外的东西不仅是不必要的,而且是不正确的。 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))