将 Requests 中的 POST 请求替换为 urrlib 导致 404 错误
Replace POST request from Requests to urrlib cause 404 Error
我有一个用 requests
开门的密码
from requests import post as req_post
HEADER = {"Authorization": Bearer 097....} # some private number
ACCESS_LINK= https://api.akerun.com/v5/organizations/.../jobs/unlock # some private link
x = req_post(ACCESS_LINK, headers=HEADER)
print(x.header)
会开门并用一些私人数据回复这样的东西
{'Date': 'Tue, 06 Oct 2020 01:14:15 GMT', 'Content-Type': 'application/json', 'Content-Length': '23', 'Connection': 'keep-alive', 'Server': 'nginx', 'Strict-Transport-Security': 'max-age=31536000', 'ETag': ... Cache-Control': 'max-age=0, private, must-revalidate', 'Set-Cookie': ..., 'X-Runtime': '0.185443'}
所以当我像这样对 urllib
做同样的事情时
a = "https://api.akerun.com/v5/organizations/.../jobs/unlock"
b = {"Authorization": "Bearer 097..."}
from urllib import request, parse
req = request.Request(a, headers=b)
resp = request.urlopen(req)
它抛出一个错误
Traceback (most recent call last):
File "/home/suomi/kaoiro/kaoiro/test.py", line 10, in <module>
resp = request.urlopen(req)
File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.8/urllib/request.py", line 531, in open
response = meth(req, response)
File "/usr/lib/python3.8/urllib/request.py", line 640, in http_response
response = self.parent.error(
File "/usr/lib/python3.8/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
result = func(*args)
File "/usr/lib/python3.8/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
为什么? requests
请求与 urllib
请求不同吗?
最有可能的问题是 urllib
执行的是 GET 而不是你的情况下的 POST 请求。
来自docs:
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
...
method should be a string that indicates the HTTP request method that will be used (e.g. 'HEAD'
). If provided, its value is stored in the method
attribute and is used by get_method()
. The default is 'GET'
if data is None
or 'POST'
otherwise. Subclasses may indicate a different default method by setting the method
attribute in the class itself.
所以使用
req = request.Request(a, headers=b, method='POST')
应该可以。
我有一个用 requests
开门的密码
from requests import post as req_post
HEADER = {"Authorization": Bearer 097....} # some private number
ACCESS_LINK= https://api.akerun.com/v5/organizations/.../jobs/unlock # some private link
x = req_post(ACCESS_LINK, headers=HEADER)
print(x.header)
会开门并用一些私人数据回复这样的东西
{'Date': 'Tue, 06 Oct 2020 01:14:15 GMT', 'Content-Type': 'application/json', 'Content-Length': '23', 'Connection': 'keep-alive', 'Server': 'nginx', 'Strict-Transport-Security': 'max-age=31536000', 'ETag': ... Cache-Control': 'max-age=0, private, must-revalidate', 'Set-Cookie': ..., 'X-Runtime': '0.185443'}
所以当我像这样对 urllib
做同样的事情时
a = "https://api.akerun.com/v5/organizations/.../jobs/unlock"
b = {"Authorization": "Bearer 097..."}
from urllib import request, parse
req = request.Request(a, headers=b)
resp = request.urlopen(req)
它抛出一个错误
Traceback (most recent call last):
File "/home/suomi/kaoiro/kaoiro/test.py", line 10, in <module>
resp = request.urlopen(req)
File "/usr/lib/python3.8/urllib/request.py", line 222, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python3.8/urllib/request.py", line 531, in open
response = meth(req, response)
File "/usr/lib/python3.8/urllib/request.py", line 640, in http_response
response = self.parent.error(
File "/usr/lib/python3.8/urllib/request.py", line 569, in error
return self._call_chain(*args)
File "/usr/lib/python3.8/urllib/request.py", line 502, in _call_chain
result = func(*args)
File "/usr/lib/python3.8/urllib/request.py", line 649, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
为什么? requests
请求与 urllib
请求不同吗?
最有可能的问题是 urllib
执行的是 GET 而不是你的情况下的 POST 请求。
来自docs:
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
...
method should be a string that indicates the HTTP request method that will be used (e.g.
'HEAD'
). If provided, its value is stored in themethod
attribute and is used byget_method()
. The default is'GET'
if data isNone
or'POST'
otherwise. Subclasses may indicate a different default method by setting themethod
attribute in the class itself.
所以使用
req = request.Request(a, headers=b, method='POST')
应该可以。