22

我真的厌倦了试图弄清楚为什么这段代码在 Python 2 中而不是在 Python 3 中有效。我只是想抓取一页 json 然后解析它。这是 Python 2 中的代码:

import urllib, json
response = urllib.urlopen("http://reddit.com/.json")
content = response.read()
data = json.loads(content)

认为Python 3 中的等效代码是这样的:

import urllib.request, json
response = urllib.request.urlopen("http://reddit.com/.json")
content = response.read()
data = json.loads(content)

但它在我面前爆炸了,因为 read() 返回的数据是“字节”类型。但是,我一辈子都无法将它转换为 json 能够解析的东西。我从标题中知道 reddit 正试图将 utf-8 发送回给我,但我似乎无法将字节解码为 utf-8:

import urllib.request, json
response = urllib.request.urlopen("http://reddit.com/.json")
content = response.read()
data = json.loads(content.decode("utf8"))

我究竟做错了什么?

编辑:问题是我无法使数据进入可用状态;即使 json 加载数据,它的一部分是无法显示的,我希望能够将数据打印到屏幕上。

第二次编辑:问题似乎更多地与打印而不是解析有关。Alex 的回答通过将 IO 设置为 utf8 为脚本在 Python 3 中工作提供了一种方法。但是仍然存在一个问题:为什么代码在 Python 2 中有效,而在 Python 3 中无效?

4

4 回答 4

15

您发布的代码可能是由于错误的剪切和粘贴操作,因为它在两个版本中显然都是错误的(f.read()因为没有f定义裸名而失败)。

在 Py3 中,ur = response.decode('utf8')对我来说效果很好,下面的json.loads(ur). 也许错误的复制和粘贴影响了您的 2 到 3 转换尝试。

于 2010-06-28T00:06:03.280 回答
7

取决于您的 python 版本,您必须选择正确的库。

对于蟒蛇 3.5

import urllib.request
data = urllib.request.urlopen(url).read().decode('utf8')

对于蟒蛇 2.7

import urllib
url = serviceurl + urllib.urlencode({'sensor':'false', 'address': address})   
uh = urllib.urlopen(url)
于 2015-10-27T00:29:02.230 回答
0

请在另一个 Unicode 相关问题中查看答案。

现在:Python 3 str(它是 Python 2 unicode)类型是一个理想化的对象,因为它处理的是“字符”,而不是“字节”。为了用于磁盘/网络数据/从磁盘/网络数据中使用这些字符,需要通过“转换表”(即编码又名代码页)将字节编码为/解码。由于操作系统的多样性,Python 历来避免猜测该编码应该是什么。多年来一直在改变,但仍然是“面对歧义,拒绝猜测的诱惑”的原则。适用。

值得庆幸的是,Web 服务器使您的工作更轻松。您的response上述内容应为您提供所需的所有额外信息:

>>> response.headers['content-type']
'application/json; charset=UTF-8'

因此,每次向 Web 服务器发出请求时,请检查 Content-Type 标头中的字符集值,并使用该字符集将请求的数据解码为 Unicode(Python 3: bytes.decode(charset)str)。

于 2011-10-17T00:10:45.433 回答
0

这是一种在两个版本之间都兼容的方法 - 它首先将字节数据转换为字符串,然后加载字符串。

import json
try:
    from urllib.request import Request, urlopen #python3+
except ImportError:
    from urllib2 import Request, urlopen        #python2

url = 'https://jsonfeed.org/feed.json'
request = Request(url)
response_json_string = urlopen(request).read().decode('utf8')
response_json_object = json.loads(response_json_string)
于 2020-02-07T22:08:14.873 回答