调用Office365 SharePoint REST API下载Excel文件报404错误
鉴权环节能正常拿到站点标题,说明身份认证逻辑完全没问题,404报错基本都是路径传参不对或者配置不匹配导致的,按以下顺序排查就行:
- 先把手动加的URL编码去掉
get_file_by_server_relative_path方法本身自带路径编码逻辑,你代码里提前把空格转成%20会触发二次编码,接口实际请求的路径会变成Shared%2520Documents,肯定找不到文件。直接把路径里所有%20换回原始空格就好,正确的路径格式是/sites/XXXXXXXX/Shared Documents/General/Testing_data/train_data.xlsx。 - 别自己手动拼文件路径,先通过接口枚举拿到准确路径
手动拼路径很容易因为站点托管路径配置、文档库重命名、文件夹层级数错出问题,可以先跑下面这段代码,把目标文件夹下的所有文件列出来,直接拿接口返回的标准路径去下载:
打印出来的folder_relative_path = "/sites/XXXXXXXX/Shared Documents/General/Testing_data" target_folder = ctx.web.get_folder_by_server_relative_path(folder_relative_path) ctx.load(target_folder.files) ctx.execute_query() for file in target_folder.files: print(f"文件名称:{file.name},服务器相对路径:{file.serverRelativeUrl}")serverRelativeUrl就是接口认的标准路径,直接传给下载方法就行,不用改。 - 核对几个基础配置,排除低级错误
- 先在浏览器里用同权限账号打开你拼的文件地址,确认文件没被删、没被移动、没改名
- 别搞混两个下载方法的传参规则:
get_file_by_server_relative_path要传没编码的原始路径,get_file_by_server_relative_url要传编码后的URL路径,传错了就会404 - 如果目标文件夹或者文件单独断了权限继承,就算你有整个站点的读取权限也可能返回404,得单独给服务主体开对应文档库的读取权限
修复后可直接跑的代码
import pathlib from office365.sharepoint.client_context import ClientContext from office365.runtime.auth.authentication_context import AuthenticationContext app_principal = { 'site_url' : 'https://XXXXXXX.sharepoint.com/sites/XXXXXX', 'client_id' : 'XXXXXXXX', 'client_secret' : 'XXXXXXXX', } ctx_auth = AuthenticationContext(app_principal['site_url']) ctx_auth.acquire_token_for_app(client_id=app_principal['client_id'], client_secret=app_principal['client_secret']) ctx = ClientContext(app_principal['site_url'], ctx_auth) web = ctx.web ctx.load(web) ctx.execute_query() print('Authenticated into sharepoint as: ',web.properties['Title']) # 注意:这里传带空格的原始路径,别手动做URL编码 file_url = "/sites/XXXXXXXX/Shared Documents/General/Testing_data/train_data.xlsx" download_path = pathlib.Path().resolve() / "download_file.xlsx" with open(download_path, "wb") as local_file: file = ctx.web.get_file_by_server_relative_path(file_url).download(local_file).execute_query() print("[Ok] file has been downloaded into: {0}".format(download_path))
内容的提问来源于stack exchange,提问作者matt.aurelio
相关产品推荐
相关产品推荐

