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

  1. 2013-12-20 20:51:09,235 __main__ ERROR 'ascii' codec can't decode byte 0xe7 in position 27379: ordinal not in range(128)
  2. Traceback (most recent call last):
  3. File "server_merge.py", line 251, in avml_storage
  4. result_f , result_m = avml_storage.uploadData( storage_key, xml_content )
  5. File "/opt/ResultCollector/app/utils/ADFSAvml.py", line 33, in uploadData
  6. r = requests.post(uploadUrl, files=f)
  7. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/api.py", line 88, in post
  8. return request('post', url, data=data, **kwargs)
  9. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/api.py", line 44, in request
  10. return session.request(method=method, url=url, **kwargs)
  11. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/sessions.py", line 335, in request
  12. resp = self.send(prep, **send_kwargs)
  13. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/sessions.py", line 438, in send
  14. r = adapter.send(request, **kwargs)
  15. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/adapters.py", line 292, in send
  16. timeout=timeout
  17. File "/usr/local/lib/python2.7/site-packages/requests-1.2.3-py2.7.egg/requests/packages/urllib3/connectionpool.py", line 428, in urlopen
  18. body=body, headers=headers)
  19. 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
  20. conn.request(method, url, **httplib_request_kw)
  21. File "/usr/local/lib/python2.7/httplib.py", line 946, in request
  22. self._send_request(method, url, body, headers)
  23. File "/usr/local/lib/python2.7/httplib.py", line 987, in _send_request
  24. self.endheaders(body)
  25. File "/usr/local/lib/python2.7/httplib.py", line 940, in endheaders
  26. self._send_output(message_body)
  27. File "/usr/local/lib/python2.7/httplib.py", line 801, in _send_output
  28. msg += message_body
  29. UnicodeDecodeError: '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做了转义:

  1. if is_py2:
  2. from urllib import quote, unquote, quote_plus, unquote_plus, urlencode
  3. from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag
  4. from urllib2 import parse_http_list
  5. import cookielib
  6. from Cookie import Morsel
  7. from StringIO import StringIO
  8. from .packages.urllib3.packages.ordered_dict import OrderedDict
  9.  
  10. builtin_str = str
  11. bytes = str
  12. str = unicode
  13. basestring = basestring
  14. numeric_types = (int, long, float)

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

  1. def putheader(self, header, value):
  2. """Send a request header line to the server.
  3.  
  4. For example: h.putheader('Accept', 'text/html')
  5. """
  6. if self.__state != _CS_REQ_STARTED:
  7. raise CannotSendHeader()
  8.  
  9. str = '%s: %s' % (header, value)
  10. self._output(str)

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

  1. def putheader(self, header, *values):
  2. """Send a request header line to the server.
  3.  
  4. For example: h.putheader('Accept', 'text/html')
  5. """
  6. if self.__state != _CS_REQ_STARTED:
  7. raise CannotSendHeader()
  8.  
  9. hdr = '%s: %s' % (header, '\r\n\t'.join([str(v) for v in values]))
  10. 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以上

Requests库上传文件时UnicodeDecodeError: 'ascii' codec can't decode byte错误解析的更多相关文章

  1. python 3以上版本使用pickle.load读取文件报UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6

    python 3以上版本使用pickle.load读取文件报UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6 ...

  2. 解决python3读写中文txt时UnicodeDecodeError : 'ascii' codec can't decode byte 0xc4 in position 5595: ordinal not in range(128) on line 0的问题

    今天使用python3读写含有中文的txt时突然报了如下错误,系统是MAC OS,iDE是pycharm: UnicodeDecodeError : 'ascii' codec can't decod ...

  3. Python HTMLTestRunner生成网页自动化测试报告时中文编码报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6

    1. 由于使用Python Selenium做网页自动化测试时,有截取网页上的中文信息保存到测试结果中,最终出现编码错误如下: File "D:/PycharmProjects/AutoTe ...

  4. python2.7安装第三方库错误:UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0

    开发环境:win10, x64, pycharm社区版,python2.7.13 python2经常会遇见乱码的问题,并且一遇到中文就乱码.所以我们在安装的时候要注意,无论是解释器interpreto ...

  5. python3运行调用htmltestrunner时,报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0

    之前解决过一次,又忘了,这次写下来了..百度没有的,跟我环境有关! 环境:自动化运行环境python3.6.5 上期说到了,写了一个bat来运行runallcase.py. 但是双击运行却报错:Uni ...

  6. setuptools,pip,install,UnicodeDecodeError: 'ascii' codec can't decode byte.原因和解决方案

    昨天重装Python2.7.6时,为了安装第三方库,我去下pip.为了装pip,又得先装 ez_setup.py.结果装ez_setup时,遇到了问题,报错: UnicodeDecodeError:  ...

  7. UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0

    Windows 7/8/10机器上安装Python 2.7后,下载一些Package包进行setup时总是报错UnicodeDecodeError,如下: File "C:/Python27 ...

  8. Windows下使用pip安装python包是报错-UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0

    先交待下开发环境: 操作系统:Windows 7 Python版本:2.7.9 Pip版本:6.1.1 其他环境忽略 在windows下使用pip下载python包,出现如下错误 Collecting ...

  9. 【Python】【解决】UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(128)

    1.问题描述 今天在升级Ubuntu到14.04,使用命令行启动软件更新器,进行版本升级,结果开始升级就异常退出了,具体打印如下: $update-manager -d 正在检查新版 Ubuntu 使 ...

随机推荐

  1. mysql 配置 utf8 依然乱码

    mysql 乱码问题排除方案: 1.检查数据库及数据表是不是utf8字符集 2.查看一下jdbc.properties配置的数据库url 是否配置了characterEncoding=UTF-8或者在 ...

  2. Mysql:The table‘xxxx’is full

    下午跑程序,在插入mysql时突然报错: "The table'xxxx'is full" 而之前一直没问题的. 上网查了一下,都说临时表的问题,需要设置"tmp_tab ...

  3. 2016.9.18 --- Shenyang ol

    1001 Resident Evil 1002 List wants to travel 1003 hannnnah_j’s Biological Test 1004 Mathematician QS ...

  4. Git切换分支出现提示'SSL端口:44301'及解决方案

    切换分支出现如下提示,并且自动签出了项目文件csproj. 修改项目文件csproj 修改前: <UseIISExpress>true</UseIISExpress> < ...

  5. NOIP2014感想

    NOIP2014转眼就结束了,让人不由感慨时间之快,仿佛几天前还是暑假,几天后就已经坐在考场里了. 从暑假8月开始写博客,发了一些解题报告什么的,但这篇文章不再会是“题目大意 & 解题过程 & ...

  6. 二模 (15)day1

    第一题: 题目大意: 有两个长度为N的序列A和B,在A和B中各任取一个数相加可以得到N2个和,求这N2个和中最小的N个. 解题过程: 1.这题是刘汝佳<<训练指南>>上的一道经 ...

  7. ios学习之UISwipeGestureRecognizer手势识别

    ios学习之UISwipeGestureRecognizer手势识别   本文部分转自俺是一个瓜娃!!!的博客UISwipeGestureRecognizer ---手指动作,转载过来仅是为了自己查询 ...

  8. JS运动基础(二) 摩擦运动、缓冲运动

    摩擦运动: 逐渐变慢,最后停止 缓冲运动: 与摩擦力的区别:可以精确的停到指定目标点距离越远速度越大速度由距离决定速度=(目标值-当前值)/缩放系数Bug:速度取整值取整: iSpeed = iSpe ...

  9. C# 对List<T>取交集、连集及差集

    1. 取交集 List A :{1,5,9,3,7} List B:{1,6,8,5,3,2,9,4} var intersectedList = listA.Intersect(listB, new ...

  10. 图片标签img中,为什么使用alt属性没用

    alt属性 alt属性是为了给那些不能看到你文档中图像的浏览者提供文字说明的.所以alt属性的本意是用于替换图像,而不是为图像提供额外说明的,但是,在ie浏览器中,alt属性会变成文字提示,这本身是一 ...