博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Requests库上传文件时UnicodeDecodeError: 'ascii' codec can't decode byte错误解析
阅读量:6759 次
发布时间:2019-06-26

本文共 3832 字,大约阅读时间需要 12 分钟。

在使用Request上传文件的时候碰到如下错误提示:

2013-12-20 20:51:09,235 __main__     ERROR    'ascii' codec can't decode byte 0xe7 in position 27379: ordinal not in range(128)Traceback (most recent call last):  File "server_merge.py", line 251, in avml_storage    result_f , result_m = avml_storage.uploadData( storage_key, xml_content )  File "/opt/ResultCollector/app/utils/ADFSAvml.py", line 33, in uploadData    r = requests.post(uploadUrl, files=f)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/api.py", line 88, in post    return request('post', url, data=data, **kwargs)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/api.py", line 44, in request    return session.request(method=method, url=url, **kwargs)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/sessions.py", line 335, in request    resp = self.send(prep, **send_kwargs)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/sessions.py", line 438, in send    r = adapter.send(request, **kwargs)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/adapters.py", line 292, in send    timeout=timeout  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 428, in urlopen    body=body, headers=headers)  File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 280, in _make_request    conn.request(method, url, **httplib_request_kw)  File "/usr/local/lib/python2.7/httplib.py", line 946, in request    self._send_request(method, url, body, headers)  File "/usr/local/lib/python2.7/httplib.py", line 987, in _send_request    self.endheaders(body)  File "/usr/local/lib/python2.7/httplib.py", line 940, in endheaders    self._send_output(message_body)  File "/usr/local/lib/python2.7/httplib.py", line 801, in _send_output    msg += message_bodyUnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 27379: ordinal not in range(128)

从traceback很容易辨别出来,发生错误的位置应该是在httplib.py中的_send_output函数中,可能是将unicode 和 str 混用导致的,通过跟踪发现 msg是unicode类型,message_body是str类型。

继续往前追溯,发现Requests将Content-Length设置为unicode,可能是为了方便操作,Request在compat.py中将str做了转义:

if is_py2:    from urllib import quote, unquote, quote_plus, unquote_plus, urlencode    from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag    from urllib2 import parse_http_list    import cookielib    from Cookie import Morsel    from StringIO import StringIO    from .packages.urllib3.packages.ordered_dict import OrderedDict    builtin_str = str    bytes = str    str = unicode    basestring = basestring    numeric_types = (int, long, float)

 

所以Requests中使用的str都是unicode类型的数据,通过_output、_send_output以及putheader几个函数可以得知问题可能出在putheader函数中对header的处理上,很有可能是没有将unicode转换成str所导致的。
putheader代码如下:

def putheader(self, header, value):        """Send a request header line to the server.        For example: h.putheader('Accept', 'text/html')        """        if self.__state != _CS_REQ_STARTED:            raise CannotSendHeader()        str = '%s: %s' % (header, value)        self._output(str)

偶然的机会发现同样的操作方式,使用Request上传文件在另外一台机器上好用,比较两台机器的环境发现只有Python的版本不一致,一个是Python2.7, 一个是Python2.7.3,对比httplib.py发现在功能运行正常的机器(Python2.7.3)上putheader的代码如下:

def putheader(self, header, *values):        """Send a request header line to the server.        For example: h.putheader('Accept', 'text/html')        """        if self.__state != _CS_REQ_STARTED:            raise CannotSendHeader()        hdr = '%s: %s' % (header, '\r\n\t'.join([str(v) for v in values]))        self._output(hdr)

通过对比可以很容易看出,Python 2.7.3已经对传入的value做了显式转换,从未避免了某些潜在的错误。

又验证了几个版本,发现 Python 2.6.6、Python2.7是使用Requests库的时候都存在问题, Python 2.7.3、Python2.7.5 都没有问题。建议将Python版本升级至2.7.3以上

转载地址:http://jxfeo.baihongyu.com/

你可能感兴趣的文章
nullnull用宏定义swap(x,y)
查看>>
【Javascript】类,封装性 -- 1
查看>>
Mono for Android安装配置破解
查看>>
uploadfy 常见问题收集
查看>>
WPF----数据绑定
查看>>
子类化GetOpenFileName/GetSaveFileName, 以及钩子函数OFNHookProc的使用的简要说明
查看>>
C语言中判断int,long型等变量是否赋值的方法
查看>>
leetcode -- Longest Valid Parentheses
查看>>
详解JAVA输出Hello World
查看>>
概率问题随笔
查看>>
关于在堆中创建字符串对象的疑惑
查看>>
poj1077(康托展开+bfs+记忆路径)
查看>>
hibernate 树状映射
查看>>
值得 Web 开发人员收藏的20个 HTML5 实例教程
查看>>
移动设备、手机浏览器Javascript滑动事件代码
查看>>
linux,__attribute__用法
查看>>
LinqToXML~读XML文件续
查看>>
java.sql.SQLException: JZ00L
查看>>
@Resource注解
查看>>
Android(Linux) 网卡名修改
查看>>