【Python爬虫】一招搞定发送中文HTTP请求头

有时须要将HTTP 请求头的值设为中文,但若是直接设成中文,会抛出异常,例如,下面的代码为Chinese 请求头设置了中文。
from urllib import requesturl = 'http://httpbin.org/post'headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36', 'Host':'httpbin.org', 'Chinese':'李宁',}req = request.Request(url = url,headers=headers,method="POST")request.urlopen(req)
 
执行这段代码,会抛出以下的异常。
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-1: ordinal not in range(256)

这个异常代表HTTP 请求头只能是英文字符和符号,不能是双字节的文字,如中文。为了解决这个问题,在设置HTTP 请求头时须要将中文编码,而后发送到服务端后,在服务端用一样的规则解码。能够采用多种编码方式,例如url 编码,base64 编码,url 编码就是在浏览器地址栏中若是输入中文,会将其转换为%xx 的形式。如输入“中国”,会变成E4%B8%AD%E5%9B%BD
对字符串url 编码,须要使用urllib.parse 模块的urlencode 函数,解码要使用unquote 函数,代码以下:
from urllib.parse import unquote,urlencode# 对中文进行编码value = urlencode({'name':'李宁'})print(value)# 对中文进行解码print(unquote(value))
执行这段代码,会输出以下结果:
name=%E6%9D%8E%E5%AE%81name=李宁
使用urlencode 函数进行编码时,须要指定字典类型,不能直接对字符串进行编码。由于urlencode 函数只能对url 参数进行编码。
base64 编码须要使用base64 模块中的b64encode 函数,解码使用b64decode 函数,代码以下:
import base64# 对中文进行编码base64Value = base64.b64encode(bytes('Python从菜鸟到高手',encoding='utf-8'))print(str(base64Value,'utf-8'))# 对中文进行解码,并按utf-8编码格式将解码后的结果转换为字符串print(str(base64.b64decode(base64Value),'utf-8'))
 
b64encode 函数编码后返回的是bytes 类型,须要使用str 函数将其转换为字符串类型。b64decode 函数解码时须要指定bytes 类型的值,b64decode 函数的返回值也是bytes 类型,因此也须要str 函数将该函数的返回值转换为字符串。
下面的例子演示了设置中文HTTP 请求头,并对其解码的完整过程。
from urllib import requestfrom urllib.parse import unquote,urlencodeimport base64url = 'http://httpbin.org/post'headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36', 'Host':'httpbin.org', 'Chinese1':urlencode({'name':'李宁'}), # 设置中文HTTP请求头,用url编码格式 # 设置中文HTTP请求头,用base64编码格式 'MyChinese':base64.b64encode(bytes('这是中文HTTP请求头',encoding='utf-8')), 'who':'Python Scrapy'}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({"国籍":"中国"}))response=request.urlopen(req)# 获取服务端的响应信息value = response.read().decode('utf-8')print(value)import json# 将返回值转换为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请求头

- EOF -javascript


推荐阅读  点击标题可跳转

Python爬虫实战:抓取博客文章列表
java

卧槽,好强大的魔法,竟能让Python支持方法重载
python

Python装饰器(decorator)不过如此,是我想多了web

这样合并Python字典,能够让程序的运行效率提升4倍json

Python代码能够加密吗?Python字节码告诉你!swift

看我用元类(metaclass)花式建立Python类
浏览器

你不知道__name__变量是什么意思吗?
微信

Python生成器(Generator)最完美解释app

关注「极客起源」公众号,加星标,不错过精彩技术干货
函数


本文分享自微信公众号 - 极客起源(geekculture)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。