2017-08-02 129 views
1

我正在阅读教程,并发现这段代码真的很混乱。为什么urlencode一个formdata然后用utf-8再次编码,这里的逻辑是什么?

from urllib import request, parse 

print('Login to somesite.com...') 
email = input('Email: ') 
passwd = input('Password: ') 
login_data = parse.urlencode([ 
    ('username', email), 
    ('password', passwd), 
    ('entry', 'mweibo'), 
    ('client_id', ''), 
    ('savestate', '1'), 
    ('ec', ''), 
    ('pagerefer', 'a referer') ]) 

req = request.Request('somesite.com') 
req.add_header('Origin', 'a origin') 
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25') 
req.add_header('Referer', 'a referer') 

with request.urlopen(req, data=login_data.encode('utf-8')) as f: 
    print('Status:', f.status, f.reason) 
    for k, v in f.getheaders(): 
     print('%s: %s' % (k, v)) 
    print('Data:', f.read().decode('utf-8')) 

什么urlencode在这里做的又是什么login_data.encode('utf-8'))做?

+0

_“urlencode在这里做什么”_你读过[它的文档](https://docs.python.org/3.5/library/urllib.parse.html#urllib.parse.urlencode)吗?你看过它的输出('print(login_data)')吗?你正在阅读的教程是否不解释这些代码?你有很多方法可以解决这个问题。 –

+1

'urlencode'的输出是百分比编码的ASCII文本字符串,需要将其转换为字节字符串以将其用作POST请求的数据。您可以将它编码为ASCII字节,但使用UTF-8并没有什么坏处,因为UTF-8保留了纯ASCII。但是,最后一行有点担心。就像在你之前的问题中一样,该代码假设返回的数据是UTF-8,它应该检查,或者至少将包含'.decode('utf-8')'调用的代码包装在适当的'try中。 ..except',所以它可以恢复解码错误。 –

+0

@Rawing哦,你可能会误解我的问题。在某种程度上,我明白为什么url需要被编码(如RFC提到的blablabla)。但我不确定为什么表单数据会被urlencoded,这是我的混乱部分。我已经检查了更多的文档并且搜索了不止一次。 – Tianqing

回答

1

虽然它们具有相同的名称,它们执行不同的操作类型:

  • URL编码被用来适应一些数据要被发送作为URL的一部分。 URL对字符类型有一些限制,它们不能包含空格或@或其他特殊字符,因此它们必须转换为不会混淆(例如空格变成%20)。在parse中,它基本上采用元组列表(left, right),并创建一个由&分隔的列表name=value的字符串。为了澄清,这里是一个例子

代码:

parse.urlencode([ 
    (name1,value1), (name2, value2) 
]) 

结果:

name1=value1&name2=value2 
  • UTF-8编码用于将字符映射到字节的序列。 Char必须表示为字节(如其他所有内容),并存在各种映射。 UTF-8是最常用的之一,因为它能够映射各种各样的字符,同时保留最常用的字符。
+0

是的。我可以理解为什么url使用urlencode(与你提到的很相似)。但为什么urlencode表单数据?我不能直接将它编码为utf-8字节吗? – Tianqing

+3

ulrencoding是创建包含GET或POST表单数据的查询字符串的标准过程,需要允许另一方取回名称/值对。 UTF-8是一个较低级别的编码,以确保字节流的正确解释。 – bracco23