使用Python的pyodata库访问自定义Odata数据源报错如何解决
pyodata连接企业内部OData数据源报错排查方案
- 验证元数据接口可用性
pyodata客户端初始化时会自动请求服务根路径下的$metadata元数据文件完成结构解析,该步骤出错是初始化失败的高频原因,可先运行以下代码验证接口返回:
import requests import urllib3 # 关闭自签证书告警,生产环境建议配置为内部CA证书路径 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) user_name = "替换为实际用户名" psw = "替换为实际密码" # 若服务根路径为/odata/,则元数据地址为https://batch.decisionkey.npd.com/odata/$metadata meta_url = "https://batch.decisionkey.npd.com/odata/dkusers/$metadata" resp = requests.get(meta_url, auth=(user_name, psw), verify=False) print(f"响应状态码:{resp.status_code}") print(f"响应前500字符:{resp.text[:500]}")
根据返回结果对应排查:
状态码401/403:认证方式不匹配,当前代码使用Basic Auth,需确认服务支持的认证方案(NTLM/OAuth2/SAML等),Excel连接时使用的认证逻辑和当前代码可能不一致
状态码404:服务根路径配置错误,
dkusers大概率是实体集名称而非服务根路径,可尝试将服务根路径改为https://batch.decisionkey.npd.com/odata/SSL证书报错:服务使用企业自签证书,可将
verify参数设置为内部CA证书的本地路径,而非直接关闭校验配置请求头适配安全策略
多数企业安全网关会拦截默认的requests请求头,可模拟Excel的请求特征配置:
session.headers.update({ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Excel/16.0.14326.20454", "Accept": "application/xml,application/json" })
- 处理CSRF强制校验
部分OData服务开启了全局CSRF校验,需先获取CSRF Token后再初始化客户端:
# 先请求服务根地址获取CSRF Token resp = session.get("https://batch.decisionkey.npd.com/odata/", headers={"X-CSRF-Token": "Fetch"}, verify=False) session.headers["X-CSRF-Token"] = resp.headers.get("X-CSRF-Token") # 再初始化pyodata客户端 theservice = pyodata.Client("https://batch.decisionkey.npd.com/odata/", session)
- 调整后完整测试代码
import requests import pyodata import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) user_name = "你的用户名" psw = "你的密码" url_root = "https://batch.decisionkey.npd.com/odata/" session = requests.Session() session.auth = (user_name, psw) session.verify = False session.headers.update({ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Excel/16.0.14326.20454", "Accept": "application/xml,application/json" }) # 拉取CSRF Token resp = session.get(url_root, headers={"X-CSRF-Token": "Fetch"}) if "X-CSRF-Token" in resp.headers: session.headers["X-CSRF-Token"] = resp.headers["X-CSRF-Token"] # 初始化客户端 theservice = pyodata.Client(url_root, session) # 测试拉取dkusers数据 for user in theservice.entity_sets.dkusers.get_entities().top(1).execute(): print(user) break
内容的提问来源于stack exchange,提问作者michael zeng
相关产品推荐
相关产品推荐

