在使用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. SAP物料批次管理配置及操作手册(轉載)

    这个有待学习 业务说明需要先熟悉基本的物料管理(MM).生产计划管理(PP).销售与分销管理(SD)的相关知识.在化工.制药.快消.汽车零部件等行业,为了进行质量的跟踪,往往需要使用批次管理来监控质量 ...

  2. zookeeper学习系列:三、利用zookeeper做选举和锁

    之前只理解zk可以做命名,配置服务,现在学习下他怎么用作选举和锁,进一步还可构建master-slave模式的分布式系统. 为什么叫Zoo?“因为要协调的分布式系统是一个动物园”. ZooKeeper ...

  3. linux 的 磁盘操作

    //显示目录和文件 以kb m g为单位 du -ah //总大小 du -sh /etc //查看分区 fdisk -l //对磁盘进行分区 fdisk /dev/sdb //格式化分区 mkfs ...

  4. Linux diable ipv6

    在RHEL 5下面测试成功     linux下面禁止ipv6的方法: 来自: 杨志刚 博客 (http://yangzhigang.cublog.cn)   这里我所做的是Redhat Linux, ...

  5. redis教程

    windows下安装redis: http://jingyan.baidu.com/article/49ad8bce40174f5834d8fa24.html redis教程: http://www. ...

  6. linux maven安装配置

    1.Run the wget command from the dir you want to extract maven too. wget http://mirrors.cnnic.cn/apac ...

  7. iwebshop 订单存库修改为下单件库存

    //减少库存量 $orderGoodsDB = new IModel('order_goods'); $orderGoodsList = $orderGoodsDB->query('order_ ...

  8. NSURLCache 和 NSCache 的区别

    NSURLCache 和 NSCache 的区别 NSURLCache提供的是URL Request缓存,可以在Memory和Disk上:NSCache提供了HTTP Request外的东西的缓存方式 ...

  9. IOS 验证码

    将十六进制的字符串转化为UIImage 最近写一个项目,有验证码,但是接口返回的并不是验证码图片的URL,而是返回的字节数组16进制字符串.这样就需要把16进制字符串首先字节数组,其次再把字节数组转化 ...

  10. C#中this在扩展方法的应用

    给类添加扩展方法 1.定义一个类Service public class Service { private string _name; public string Name { get { retu ...