Python Requests: requests.exceptions.TooManyRedirects: 超过30次重定向

28 投票
3 回答
42852 浏览
提问于 2025-04-18 06:31

我在用python-requests库爬取这个页面。

import requests
from lxml import etree,html

url = 'http://www.amazon.in/b/ref=sa_menu_mobile_elec_all?ie=UTF8&node=976419031'
r = requests.get(url)
tree = etree.HTML(r.text)
print tree

但是我遇到了一个错误。(TooManyRedirects)我试着用allow_redirects这个参数,但还是出现了同样的错误。

r = requests.get(url, allow_redirects=True)

我甚至尝试在请求中发送一些头信息和数据,但我不确定这样做是否正确。

headers = {'content-type': 'text/html'}
payload = {'ie':'UTF8','node':'976419031'}
r = requests.post(url,data=payload,headers=headers,allow_redirects=True)

我该如何解决这个错误。我出于好奇还尝试了beautiful-soup4,结果得到了不同但类似的错误。

page = BeautifulSoup(urllib2.urlopen(url))

urllib2.HTTPError: HTTP Error 301: The HTTP server returned a redirect error that would lead to an infinite loop.
The last 30x error message was:
Moved Permanently

3 个回答

0

你需要把cookie的值复制到你的请求头里。我这边是可以正常工作的。

6

你可以通过明确指定数量来增加 max_redirect 的值,下面的例子就是这样做的:

session = requests.Session()
session.max_redirects = 60
session.get('http://www.amazon.com')
41

亚马逊正在将你的请求重定向到 http://www.amazon.in/b?ie=UTF8&node=976419031,然后这个链接又重定向到 http://www.amazon.in/electronics/b?ie=UTF8&node=976419031,接着你就进入了一个循环:

>>> loc = url
>>> seen = set()
>>> while True:
...     r = requests.get(loc, allow_redirects=False)
...     loc = r.headers['location']
...     if loc in seen: break
...     seen.add(loc)
...     print loc
... 
http://www.amazon.in/b?ie=UTF8&node=976419031
http://www.amazon.in/electronics/b?ie=UTF8&node=976419031
>>> loc
http://www.amazon.in/b?ie=UTF8&node=976419031

也就是说,你最开始的链接A重定向到一个新的链接B,链接B又重定向到链接C,链接C又重定向回链接B,等等。

显然,亚马逊是根据用户代理(User-Agent)这个信息来做这些重定向的,这时它会设置一个cookie,让后续的请求也能带上这个cookie。下面的方法可以解决这个问题:

>>> s = requests.Session()
>>> s.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'
>>> r = s.get(url)
>>> r
<Response [200]>

这个方法创建了一个会话(这样可以方便地重复使用,并且保持cookie有效),同时也复制了Chrome浏览器的用户代理字符串。这样请求就成功了(返回了200的响应)。

撰写回答