urllib2 Ошибка HTTP 400: неверный запрос - PullRequest
19 голосов
/ 12 января 2012

У меня есть фрагмент кода, подобный этому

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

Кто-нибудь может указать, что я делаю не так?Заранее спасибо.

Ответы [ 4 ]

59 голосов
/ 12 января 2012

Причина, по которой «собака» возвращает ошибку 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)

Это будет работать.

Однако я настоятельно рекомендую использовать запросы вместо использования urllib / urllib2 /HTTPLIB.Это намного проще и будет обрабатывать все это для вас.

Это тот же код с запросами Python:

import requests

results = requests.get("http://www.bing.com/search", 
              params={'q': query, 'first': page}, 
              headers={'User-Agent': user_agent})
5 голосов
/ 12 января 2012

Вам нужно использовать urllib.quote() в вашей переменной 'query':

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

Это делает необходимый URL экранирования для преобразования пробела в big dog в big%20dog.

3 голосов
/ 12 января 2012

вы должны использовать urllib.quote

0 голосов
/ 22 августа 2015

Я также столкнулся с той же проблемой. Оказывается, проблема заключалась в том, что метод был установлен неправильно. Когда вы включаете urlencoded данные в urllib2.urlopen (), метод должен быть установлен в 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

Это установит ваш метод запроса URL на соответствующий требуемый метод

...