有没有一个简单的方法来请求一个在 python 的 URL,而不遵循重定向?

看看 urllib2的源代码,似乎最简单的方法是子类化 HTTPRedirectHandler,然后使用 build _ opener 覆盖默认的 HTTPRedirectHandler,但这似乎需要很多(相对复杂的)工作来完成看起来应该很简单的事情。

102543 次浏览

Dive Into Python 有一个很好的章节介绍了如何使用 urllib2处理重定向。

>>> import httplib
>>> conn = httplib.HTTPConnection("www.bogosoft.com")
>>> conn.request("GET", "")
>>> r1 = conn.getresponse()
>>> print r1.status, r1.reason
301 Moved Permanently
>>> print r1.getheader('Location')
http://www.bogosoft.com/new/location

我第二个 olt 的指针指向 一头扎进巨蟒里。下面是一个使用 urllib2重定向处理程序的实现,比它应该做的工作更多吗?也许吧,耸耸肩。

import sys
import urllib2


class RedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_301(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_301(
self, req, fp, code, msg, headers)
result.status = code
raise Exception("Permanent Redirect: %s" % 301)


def http_error_302(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_302(
self, req, fp, code, msg, headers)
result.status = code
raise Exception("Temporary Redirect: %s" % 302)


def main(script_name, url):
opener = urllib2.build_opener(RedirectHandler)
urllib2.install_opener(opener)
print urllib2.urlopen(url).read()


if __name__ == "__main__":
main(*sys.argv)

我想这会有帮助

from httplib2 import Http
def get_html(uri,num_redirections=0): # put it as 0 for not to follow redirects
conn = Http()
return conn.request(uri,redirections=num_redirections)

这是一个不遵循重定向的 urllib2处理程序:

class NoRedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_302(self, req, fp, code, msg, headers):
infourl = urllib.addinfourl(fp, headers, req.get_full_url())
infourl.status = code
infourl.code = code
return infourl
http_error_300 = http_error_302
http_error_301 = http_error_302
http_error_303 = http_error_302
http_error_307 = http_error_302


opener = urllib2.build_opener(NoRedirectHandler())
urllib2.install_opener(opener)

然而,最短的方法是

class NoRedirect(urllib2.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, hdrs, newurl):
pass


noredir_opener = urllib2.build_opener(NoRedirect())

httplib2请求方法中的 redirections关键字是一条红鲱鱼。如果它接收到一个重定向状态代码,它将引发 RedirectLimit异常,而不是返回第一个请求。要返回初始响应,需要在 Http对象上将 follow_redirects设置为 False:

import httplib2
h = httplib2.Http()
h.follow_redirects = False
(response, body) = h.request("http://example.com")

以下是 请求的做法:

import requests
r = requests.get('http://github.com', allow_redirects=False)
print(r.status_code, r.headers['Location'])