Python连接关联Teams的私人SharePoint下载文件遇认证问题求助
尝试通过Python自动化下载关联Teams专业版群组的私人SharePoint站点中的全部文件,但每次调试脚本都会出现相同错误,怀疑是认证问题。参考GitHub示例编写的脚本无法实现需求,脚本如下:
import os from shareplum import Site from shareplum import Office365 from shareplum.site import Version class SPInterface: """This is a class to interact with Sharepoint from Python""" def __init__(self, sharepoint_base_url, username, password): self.username = username self.password = password self.sharepoint_base_url = sharepoint_base_url self.authcookie = Office365( sharepoint_base_url, username=username, password=password ).GetCookies() def download_file_sharepoint( self, source_path, sink_path, filename, sharepoint_site ): site = Site(sharepoint_site, version=Version.v2016, authcookie=self.authcookie) full_source_path = os.path.join(source_path, filename) full_sink_path = os.path.join(sink_path, filename) print(full_source_path) print(full_sink_path) folder = site.Folder(source_path) for attempt in range(0, 3): try: output_file = open(full_sink_path, "wb") input_file = folder.get_file(filename) binary_format = bytearray(input_file) output_file.write(binary_format) output_file.close() print("Attempt #No: ", attempt) print( "Downloaded file size is ", round(os.path.getsize(full_sink_path) / 1024, 2), " KB", ) except Exception as e: if attempt < 2: print("Try again!") continue print("Error", e) raise e break def main(): # stars anonymize private datas sharepoint_base_url = r'https://*.sharepoint.com/' username = "*" password = "*" source_path = 'sites/*/Shared%20Documents/' sharepoint_site = r'https://*.sharepoint.com/sites/*/' sink_path = r'C:/Users/*' sp = SPInterface(sharepoint_base_url, username, password) sp.download_file_sharepoint(source_path, sink_path, sharepoint_site) if __name__ == "__main__": main()
脚本中的核心问题
参数不匹配错误
main函数调用download_file_sharepoint时,参数顺序与函数定义不符:函数需要source_path, sink_path, filename, sharepoint_site四个参数,但调用时仅传入三个,直接触发参数数量错误。路径格式错误
source_path中的Shared%20Documents是URL编码格式,shareplum的Folder方法需要传入实际文件夹名称(即Shared Documents),而非编码后的字符串,否则会无法识别目标文件夹。认证方式局限性
私人/Teams关联的SharePoint站点普遍启用现代认证(如MFA),shareplum原生的用户名密码认证不支持MFA场景,这是你遇到认证错误的核心原因。缺少批量下载逻辑
当前脚本仅支持单个文件下载,没有遍历文件夹及子文件夹、批量下载全部文件的逻辑,不符合你的需求。
修复方案
1. 改用应用权限认证(支持MFA场景)
在Azure AD中注册应用,获取以下信息:
- 租户ID(Tenant ID)
- 客户端ID(Client ID)
- 客户端密钥(Client Secret)
为应用授予Sites.Read.All(或针对目标站点的Sites.Selected)权限,然后使用msal库获取访问令牌。
2. 修复脚本并添加批量下载逻辑
以下是修复后的完整脚本:
import os from shareplum import Site from shareplum.site import Version import msal class SPInterface: def __init__(self, tenant_id, client_id, client_secret, sharepoint_site_url): self.sharepoint_site_url = sharepoint_site_url # 使用MSAL获取应用级访问令牌 authority = f"https://login.microsoftonline.com/{tenant_id}" app = msal.ConfidentialClientApplication( client_id, authority=authority, client_credential=client_secret ) scope = ["https://*.sharepoint.com/.default"] result = app.acquire_token_for_client(scopes=scope) if "access_token" not in result: raise Exception(f"认证失败: {result.get('error_description')}") self.token = result['access_token'] # 通过令牌初始化站点对象 self.site = Site(sharepoint_site_url, version=Version.v2016, token=self.token) def download_folder(self, sp_folder_path, local_folder_path): # 创建本地文件夹(不存在则自动创建) os.makedirs(local_folder_path, exist_ok=True) # 获取SharePoint目标文件夹对象 sp_folder = self.site.Folder(sp_folder_path) # 下载当前文件夹内的所有文件 for file in sp_folder.files: file_name = file['Name'] local_file_path = os.path.join(local_folder_path, file_name) with open(local_file_path, "wb") as f: f.write(sp_folder.get_file(file_name)) print(f"已下载: {local_file_path}") # 递归处理子文件夹(跳过SharePoint系统文件夹Forms) for sub_folder in sp_folder.folders: sub_folder_name = sub_folder['Name'] if sub_folder_name == "Forms": continue sub_sp_path = f"{sp_folder_path}/{sub_folder_name}" sub_local_path = os.path.join(local_folder_path, sub_folder_name) self.download_folder(sub_sp_path, sub_local_path) def main(): # 替换为你的实际信息 tenant_id = "你的租户ID" client_id = "你的应用客户端ID" client_secret = "你的应用客户端密钥" sharepoint_site_url = "https://xxx.sharepoint.com/sites/你的站点名" sp_folder_path = "Shared Documents" # Teams关联站点的默认文档库路径 local_folder_path = r"C:/Users/xxx/下载/SharePoint文件" try: sp = SPInterface(tenant_id, client_id, client_secret, sharepoint_site_url) sp.download_folder(sp_folder_path, local_folder_path) print("全部文件下载完成") except Exception as e: print(f"错误: {e}") if __name__ == "__main__": main()
3. 关键说明
- 认证逻辑:使用MSAL库获取应用级令牌,绕过MFA限制,完美适配私人/Teams关联的SharePoint站点。
- 批量下载:递归遍历目标文件夹下的所有文件和子文件夹,自动同步本地目录结构。
- 路径处理:使用实际文件夹名称(如
Shared Documents)而非URL编码字符串,避免路径识别错误。
内容的提问来源于stack exchange,提问作者Grobln
相关产品推荐
相关产品推荐

