为什么我能够在 python 3 urllib.request 中读取 HEAD http 请求?
Why am I able to read a HEAD http request in python 3 urllib.request?
我想发出没有任何内容数据的 HEAD 请求以节省带宽。我正在使用 urllib.request
。但是,经过测试,似乎HEAD请求也获取了数据?怎么回事?
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:16:31) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib.request
>>> req = urllib.request.Request("http://www.google.com", method="HEAD")
>>> resp = urllib.request.urlopen(req)
>>> a = resp.read()
>>> len(a)
24088
http://www.google.com
URL重定向:
$ curl -D - -X HEAD http://www.google.com
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.co.uk/?gfe_rd=cr&ei=A8sXVZLOGvHH8ge1jYKwDQ
Content-Length: 261
Date: Sun, 29 Mar 2015 09:50:59 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0.5
和 urllib.request
已遵循重定向,向该新位置发出 GET 请求:
>>> import urllib.request
>>> req = urllib.request.Request("http://www.google.com", method="HEAD")
>>> resp = urllib.request.urlopen(req)
>>> resp.url
'http://www.google.co.uk/?gfe_rd=cr&ei=ucoXVdfaJOTH8gf-voKwBw'
您必须构建自己的处理程序堆栈来防止这种情况; HTTPRedirectHandler
不够智能,无法在发出 HEAD
方法操作时处理重定向。将 Alan Duan 的示例从 How do I prevent Python's urllib(2) from following a redirect 改编为 Python 3 将得到:
import urllib.request
class NoRedirection(urllib.request.HTTPErrorProcessor):
def http_response(self, request, response):
return response
https_response = http_response
opener = urllib.request.build_opener(NoRedirection)
req = urllib.request.Request("http://www.google.com", method="HEAD")
resp = opener.open(req)
你最好使用 requests
library;它在使用 requests.head()
或 requests.Session().head()
可调用对象时显式设置 allow_redirects=False
,因此您 可以 看到原始结果:
>>> import requests
>>> requests.head('http://www.google.com')
<Response [302]>
>>> _.headers['Location']
'http://www.google.co.uk/?gfe_rd=cr&ei=FcwXVbepMvHH8ge1jYKwDQ'
即使启用了重定向,response.history
列表也可以让您访问中间请求,并且 requests
也使用正确的方法进行重定向调用:
>>> response = requests.head('http://www.google.com', allow_redirects=True)
>>> response.url
'http://www.google.co.uk/?gfe_rd=cr&ei=8e0XVYfGMubH8gfJnoKoDQ'
>>> response.history
[<Response [302]>]
>>> response.history[0].url
'http://www.google.com/'
>>> response.request.method
'HEAD'
我想发出没有任何内容数据的 HEAD 请求以节省带宽。我正在使用 urllib.request
。但是,经过测试,似乎HEAD请求也获取了数据?怎么回事?
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:16:31) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib.request
>>> req = urllib.request.Request("http://www.google.com", method="HEAD")
>>> resp = urllib.request.urlopen(req)
>>> a = resp.read()
>>> len(a)
24088
http://www.google.com
URL重定向:
$ curl -D - -X HEAD http://www.google.com
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.co.uk/?gfe_rd=cr&ei=A8sXVZLOGvHH8ge1jYKwDQ
Content-Length: 261
Date: Sun, 29 Mar 2015 09:50:59 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0.5
和 urllib.request
已遵循重定向,向该新位置发出 GET 请求:
>>> import urllib.request
>>> req = urllib.request.Request("http://www.google.com", method="HEAD")
>>> resp = urllib.request.urlopen(req)
>>> resp.url
'http://www.google.co.uk/?gfe_rd=cr&ei=ucoXVdfaJOTH8gf-voKwBw'
您必须构建自己的处理程序堆栈来防止这种情况; HTTPRedirectHandler
不够智能,无法在发出 HEAD
方法操作时处理重定向。将 Alan Duan 的示例从 How do I prevent Python's urllib(2) from following a redirect 改编为 Python 3 将得到:
import urllib.request
class NoRedirection(urllib.request.HTTPErrorProcessor):
def http_response(self, request, response):
return response
https_response = http_response
opener = urllib.request.build_opener(NoRedirection)
req = urllib.request.Request("http://www.google.com", method="HEAD")
resp = opener.open(req)
你最好使用 requests
library;它在使用 requests.head()
或 requests.Session().head()
可调用对象时显式设置 allow_redirects=False
,因此您 可以 看到原始结果:
>>> import requests
>>> requests.head('http://www.google.com')
<Response [302]>
>>> _.headers['Location']
'http://www.google.co.uk/?gfe_rd=cr&ei=FcwXVbepMvHH8ge1jYKwDQ'
即使启用了重定向,response.history
列表也可以让您访问中间请求,并且 requests
也使用正确的方法进行重定向调用:
>>> response = requests.head('http://www.google.com', allow_redirects=True)
>>> response.url
'http://www.google.co.uk/?gfe_rd=cr&ei=8e0XVYfGMubH8gfJnoKoDQ'
>>> response.history
[<Response [302]>]
>>> response.history[0].url
'http://www.google.com/'
>>> response.request.method
'HEAD'