【发布时间】:2017-12-10 16:09:41
【问题描述】:
大家好,
我是使用 python 从网络获取数据的新手。我想把这个页面的源代码放在一个字符串中: https://projects.fivethirtyeight.com/2018-nba-predictions/
以下代码适用于其他页面(例如https://www.basketball-reference.com/boxscores/201712090ATL.html):
import urllib.request
file = urllib.request.urlopen(webAddress)
data = file.read()
file.close()
dataString = data.decode(encoding='UTF-8')
而且我希望 dataString 是一个 HTML 字符串(请参阅下文了解我在这种特定情况下的期望)
<!DOCTYPE html><html lang="en"><head><meta property="article:modified_time" etc etc
相反,对于 538 网站,我收到此错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
我的研究表明问题在于我的文件实际上并未使用 UTF-8 编码,但页面的字符集和 beautiful-soup 的 UnicodeDammit() 都声称它是 UTF-8(第二个可能是因为第一个)。 chardet.detect() 不建议任何编码。我尝试在 decode() 的编码参数中将以下内容替换为“UTF-8”,但无济于事:
ISO-8859-1
拉丁-1
Windows-1252
也许值得一提的是字节数组数据看起来不像我期望的那样。这是来自工作 URL 的 data[:10]:
b'\n<!DOCTYPE'
这是来自 538 站点的数据[:10]:
b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
怎么了?
【问题讨论】:
-
用
wget抓取数据提供了一个gzip压缩的文件,它在未压缩时提供了一个常规的UTF-8 HTML页面;可能是服务器配置不当,提供了一个压缩页面而没有设置相关的标题。 -
(看
file.headers['content-encoding']) -
@Ryan:确实它似乎将
gzip设置为content-encoding,但curl和wget都没有对此做任何事情,这很奇怪,因为它们通常会透明地处理传输-级别压缩...这台服务器的行为一定有些奇怪。 -
@matteoitalia 使用 wget 确实向我展示了它是 gzip 压缩的。对于使用 python 的我来说,这是一个陌生的领域,但它已经取得了足够的进展,我有信心进一步探索。谢谢!!
-
@AndyPollino:进一步研究,似乎
curl(没有--compressed)、wget和urllib(通常)不会自动处理压缩后的内容,因此它们不要设置相应的accept-encoding请求头,但是服务器无论如何都会提供gzip压缩的内容。看来你得自己处理了。 OTOH,伟大的requests库确实可以自己处理整个事情。
标签: python encoding utf-8 character-encoding