在使用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_body
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做了转义:

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以上

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. python学习------dictionary和set

    一.dictionary 1.字典的形式:a={‘key’:value,‘key1’:value,................} 2.字典的的key不能重复,是一个不可变对象 3.字典的的查找和添 ...

  2. JQ二级菜单练习之一~~~

    <div class="nav"> <ul> <li><a href="#">首页</a> < ...

  3. PHP数组去重..............过滤字段

    $test_data = M('hot'); //实例化数据表 $data = $test_data->Distinct(true)->field('descriprion')->o ...

  4. longitude

    确保有loc:[longitude, latitude]属性给loc增加索引AttractionSchema.index({loc: '2d'});使用geoNeardb.places.find( { ...

  5. 【64测试20161112】【Catalan数】【数论】【扩展欧几里得】【逆】

    Problem: n个人(偶数)排队,排两行,每一行的身高依次递增,且第二行的人的身高大于对应的第一行的人,问有多少种方案.mod 1e9+9 Solution: 这道题由1,2,5,14 应该想到C ...

  6. 使用UISegmentedControl的一个注意事项

    NSArray* array = [[NSArray alloc]initWithObjects:@"机会",@"联系人", nil]; //先确定segmen ...

  7. 需要使用id内省方法--responsesToSelector: 的两个地方

    第一个: 当从数组中取出对象,并且需要执行某个方法时,最好使用responsesToSelector:判断该对象是否可以 执行该方法.因为在OC数组中,取出的对象都是 id 类型的. 第二个: 在MV ...

  8. What is Requirement ?

    The IEEE 610 standard defines a requirement as: (1). a condition or capability needed by a user to s ...

  9. vitruviano

    维特鲁威人(意大利语:Uomo vitruviano) 是列奥纳多·达·芬奇在1487年前后创作的世界著名素描. 它是钢笔和墨水绘制的手稿,规格为34.4 cm × 25.5 cm. 根据约1500年 ...

  10. 公测后,微信小程序应用可能被拒原因.

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 34.0px "PingFang SC Semibold"; color: #23232 ...