在使用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. 基于TF-IDF值的汉语语义消歧算法

    RT,学校课题需要233,没了 话说,窝直接做个链接的集合好了,方便以后查找 特征值提取之 -- TF-IDF值的简单介绍 汉语语义消歧之 -- 句子相似度 汉语语义消歧之 -- 词义消歧简介 c++ ...

  2. .htaccess的301重定向代码

    把不带www的域名301到带www的域名 RewriteEngine On RewriteCond %{http_host} ^example.com$ [NC] RewriteRule ^(.*)$ ...

  3. SAP常用命令及BASIS操作

    Pfcg         角色,权限参数文件配置Su53        查看权限对象  st01  跟踪St22         看dump,以分析错误  eg.找到ABAP程序出错的地方,找出fou ...

  4. 通过top命令发现plymouthd进程cpu负载达到近100% 解决办法

    最近几天一直遇到服务器cpu100%, 通过top命令发现plymouthd进程cpu负载达到近100% 解决方法:打开 /boot/grub/menu.lst , 去掉 “rhgb quiet”这两 ...

  5. sprintf函数

    sprintf函数用法举例 #include<stdio.h> int main() { //1.连接字符串 char a1[] = {'A', 'B', 'C', 'D', 'E', ' ...

  6. K2 BPM打造企业新门户,步入移动办公时代

    公司介绍步步高教育电子有限公司(前身为步步高电脑电玩厂)是广东步步高电子工业有限公司属下的三个分公司之一,一直致力于面向广大学生的教育电子产品的研发与生产,主要产品有视频学习机.点读机.学生电脑.语言 ...

  7. 图表控件== 百度 echarts的入门学习

    花了3天的时间 去学习跟试用之前两款的图表控件 hightcharts(商业,人性化,新手非常方便试用,图表少了点) 跟chartjs==>搭配vue更好 控件,整体而言都还可以. http:/ ...

  8. GCD下的几种实现同步的方式

    GCD多线程下,实现线程同步的方式有如下几种: 1.串行队列 2.并行队列 3.分组 4.信号量 实例: 去网上获取一张图片并展示在视图上. 实现这个需求,可以拆分成两个任务,一个是去网上获取图片,一 ...

  9. 使用python-openCV对摄像头捕捉的镜头进行二值化并打上文字

    用CaptureFromCAM函数对图像进行提取: capture = cv.CaptureFromCAM(0) 读取直接的视频文件只需将语句改变为: capture = cv.VideoCaptur ...

  10. node.js在linux下的安装

    简单说就是解压后,在bin文件夹中已经存在node以及npm,如果你进入到对应文件的中执行命令行一点问题都没有,不过不是全局的,所以将这个设置为全局就好了. ? 1 2 3 cd node-v0.10 ...