Urllib2 Ошибка HTTP 400: неверный запрос
У меня есть такой код, как этот
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
Может ли кто-нибудь указать, что я делаю неправильно?
Спасибо заранее.
Ответы
Ответ 1
Причина, по которой "собака" возвращает ошибку 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})
Ответ 2
Вам нужно использовать 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
вам нужно использовать urllib.quote
Ответ 4
Вот пример того, как использовать объект urllib.request в Python 3.6 и выше.
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)
Ответ 5
Я также столкнулся с той же проблемой. Оказывается, проблема заключалась в том, что метод был установлен неправильно. Когда вы включаете 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 на соответствующий требуемый метод.