urllib2 HTTP错误400:错误请求

时间:2012-01-12 18:27:40

标签: python urllib2 http-error

我有一段像这样的代码

host = 'http://www.bing.com/search?q=%s&go=&qs=n&sk=&sc=8-13&first=%s' % (query, page)
req = urllib2.Request(host)
req.add_header('User-Agent', User_Agent)
response = urllib2.urlopen(req)

当我输入大于一个单词的查询时,如“狗”,我得到以下错误。

response = urllib2.urlopen(req)
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 400, in open
response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 513, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 438, in error
return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 372, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 521, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: Bad Request

谁能指出我做错了什么? 提前谢谢。

5 个答案:

答案 0 :(得分:59)

“狗”返回400错误的原因是因为您没有转义URL的字符串。

如果你这样做:

import urllib, urllib2

quoted_query = urllib.quote(query)
host = 'http://www.bing.com/search?q=%s&go=&qs=n&sk=&sc=8-13&first=%s' % (quoted_query, page)
req = urllib2.Request(host)
req.add_header('User-Agent', User_Agent)
response = urllib2.urlopen(req)

它会起作用。

但我强烈建议您使用requests而不是使用urllib / urllib2 / httplib。它更容易,它将为您处理所有这些。

这与python请求的代码相同:

import requests

results = requests.get("http://www.bing.com/search", 
              params={'q': query, 'first': page}, 
              headers={'User-Agent': user_agent})

答案 1 :(得分:5)

您需要在'query'变量上使用urllib.quote()

query = urllib.quote(query)
host = 'http://www.bing.com/search?q=%s&go=&qs=n&sk=&sc=8-13&first=%s' % (query, page)

这会将必要的网址转义为将big dog中的空格转换为big%20dog

答案 2 :(得分:3)

你必须使用urllib.quote

答案 3 :(得分:1)

以下是在Python 3.6及更高版本中如何使用urllib.request对象的示例。

import urllib.request
import json
from pprint import pprint

url = "some_url"

values = {
    "first_name": "Vlad",
    "last_name": "Bezden",
    "urls": [
        "https://twitter.com/VladBezden",
        "https://github.com/vlad-bezden",
    ],
}


headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
}

data = json.dumps(values).encode("utf-8")
pprint(data)

try:
    req = urllib.request.Request(url, data, headers)
    with urllib.request.urlopen(req) as f:
        res = f.read()
    pprint(res.decode())
except Exception as e:
    pprint(e)

答案 4 :(得分:0)

我也遇到了同样的问题。原来问题是方法设置不当。当你在urllib2.urlopen()中包含urlencoded数据时,该方法应该设置为POST,当你排除它时,方法应该是GET。那么,如何设置方法如下:

对于POST请求

request_object = urllib2.Request(url)
method = ("POST", "GET")
request_object.get_method = lambda: method[0] #If method is set to POST
url_handle = opener.open(req, data) #If method is set to POST

对于GET请求

request_object = urllib2.Request(url)
method = ("POST", "GET")
request_object.get_method = lambda: method[1] #If method is set to GET
url_handle = opener.open(req) #If method is set to GET

这会将您的网址请求方法设置为相应的必需方法