【发布时间】:2015-12-15 13:40:32
【问题描述】:
嘿,我尝试将那个小 sn-p 从 2 移植到 Python 3。
Python 2:
def _download_database(self, url):
try:
with closing(urllib.urlopen(url)) as u:
return StringIO(u.read())
except IOError:
self.__show_exception(sys.exc_info())
return None
Python 3:
def _download_database(self, url):
try:
with closing(urllib.request.urlopen(url)) as u:
response = u.read().decode('utf-8')
return StringIO(response)
except IOError:
self.__show_exception(sys.exc_info())
return None
但我还是得到了
utf-8 codec can't decode byte 0x8f in position 12: invalid start byte
我需要使用 StringIO,因为它是一个 zipfile,我想用那个函数解析它:
def _parse_zip(self, raw_zip):
try:
zip = zipfile.ZipFile(raw_zip)
filelist = map(lambda x: x.filename, zip.filelist)
db_file = 'IpToCountry.csv' if 'IpToCountry.csv' in filelist else filelist[0]
with closing(StringIO(zip.read(db_file))) as raw_database:
return_val = self.___parse_database(raw_database)
if return_val:
self._load_data()
except:
self.__show_exception(sys.exc_info())
return_val = False
return return_val
raw_zip 是下载数据库函数的返回
【问题讨论】:
-
您收到的数据的编码显然是不是 UTF-8。它是什么编码?如果 Web 服务器是正确的,那么 HTTP 响应的
Content-Type标头应该告诉您,以及文档中可能的 HTML<meta>标记(如果是 HTML)。 -
许多网络服务器的默认编码是iso-8859-1。
-
Here 是 StackOverflow 上的现有问题,其答案解释了将字节解码为字符。
-
那个 url 正在下载一个 zip 文件 -- 你为什么要把一个二进制文件转换成一个字符串?
-
@Fragkiller 正如其他人所指出的,您正在检索二进制文件,而不是文本。 Ashley Wilson 的回答显示了如何获取字节。它在 Python 2 中“工作”的原因是因为 Python 2 在字节与字符方面非常草率,并且没有很好地处理 Unicode。在 Python 3 中,您需要了解其中的区别。
标签: python-3.x urllib stringio