Ric*_*son 21 html python python-requests
我正在尝试教自己一些基本的网络抓取.使用Python的请求模块,我能够获取各种网站的HTML,直到我尝试这个:
>>> r = requests.get('http://www.wrcc.dri.edu/WRCCWrappers.py?sodxtrmts+028815+por+por+pcpn+none+mave+5+01+F')
Run Code Online (Sandbox Code Playgroud)
而不是作为此页面源的基本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...
Run Code Online (Sandbox Code Playgroud)
我已经尝试了很多get/post的组合,我可以从文档和SO以及其他示例中猜出每种语法.我不明白我上面看到的是什么,无法把它变成我能读到的任何东西,也无法弄清楚如何得到我真正想要的东西.我的问题是,如何获取上述页面的html?
Mar*_*ers 18
有问题的服务器正在给你一个gzipped响应.服务器也非常破碎 ; 它发送以下标题:
$ curl -D - -o /dev/null -s -H 'Accept-Encoding: gzip, deflate' http://www.wrcc.dri.edu/WRCCWrappers.py?sodxtrmts+028815+por+por+pcpn+none+mave+5+01+F
HTTP/1.1 200 OK
Date: Tue, 06 Jan 2015 17:46:49 GMT
Server: Apache
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"><html xmlns="http: //www.w3.org/1999/xhtml" lang="en-US">
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 3659
Content-Type: text/html
Run Code Online (Sandbox Code Playgroud)
该<!DOCTYPE..>行没有有效的HTTP标头.因此,剩余的头过去Server被忽略.为什么服务器插入不清楚; 在所有可能的引擎盖WRCCWrappers.py是一个CGI脚本,它不输出标题,但在doctype行后包含一个双重换行符,重复Apache服务器插入其他标题.
因此,requests也没有检测到数据是gzip编码的.数据就在那里,您只需解码即可.或者你可以,如果它不是很不完整.
解决方法是告诉服务器不要打扰压缩:
headers = {'Accept-Encoding': 'identity'}
r = requests.get(url, headers=headers)
Run Code Online (Sandbox Code Playgroud)
并返回未压缩的响应.
顺便说一句,在Python 2上,HTTP头解析器不是那么严格,并设法将doctype声明为头:
>>> pprint(dict(r.headers))
{'<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "dtd/xhtml1-transitional.dtd"><html xmlns="http': '//www.w3.org/1999/xhtml" lang="en-US">',
'connection': 'Keep-Alive',
'content-encoding': 'gzip',
'content-length': '3659',
'content-type': 'text/html',
'date': 'Tue, 06 Jan 2015 17:42:06 GMT',
'keep-alive': 'timeout=5, max=100',
'server': 'Apache',
'vary': 'Accept-Encoding'}
Run Code Online (Sandbox Code Playgroud)
并且content-encoding信息仍然存在,因此requests可以按预期为您解码内容.
Aid*_*len 11
这是使用BeautifulSoup库的示例。它“使从网页上抓取信息变得容易”。
from bs4 import BeautifulSoup
import requests
# request web page
resp = requests.get("http://example.com")
# get the response text. in this case it is HTML
html = resp.text
# parse the HTML
soup = BeautifulSoup(html, "html.parser")
# print the HTML as text
print(soup.body.get_text().strip())
Run Code Online (Sandbox Code Playgroud)
和结果
Example Domain
This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.
More information...
Run Code Online (Sandbox Code Playgroud)
此 URL 的 HTTP 标头现已修复。
>>> import requests
>>> print requests.__version__
2.5.1
>>> r = requests.get('http://www.wrcc.dri.edu/WRCCWrappers.py?sodxtrmts+028815+por+por+pcpn+none+mave+5+01+F')
>>> r.text[:100]
u'\n<!DOCTYPE html>\n<HTML>\n<HEAD><TITLE>Monthly Average of Precipitation, Station id: 028815</TITLE></H'
>>> r.headers
{'content-length': '3672', 'content-encoding': 'gzip', 'vary': 'Accept-Encoding', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'connection': 'Keep-Alive', 'date': 'Thu, 12 Feb 2015 18:59:37 GMT', 'content-type': 'text/html; charset=utf-8'}
Run Code Online (Sandbox Code Playgroud)
我会用更简单的方式解决这个问题。只需导入html库即可解码 HTML 特殊字符:
import html
r = requests.get('http://www.wrcc.dri.edu/WRCCWrappers.py?sodxtrmts+028815+por+por+pcpn+none+mave+5+01+F')
print(html.unescape(r.text))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
66230 次 |
| 最近记录: |