为什么使用Python的urllib.urlopen会导致Google返回"302 Moved"的http状态?

3

在CentOS 6.4上使用Python 2.6.6

import urllib
#url = 'http://www.google.com.hk'    #ok
#url = 'http://clients1.google.com.hk'    #ok
#url = 'http://clients1.google.com.hk/complete/search'  #ok (blank)
url  = 'http://clients1.google.com.hk/complete/search?output=toolbar&hl=zh-CN&q=abc'  #fails
print url
page = urllib.urlopen(url).read()
print page

使用前三个URL,代码可以正常工作。但是对于第四个URL,Python会返回302错误:
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://clients1.google.com.hk/complete/search?output=toolbar&amp;hl=zh-CN&amp;q=abc">here</A>.
</BODY></HTML>

我的代码中的URL与它告诉我使用的URL相同:

My URL:  http://clients1.google.com.hk/complete/search?output=toolbar&hl=zh-CN&q=abc
Its URL: http://clients1.google.com.hk/complete/search?output=toolbar&hl=zh-CN&q=abc

Google说URL已移动,但URL都是相同的。有什么想法吗?

更新:所有的URL在浏览器中都可以正常工作。但在Python命令行中,第4个URL会返回302状态码。


该URL返回一个“200 OK”。 - Octopus
在你的浏览器或Python命令行中? - davidjhp
我从Python 2.7得到了302。 - marcadian
@davidjhp,是的,在浏览器中。这很奇怪。一定与头文件有关,而且不是用户代理(我试图模仿)。我猜可能与cookie有关。 - Octopus
4个回答

2
很可能与头文件和cookie有关。我在命令行上使用curl进行了快速测试,也得到了302转移。它提供的Location标题不同于文档中的标题。如果我跟随body URL,我会得到一个204响应(奇怪)。如果我跟随Location标题,最终会得到一个像你所说的循环响应。
或许重要的是Set-Cookie头文件。它可能会重定向直到设置适当的cookie。它也可能会扫描User-Agent并基于此执行某些操作。这些是将浏览器与requests或urlib等工具区分开来的重要方面。浏览器创建会话,存储cookie并发送不同的headers。

2

我不知道为什么urllib失败了(我得到了相同的响应),然而requests库完美地工作:

import requests
url = 'http://clients1.google.com.hk/complete/search?output=toolbar&hl=zh-CN&q=abc'    # fails
print (requests.get(url).text)

2

urllib忽略了cookie并发送不带cookie的新请求,因此在该URL上会导致重定向循环。为了解决这个问题,您可以使用更新的urllib2并添加cookie处理程序:

import urllib2
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
response = opener.open('http://clients1.google.com.hk/complete/search?output=toolbar&hl=zh-CN&q=abc')
print response.read()

0

如果你使用你最喜欢的网络调试器(比如我的 Fiddler),并在浏览器中打开该 URL,你会发现你也会得到初始的 302 响应。你的浏览器只是聪明到足以自动重定向你。所以你的代码返回了正确的响应。如果你想让你的代码自动重定向到新的 URL,那么你必须让你的代码变得足够聪明才行。


是的,但指定的重定向URL会导致无限循环。 - Octopus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接