Python调用Office365 API读取OneDrive txt文件报400错误咨询
报错根因
两次HTTP 400错误核心是传入File.open_binary方法的服务器相对路径不符合OneDrive for Business的站点路径规则:
- 第一次传
Documents/textfile.txt没有以/开头,不符合接口对服务器相对路径的基础格式要求,直接触发参数非法错误 - 第二次修改为
/Documents/textfile.txt依旧报错,是因为OneDrive个人站点的SPWeb服务根路径不是域名根,而是站点地址中/personal/<邮箱编码>/这一段,你传入的路径相当于从域名根目录查找文件,完全匹配不到站点下的资源,因此触发"服务器相对URL必须以SPWeb.ServerRelativeUrl开头"的错误。
你之前读取普通SharePoint站点文件能正常运行,是因为传入的file_url前缀/sites/sitename/刚好和对应站点的SPWeb根路径匹配;读取OneDrive内Excel文件未报错,大概率是使用了基于DriveItem ID的接口或OneDrive专用SDK,没有走SharePoint文件的相对路径读取逻辑,因此没有触发该问题。
正确实现代码
只需要补全OneDrive文件的完整服务器相对路径即可,同时修正原有代码里的两处细节问题:一是ClientContext初始化第一个参数固定传站点根地址,不要传文件路径;二是读取文本内容不要用字符串替换的方式处理字节流,直接指定编码解码避免乱码。
from office365.runtime.auth.authentication_context import AuthenticationContext from office365.sharepoint.client_context import ClientContext from office365.sharepoint.files.file import File username, password = "<username>", "<password>" # 保持原有OneDrive个人站点地址不变 site_url = 'https://<company>-my.sharepoint.com/personal/<email_id>/' # 关键:补全全量服务器相对路径,前缀和site_url中的personal路径完全一致 # 注意OneDrive个人文档库的内部路径是Documents,不要写成SharePoint站点用的Shared Documents file_url = '/personal/<email_id>/Documents/textfile.txt' ctx_auth = AuthenticationContext(site_url) if ctx_auth.acquire_token_for_user(username, password): ctx = ClientContext(site_url, ctx_auth) response = File.open_binary(ctx, file_url) response.raise_for_status() # 接口请求失败时直接抛出异常,方便排查问题 # 按文件实际编码解码即可,不要用str替换字节标识的写法,避免内容损坏 file_content = response.content.decode('utf-8') print(response) print(file_content)
注意事项
- 路径中的
<email_id>直接从你自己的site_url里复制即可,一般是邮箱地址把@和.替换成_的格式,比如zhangsan@company.com对应zhangsan_company_com,不要手动拼写避免出错 - 如果文件存放在OneDrive的子文件夹里,直接在路径后追加子文件夹路径即可,比如文件在
Documents/工作记录/2024/log.txt,对应file_url就是/personal/<email_id>/Documents/工作记录/2024/log.txt - 你之前能正常读取SharePoint文件的代码中
ClientContext(file_url, ctx_auth)属于写法不规范,只是因为路径匹配刚好没有触发问题,所有场景下ClientContext第一个参数都应该传站点根地址。
内容的提问来源于stack exchange,提问作者Kartik
相关产品推荐
相关产品推荐

