我有这个简单的URL,我想从我的python脚本调用: http://test.my-site.com/bla-blah/createAccount (由于隐私,我更改了一些字母,所有特殊字符等完全相同)
import urllib2
def myfunc(self, url):
result = urllib2.urlopen(url).read()
# HTTP Error 400: Bad Request
当我调用上述网址时,收到错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 406, in open
response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 519, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 444, in error
return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 527, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request
我不认为它与引号(和/或空白显然)有关。 当我调用URL http://test.my-site.com/bla-blah/listAccounts时,它工作正常,结果是我在浏览器中调用URL时得到的完全相同的文本。当然我通过浏览器检查了第一个URL,它运行正常。
知道这可能是什么吗?
修改以澄清:
这两个URL应该是可调用的,没有任何其他参数或查询字符串,就像他们站在上面一样。然后该网站应显示类似&#34;错误:参数缺失&#34;。当我在浏览器中调用URL或通过bash中的curl调用时,会发生这种情况。只是python模块正在制造问题。
Edit2 (也更改为发布标题以更好地匹配情况)
谢谢,你是对的:如果我做curl -v 'http://test.my-site.com/bla-blah/createAccount'
,我会得到以下内容:
* About to connect() to <blackened> port 80 (#0)
* Trying 193.46.215.110... connected
> GET <blackened> HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: <blackened>
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< content-language: en-US
< server: <blackened>
< date: Thu, 04 Dec 2014 07:20:15 GMT
< set-cookie: beng_proxy_session=e2e037e7e79c1b03; HttpOnly; Path=/; Version=1; Discard
< p3p: CP="CAO PSA OUR"
< content-length: 234
<
error: parameter x missing
error: parameter y missing
* Connection #0 to host <blackened> left intact
* Closing connection #0
如您所见,存在HTTP标头错误。但curl(和浏览器)继续打印site-body(&#34;参数缺失...&#34;),但python urllib在看到标题错误后停止并且不打印正文。 (我猜是头错误btw是由服务器应用程序发送的。所以这与python urllib无关) 所以我们距离更近了一步,但即使出现错误,我仍然需要看到身体,因为我必须知道(并显示)到底出了什么问题。 但刚才我找到了解决方案:
try:
response = urllib2.urlopen("http://test.my-site.com/bla-blah/createAccount")
contents = response.read()
print("success: %s" % contents)
except urllib2.HTTPError as e:
contents = e.read()
print("error: %s" % contents)
这样我就可以获得网站的正文,无论是错误还是成功。
(顺便说一下,这是我得到解决方案的帖子:Overriding urllib2.HTTPError or urllib.error.HTTPError and reading response HTML anyway)
非常感谢!
答案 0 :(得分:1)
修改2
Python在收到状态代码为400的HTTP响应时引发异常。响应正文中可能存在一些您没有看到的文本,因为存在异常并且未读取数据。该文本可能是“错误:参数缺失”。
可能curl正在做同样的事情,然而,它显示响应的主体,而不是适合,所以你看到“错误:参数缺失”。与您的浏览器类似的行为。
尝试运行curl -v http://test.my-site.com/bla-blah/createAccount
。这将以详细模式运行curl,您将能够看到响应并检查是否返回状态代码400。如果它是状态码400,则urllib2.urlopen()
没有任何问题,您只需要在查询字符串中发送参数。
修改1
以下是curl请求和urllib2.urlopen请求之间的区别......
[mhawke@localhost ~]$ python
GET /bla-blah/createAccount HTTP/1.1
Accept-Encoding: identity
Host: localhost:12345
Connection: close
User-Agent: Python-urllib/2.7
[mhawke@localhost ~]$ nc -l localhost 12345
GET /bla-blah/createAccount HTTP/1.1
User-Agent: curl/7.32.0
Host: localhost:12345
Accept: */*
也许您可以尝试在Python中添加/删除标头以实现curl生成的相同请求。
原始回答
网址http://test.my-site.com/bla-blah/listAccounts
看起来像是HTTP GET请求,而http://test.my-site.com/bla-blah/createAccount
可能需要HTTP POST请求,其中包含“创建帐户”所需的数据字段。
我不知道您的服务器应用程序需要什么数据,但(如果我的猜测是正确的)这通常是您需要考虑的事情:
import urllib2
from urllib import urlencode
data = {'username': 'droids', 'password': '123droids321', 'phone': '012351234'}
result = urllib2.urlopen(url, urlencode(data)).read()
urlencoded数据的存在会生成POST请求,而不是您当前代码将发出的GET请求。
请注意,HTTP有一个更可用的模块:requests。看看吧。