urllib.urlopen能用但是urllib2.urlopen不能用

11

我正在测试一个简单的网站,它在本地主机上运行,我可以在浏览器中访问它。主页只是一个单词“running”。

urllib.urlopen 可以成功读取该页面,但 urllib2.urlopen 却无法。以下是演示问题的脚本(这是实际脚本,而不是其他测试脚本的简化版本):

import urllib, urllib2
print urllib.urlopen("http://127.0.0.1").read()  # prints "running"
print urllib2.urlopen("http://127.0.0.1").read() # throws an exception

以下是堆栈跟踪信息:

Traceback (most recent call last):
  File "urltest.py", line 5, in <module>
    print urllib2.urlopen("http://127.0.0.1").read()
  File "C:\Python25\lib\urllib2.py", line 121, in urlopen
    return _opener.open(url, data)
  File "C:\Python25\lib\urllib2.py", line 380, in open
    response = meth(req, response)
  File "C:\Python25\lib\urllib2.py", line 491, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python25\lib\urllib2.py", line 412, in error
    result = self._call_chain(*args)
  File "C:\Python25\lib\urllib2.py", line 353, in _call_chain
    result = func(*args)
  File "C:\Python25\lib\urllib2.py", line 575, in http_error_302
    return self.parent.open(new)
  File "C:\Python25\lib\urllib2.py", line 380, in open
    response = meth(req, response)
  File "C:\Python25\lib\urllib2.py", line 491, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python25\lib\urllib2.py", line 418, in error
    return self._call_chain(*args)
  File "C:\Python25\lib\urllib2.py", line 353, in _call_chain
    result = func(*args)
  File "C:\Python25\lib\urllib2.py", line 499, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 504: Gateway Timeout

有什么想法吗?我可能最终需要使用urllib2的更高级功能,所以不想只是使用urllib,而且我想理解这个问题。

4个回答

16

看起来你已经定义了代理设置,urllib2正在使用这些设置。当它试图代理 "127.0.0.1/" 时,代理会放弃并返回一个504错误。

来自Obscure python urllib2 proxy gotcha

proxy_support = urllib2.ProxyHandler({})
opener = urllib2.build_opener(proxy_support)
print opener.open("http://127.0.0.1").read()

# Optional - makes this opener default for urlopen etc.
urllib2.install_opener(opener)
print urllib2.urlopen("http://127.0.0.1").read()

这解决了问题,虽然我不知道它为什么会想到使用代理,因为我的脚本只有三行,而且我没有任何环境变量表明任何代理的存在。不过,问题解决了还是很好的,所以感谢您的帮助。 - Eli Courtwright
OpenerDirector实例没有'urlopen'属性 - 您需要将上面的片段更改为opener.open(...)。 - ryan

1

先调用urlib2.open,然后是urllib.open,结果会相同吗?我只是想知道第一次调用open是否会导致http服务器忙碌,从而导致超时。


不,无论urllib2是否首先调用,它都会出现错误,而即使多次调用urllib也永远不会出现错误。不过想法很好。 - Eli Courtwright

1

我不知道发生了什么事,但你可能会发现这对你解决问题有所帮助:

>>> import urllib2
>>> urllib2.urlopen('http://mit.edu').read()[:10]
'<!DOCTYPE '
>>> urllib2._opener.handlers[1].set_http_debuglevel(100)
>>> urllib2.urlopen('http://mit.edu').read()[:10]
connect: (mit.edu, 80)
send: 'GET / HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: mit.edu\r\nConnection: close\r\nUser-Agent: Python-urllib/2.5\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Tue, 14 Oct 2008 15:52:03 GMT
header: Server: MIT Web Server Apache/1.3.26 Mark/1.5 (Unix) mod_ssl/2.8.9 OpenSSL/0.9.7c
header: Last-Modified: Tue, 14 Oct 2008 04:02:15 GMT
header: ETag: "71d3f96-2895-48f419c7"
header: Accept-Ranges: bytes
header: Content-Length: 10389
header: Connection: close
header: Content-Type: text/html
'<!DOCTYPE '

1

urllib.urlopen()函数向服务器发送以下请求:

GET / HTTP/1.0
Host: 127.0.0.1
User-Agent: Python-urllib/1.17

当使用urllib2.urlopen()时,会抛出以下异常:

GET / HTTP/1.1
Accept-Encoding: identity
Host: 127.0.0.1
Connection: close
User-Agent: Python-urllib/2.5

所以,你的服务器要么不理解HTTP/1.1协议,要么无法处理额外的头部字段。


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