我正在尝试自学一些基本的网络抓取。使用 Python 的 requests 模块,我能够获取各种网站的 html,直到我尝试了这个:
>>> r = requests.get('http://www.wrcc.dri.edu/WRCCWrappers.py?sodxtrmts+028815+por+por+pcpn+none+mave+5+01+F')
我得到的不是作为此页面源的基本 html,而是:
>>> r.text
'\x1f\ufffd\x08\x00\x00\x00\x00\x00\x00\x03\ufffd]o\u06f8\x12\ufffd\ufffd\ufffd+\ufffd]...
>>> r.content
b'\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xed\x9d]o\xdb\xb8\x12\x86\xef\xfb+\x88]\x14h...
我已经尝试了很多 get/post 的组合,以及我可以从文档、SO 和其他示例中猜到的每种语法。我不明白我在上面看到的是什么,没能把它变成任何我能读懂的东西,也不知道如何得到我真正想要的东西。我的问题是,如何获取上述页面的 html?
原文由 Rich Thompson 发布,翻译遵循 CC BY-SA 4.0 许可协议
有问题的服务器给你一个 _gzipped 响应_。服务器也 _很坏_;它发送以下标头:
<!DOCTYPE..>
行 没有有效的 HTTP 标头。因此, 忽略Server
之后的剩余标头。为什么服务器会插入尚不清楚;在所有可能的引擎盖中WRCCWrappers.py
是一个 CGI 脚本,它不输出标题,但在 doctype 行之后包含一个双换行符,欺骗 Apache 服务器在那里插入额外的标题。因此,
requests
也没有检测到数据是 gzip 编码的。数据都在那里,你只需要解码它。或者你可以,如果它不是相当不完整的话。解决方法是告诉服务器不要打扰压缩:
并返回未压缩的响应。
顺便说一句,在 Python 2 上,HTTP 标头解析器不是那么严格,并且设法将 doctype 声明为标头:
而
content-encoding
信息仍然存在,所以requests
为您解码内容,正如预期的那样。