【发布时间】:2022-05-12 17:52:42
【问题描述】:
我在尝试通过 API 访问“EDQM 标准术语”字典时偶然发现了一个错误——这是欧盟使用的各种药物配方的字典,我想使用 Python 脚本来获取数据以进行进一步处理。 EDQM 发布的 API 文档真的很稀缺: Standard Terms API documentation
我尝试访问 API 文档中列出的端点之一 - 即语言列表 - 无论我尝试什么,我都会收到 403 FORBIDDEN 错误作为回复。我直接从 Python 以及 Postman 中检查了这一点,结果是一样的。我仔细检查了,我使用了正确的 API 密钥,并且我的 EDQM 帐户的 Web 服务处于活动状态。
我写了以下函数:
- assemble_string
def assemble_sig(verb: str, uri: str, timestamp: str):
string_to_sign = verb + "&" + uri + "&" + HOST + "&" + timestamp
return string_to_sign
此函数根据 URI、“GET”动词和当前时间/日期生成 API 文档中提到的签名。
- sign_string
def sign_string(key: str, msg: str):
signature = hmac.new(
key.encode(),
msg.encode(),
digestmod=hashlib.sha512,
).hexdigest()
signature_b64 = base64.b64encode(signature.encode())
signature_final = signature_b64.decode()
return signature_final[-22:]
此函数获取我的 API 密钥和组装字符串,对其进行编码并返回最后 22 个字符。
- api_header
def api_header(uri: str):
d = dt.datetime.now()
edqm_timestamp = format_date_time(d.timestamp())
api_signature = assemble_sig(HTTP_VERB, uri, edqm_timestamp)
signed_string = sign_string(API_KEY, api_signature)
api_hdr = {
"Date": edqm_timestamp,
"X-STAPI-KEY": f"{LOGIN}|{signed_string}",
}
return api_hdr
此函数使用前两个函数为 API 请求组装标头。 生成的标头如下所示:
{'Date': 'Sun, 06 Feb 2022 16:43:06 GMT', 'X-STAPI-KEY': 'mylogin|FhYzRiMTllNjhlNzQ0MWI='}
其中 mylogin 替换为我的真实登录名。
API 请求的完整代码:
edqm_req_url = f"{HOST}{URI['languages']}"
edqm_req_header = api_header(URI["languages"])
edqm_session = requests.Session()
edqm_req = edqm_session.get(
edqm_req_url,
headers=edqm_req_header,
)
print(edqm_req.raise_for_status())
我已经尝试了以下方法:
- sign_string 函数中的不同编码 - 当 encode() 或 decode() 与 UTF-8 或 ASCII 编码参数一起使用时,我得到 400 错误请求;
- 使用授权标头{"Authorization": "X-STAPI-KEY = mylogin|signed_string"},但我也收到了 400 BAD REQUEST。
我将非常感谢任何帮助让这个东西正常工作!
谢谢:-)
库巴
【问题讨论】:
-
嗨 jkosciel,如果我不信任文档或者我根本不知道自己做错了什么,我会尝试捕获应用程序或网站的网络流量已经实现了我正在尝试调用的 API 的端点,并将其与我正在尝试执行的请求进行比较。我不确定这是否真的对你有帮助,因为一个重要的要求是你知道这样的应用程序/网站......
-
嗨 PixelPixel,感谢您的评论! :-) 我已经尝试使用 browsershark 分析 EDQM 网站上的一些流量,但这并没有帮助。这是一个非常小众的数据库,许多其他网站/应用程序都没有使用它。我还联系了 EDQM 的帮助台,他们提出的解决方案也不起作用……
标签: python postman http-status-code-403 api-key