Python UnicodeDecodeError:&x27;ascii';编解码器可以';t解码位置0处的字节0xff:序号不在范围内(128)

Python UnicodeDecodeError:&x27;ascii';编解码器可以';t解码位置0处的字节0xff:序号不在范围内(128),python,Python,我有一个Python脚本,它使用tinypng api递归地转换图像,由于某些原因,它无法工作,我得到: UnicodeDecodeError:“ascii”编解码器无法解码位置0:ordinal中的字节0xff 不在范围内(128) 我做错了什么 import os import base64 from os.path import dirname from urllib2 import Request, urlopen from base64 import b64encode compre

我有一个Python脚本,它使用tinypng api递归地转换图像,由于某些原因,它无法工作,我得到:

UnicodeDecodeError:“ascii”编解码器无法解码位置0:ordinal中的字节0xff 不在范围内(128)

我做错了什么

import os
import base64
from os.path import dirname
from urllib2 import Request, urlopen
from base64 import b64encode

compress_png = True 
compress_jpg = True
import_dir = '666\product'
output_dir = '666\product'
tiny_png_key = 'xxxxxx'
tiny_png_url = 'https://api.tinypng.com/shrink'

img_count = 0
file_count = 0
compress_count = 0
existing_count = 0


def compressImage(filepath, filedest, overwrite = True):
    global compress_count
    global existing_count
    if not os.path.isfile(filedest) or overwrite: 
        status = ''
        request = Request(tiny_png_url, open(filepath, "rb").read())
        auth = b64encode(bytes("api:" + tiny_png_key)).decode("ascii")
        request.add_header("Authorization", "Basic %s" % auth)
        response = urlopen(request)

        if response.getcode() == 201:
            status = "success";
            headers = response.info()
            result = urlopen(headers["Location"]).read()

            if not os.path.exists(os.path.dirname(filedest)):
                os.makedirs(os.path.dirname(filedest))
            open(filedest, "wb").write(result)
            compress_count += 1
        else:
            status = "failed"
        print 'Compressing: %s\nFile: %s\nStatus: %s\n'%(filepath, img_count, status)
    else:
        existing_count += 1


# loop througs files in import_dir recursively 
for subdir, dirs, files in os.walk(import_dir):
    for file in files:
        filepath = os.path.join(subdir, file)
        fileName, fileExtension = os.path.splitext(file)
        file_count += 1
        if(fileExtension == '.png' and compress_png) or (fileExtension == '.jpg' and compress_jpg):
            img_count += 1
            filedest = filepath.replace(import_dir, output_dir)
            compressImage(filepath, filedest)


print '================'
print 'Total Files: %s'%(file_count)
print 'Total Images: %s'%(img_count)
print 'Images Compressed: %s'%(compress_count)
print 'Images Previously Compressed (Exist in output directory): %s'%(existing_count)
完全错误:

Traceback (most recent call last):
    File "C:\Users\Vygantas\Desktop\test.py", line 55, in <module> compressImage(filepath, filedest)
    File "C:\Users\Vygantas\Desktop\test.py", line 28, in compressImage response = urlopen(request)
    File "C:\Python27\lib\urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout)
    File "C:\Python27\lib\urllib2.py", line 391, in open response = self._open(req, data)
    File "C:\Python27\lib\urllib2.py", line 409, in _open '_open', req)
    File "C:\Python27\lib\urllib2.py", line 369, in _call_chain result = func(*args)
    File "C:\Python27\lib\urllib2.py", line 1181, in https_open return self.do_open(httplib.HTTPSConnection, req)
    File "C:\Python27\lib\urllib2.py", line 1142, in do_open h.request(req.get_method(), req.get_selector(), req.data, headers)
    File "C:\Python27\lib\httplib.py", line 946, in request self._send_request(method, url, body, headers)
    File "C:\Python27\lib\httplib.py", line 987, in _send_request self.endheaders(body)
    File "C:\Python27\lib\httplib.py", line 940, in endheaders self._send_output(message_body)
    File "C:\Python27\lib\httplib.py", line 801, in _send_output msg += message_body UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
回溯(最近一次呼叫最后一次):
压缩图像(filepath,filedest)中第55行的文件“C:\Users\Vygantas\Desktop\test.py”
文件“C:\Users\Vygantas\Desktop\test.py”,第28行,压缩图像响应=urlopen(请求)
文件“C:\Python27\lib\urllib2.py”,第126行,在urlopen return\u opener.open(url,数据,超时)中
文件“C:\Python27\lib\urllib2.py”,第391行,在open response=self.\u open(请求,数据)中
文件“C:\Python27\lib\urllib2.py”,第409行,在_open'_open',req中)
文件“C:\Python27\lib\urllib2.py”,第369行,在_call_chain result=func(*args)中
文件“C:\Python27\lib\urllib2.py”,第1181行,在https_open中返回self.do_open(httplib.HTTPSConnection,req)
文件“C:\Python27\lib\urllib2.py”,第1142行,在do_open h.request(req.get_方法(),req.get_选择器(),req.data,标题)中
文件“C:\Python27\lib\httplib.py”,第946行,在请求self.\u发送\u请求(方法、url、正文、标题)中
文件“C:\Python27\lib\httplib.py”,第987行,在_send_request self.endheaders(body)中
文件“C:\Python27\lib\httplib.py”,第940行,在endheaders self.\u send\u输出(消息体)中
文件“C:\Python27\lib\httplib.py”,第801行,在_send_output msg+=message_body UnicodeDecodeError:“ascii”编解码器无法解码位置0中的字节0xff:序号不在范围内(128)

您必须对数据进行编码,但不能对用户名进行编码 我想尝试一下:

def compressImage(filepath, filedest, overwrite = True):
    global compress_count
    global existing_count
    if not os.path.isfile(filedest) or overwrite: 
        status = ''
        data = open(filepath, "rb").read()
        data = base64.b64encode(data)
        request = Request(tiny_png_url, data)
        request.add_header("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
        auth = "api:" + tiny_png_key
        request.add_header("Authorization", "Basic %s" % auth)
        response = urlopen(request)

使用网站上的示例并将其改编为Python 2(与您所做的方式相同)似乎对我有用:

from os.path import dirname
from urllib2 import Request, urlopen
from base64 import b64encode

key = "xxxx_xxxx"
input = "NLMK.png"
output = "tiny-output.png"

request = Request("https://api.tinypng.com/shrink", open(input, "rb").read())

auth = b64encode("api:" + key).decode("ascii")
request.add_header("Authorization", "Basic %s" % auth)

response = urlopen(request)
if response.getcode() == 201:
    # Compression was successful, retrieve output from Location header.
    headers = response.info()
    result = urlopen(headers["Location"]).read()
    open(output, "wb").write(result)
else:
    # Something went wrong! You can parse the JSON body for details.
    print("Compression failed")

一般建议。将代码精简到最低限度,然后学习一些调试技术。“auth=b64encode(bytes(“api:+tiny_png_key”).decode(“ascii”)”的目的是什么,而不进行回溯(最近一次调用):文件“”,第55行,压缩图像(filepath,filedest)文件“”,第28行,压缩图像响应=urlopen(请求)文件“urllib2.py”,第126行,在urlopen return\u opener.open(url、数据、超时)文件“urllib2.py”第397行,在open response=meth(req、response)文件“urllib2.py”第510行,在http\u response“http”、请求、响应、代码、消息、hdrs)文件“urllib2.py”第435行,在错误返回self中,在第518行的_call_chain result=func(*args)文件“urllib2.py”中,在http_error_default raise HTTPError(req.get_full_url(),code,msg,hdrs,fp)urllib2.HTTPError:http error 401:Hey的未经授权的可能重复,谢谢,但在这一行上出现错误:request=request(tiny_png_url,data))request=request(tiny_png_url,data))^SyntaxError:无效语法更改为request=request(微小的png\U url,数据)仍然错误文件“test.py”,如果response.getcode()==201,则第33行:^TabError:缩进中制表符和空格的使用不一致,但我不确定我的答案是否正确。我已经用一段代码做了一些测试,它看起来更像你的原始代码,对我来说效果很好。我现在怀疑这个答案是否相关。我正在考虑删除它。