有时需要将HTTP请求头的值设置为中文,但如果直接设置为中文,则会抛出异常。比如下面的代码设置中文请求头Chinese。fromurllibimportrequesturl='http://httpbin.org/post'headers={'User-Agent':'Mozilla/5.0(Macintosh;IntelMacOSX10_14_3)AppleWebKit/537.36(KHTML,likeGecko)Chrome/72.0.3626.109Safari/537.36','Host':'httpbin.org','Chinese':'李宁',}req=request.Request(url=url,headers=headers,method="POST")request.urlopen(req)执行这段代码,它会抛出如下异常。UnicodeEncodeError:'latin-1'codeccan'tencodecharactersinposition0-1:ordinalnotinrange(256)这个异常说明HTTP请求头只能是英文字符和符号,不能是双字节文本,比如中文。为了解决这个问题,需要在设置HTTP请求头的时候对汉字进行编码,发送到服务器后在服务器上用同样的规则进行解码。可以使用多种编码方式,比如url编码,base64编码,url编码的意思是如果在浏览器地址栏输入中文,会被转换成%xx的形式。如果输入“中国”,则变成E4%B8%AD%E5%9B%BD。对字符串url进行编码需要使用urllib.parse模块的urlencode函数,解码需要使用unquote函数,代码如下:fromurllib.parseimportunquote,urlencode#EncodeChinesevalue=urlencode({'name':'李宁'})print(value)#解码中文print(unquote(value))执行这段代码,会输出如下结果:name=%E6%9D%8E%E5%AE%81name=WhenLiNing使用urlencode函数进行编码,需要指定字典类型不能直接对字符串进行编码。因为urlencode函数只能对url参数进行编码。base64编码需要使用base64模块中的b64encode函数,解码使用b64decode函数。代码如下:importbase64#Encode中文base64Value=base64.b64encode(bytes('Python从菜鸟到高手',encoding='utf-8'))print(str(base64Value,'utf-8'))#Decode中文,将解码结果按照utf-8编码格式转换成字符串print(str(base64.b64decode(base64Value),'utf-8'))b64encode函数编码后返回一个bytes类型,需要使用str函数将其转换为字符串类型。b64decode函数解码时需要指定bytes类型的值,而b64decode函数的返回值也是bytes类型,所以还需要str函数将函数的返回值转成字符串。下面的例子演示了设置中文HTTP请求头并进行解码的完整过程。fromurllibimportrequestfromurllib.parseimportunquote,urlencodeimportbase64url='http://httpbin.org/post'headers={'User-Agent':'Mozilla/5.0(Macintosh;IntelMacOSX10_14_3)AppleWebKit/537.36(KHTML,likeGecko)Chrome/72.0.3626.109Safari/537.36','Host':'httpbin.org','Chinese1':urlencode({'name':'李宁'}),#设置中文HTTP请求头,使用url编码格式#设置中文HTTP请求头,使用base64编码格式'MyChinese':base64.b64encode(bytes('这是中文HTTP请求头',encoding='utf-8')),'who':'PythonScrapy'}dict={'name':'Bill','age':30}data=bytes(urlencode(dict),encoding='utf-8')req=request.Request(url=url,data=data,headers=headers,method="POST")#通过add_header方法添加中文HTTP请求头,url编码格式req.add_header('Chinese2',urlencode({"nationality":"China"}))response=request.urlopen(req)#获取服务器的响应信息value=response.read().decode('utf-8')print(value)importjson#将返回值转换为json对象responseObj=json.loads(value)#解码url编码格式的HTTP请求头print(unquote(responseObj['headers']['Chinese1']))#解码url编码格式的HTTP请求头print(unquote(responseObj['headers']['Chinese2']))#解码base64编码格式的HTTP请求头print(str(base64.b64decode(responseObj['headers']['Mychinese']),'utf-8'))运行结果如图1图1设置中文HTTP请求Header本文转载自微信公众号“极客起源”,可通过以下二维码关注。转载本文请联系极客本源公众号。
