Python 为什么可以';我不能解码这个UTF-8页面吗?

Python 为什么可以';我不能解码这个UTF-8页面吗?,python,encoding,utf-8,character-encoding,Python,Encoding,Utf 8,Character Encoding,大家好 我不熟悉使用python从web获取数据。我希望此页面的源代码为字符串: 以下代码适用于其他页面(例如): 我希望dataString是一个HTML字符串(关于我在这个特定案例中的期望,请参见下文) 我的研究表明,问题在于我的文件实际上没有使用UTF-8编码,但页面的字符集和Beauty soup的UnicodeAmmit()都声称它是UTF-8(第二个可能是因为第一个)。detect()不建议任何编码。我尝试用decode()的编码参数中的“UTF-8”替换以下内容,但无效: I

大家好

我不熟悉使用python从web获取数据。我希望此页面的源代码为字符串:

以下代码适用于其他页面(例如):

我希望dataString是一个HTML字符串(关于我在这个特定案例中的期望,请参见下文)

我的研究表明,问题在于我的文件实际上没有使用UTF-8编码,但页面的字符集和Beauty soup的UnicodeAmmit()都声称它是UTF-8(第二个可能是因为第一个)。detect()不建议任何编码。我尝试用decode()的编码参数中的“UTF-8”替换以下内容,但无效:

ISO-8859-1

拉丁语-1

Windows-1252

也许值得一提的是,字节数组数据看起来不像我期望的那样。以下是工作URL中的数据[:10]:

b'\n<!DOCTYPE'

怎么了?

您正在读取gzip压缩的数据:您必须解压缩它

服务器为您提供了gzip压缩数据;这并不完全常见,因为默认情况下
urllib
不会设置任何
accept encoding
值,因此服务器通常不会保守地压缩数据

不过,响应的
content encoding
字段已经设置,因此您可以知道您的页面确实是经过gzip压缩的,并且可以在进一步处理之前使用Python
gzip
模块对其进行解压缩

import urllib.request
import gzip
file = urllib.request.urlopen(webAddress)
data = file.read()
if file.headers['content-encoding'].lower() == 'gzip':
    data = gzip.decompress(data)
file.close()
dataString = data.decode(encoding='UTF-8')
OTOH,如果您有可能使用该模块,它将自行处理所有这些混乱,包括压缩(我是否提到过,除了
gzip
,您还可能得到
deflate
,哪个?)和(至少部分)编码

import requests
webAddress = "https://projects.fivethirtyeight.com/2018-nba-predictions/"
r = requests.get(webAddress)
print(repr(r.text))

这将执行您的请求并正确打印出已解码的Unicode字符串。

使用
wget
获取数据将提供一个gzip压缩文件,该文件未压缩后将提供一个常规的UTF-8 HTML页面;可能服务器配置不好,提供了一个压缩页面,但没有设置相关的标题。(查看
file.headers['content-encoding']
)@Ryan:确实,它似乎将
gzip
设置为
content-encoding
,但
curl
wget
都没有做任何事情,这很奇怪,通常,它们透明地处理传输级压缩。。。这台服务器的行为一定有点奇怪。@matteoitalia使用wget确实向我展示了它是gzip压缩的。对于我使用python来说,这是一个陌生的领域,但这已经足够让我有信心进一步探索。谢谢@AndyPollino:进一步看,似乎
curl
(没有
--compressed
)、
wget
urllib
(通常)不会自动处理gzip内容,因此它们不会设置相应的接受编码请求头,但服务器无论如何都会提供gzip内容。看来你得自己处理了。OTOH,伟大的
请求
库自己处理整个事情。
b'\n<!DOCTYPE'
b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
import urllib.request
import gzip
file = urllib.request.urlopen(webAddress)
data = file.read()
if file.headers['content-encoding'].lower() == 'gzip':
    data = gzip.decompress(data)
file.close()
dataString = data.decode(encoding='UTF-8')
import requests
webAddress = "https://projects.fivethirtyeight.com/2018-nba-predictions/"
r = requests.get(webAddress)
print(repr(r.text))