Office365-rest-python-client: 如何下载包含多个文件的 SharePoint 文件夹?

创建于 2019-03-27  ·  15评论  ·  资料来源: vgrem/Office365-REST-Python-Client

我的 Python 3 代码:

从 office365.runtime.auth.authentication_context 导入 AuthenticationContext
从 office365.sharepoint.client_context 导入 ClientContext

url = ' https://company.sharepoint.com/sites/abc '
ctx_auth = AuthenticationContext(url=url)
如果 ctx_auth.acquire_token_for_user(username='[email protected]', password='12345'):
ctx = ClientContext(url, ctx_auth)
列表 = ctx.web.lists
ctx.load(列表)
ctx.execute_query()
对于列表中的 l:
打印(l.properties['Title'])

从上面的代码,我可以列出站点中的项目。 但我的计划是使用 Python 在 AWS Lambda 中运行整个模块,并从 SharePoint 文档下载并存储在 AWS S3 中。

一个文件夹可以有多个文件。 我想下载包含所有文件的整个文件夹。 有人这样做过吗? 有什么帮助吗? 工作代码将是一个很大的帮助,因为我对网络抓取完全陌生!

最有用的评论

不要感谢我, @vgrem是罪魁祸首:) ...我不确定,也许还有其他方法可以实现相同的目标....

对,要列出共享文档文档库中的所有文件夹,您可以尝试:

    list_object = ctx.web.lists.get_by_title(listTitle)
    folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()

    folders = folder.folders
    ctx.load(folders)
    ctx.execute_query()

    for myfolder in folders:
        print("File name: {0}".format(myfolder.properties["Name"]))

米。

所有15条评论

你好,
也许您可以循环执行,例如:

  1. 首先使用函数返回共享点文档库内容:

listTitle = "文档"
站点 = "abc"

def fncPrintLibraryContents(ctx, listTitle):

try:

    list_object = ctx.web.lists.get_by_title(listTitle)
    folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()

    files = folder.files
    ctx.load(files)
    ctx.execute_query()

    return files

except:

    print('Problem printing out library contents')   
    sys.exit(1)
  1. 然后通过调用 proc 下载每个文件,例如:

定义下载文件(ctx,文件名):

try:
    with open(fileName, "wb") as localFile:            
        relativeUrl = '/sites/{0}/Shared%20Documents/{1}'.format(site, fileName)
        response = File.open_binary(ctx, relativeUrl)
        localFile.write(response.content) 
        localFile.close()

except:

    print('Problem downloading file:', fileName)
    sys.exit(1)

myfiles = fncPrintLibraryContents(ctx, listTitle)

对于 myfiles 中的 myfile:
print("下载文件:{0}".format(myfile.properties["Name"]))
下载文件(ctx,` myfile.properties[“名称”])

米。

请在 for 循环中缩进最后两行,我似乎无法做到。
米。

嘿,

谢谢这么快的回复。 我能够成功下载文件,因为我必须给出文件名。 但是,为了能够递归下载所有文件,我需要首先列出特定文件夹中的所有现有文件,经过多次试验,出现 Not Found 错误。 也许我在某个地方出错了,因为我对标题的概念不正确,所以每当我试图通过将该名称作为标题来列出子文件夹时,我都会失败。 我会检查你的代码,看看我是否能够做到。

同时,我当前正在运行的代码(下载工作正常,列出根目录的文件夹和文件正在工作,但每当我在标题中给出除文档以外的任何特定文件夹名称时,它都会失败):

`从 office365.runtime.auth.authentication_context 导入 AuthenticationContext
从 office365.sharepoint.client_context 导入 ClientContext
从 office365.sharepoint.file 导入文件
从 office365.sharepoint.file_creation_information 导入 FileCreationInformation

def read_folder_and_files(context, list_title):
"""读取文件夹示例"""
list_obj = context.web.lists.get_by_title(list_title)
文件夹 = list_obj.root_folder
上下文加载(文件夹)
context.execute_query()
打印(“列表网址:{0}”.format(folder.properties[“ServerRelativeUrl”]))

files = folder.files
context.load(files)
context.execute_query()
for cur_file in files:
    print("File name: {0}".format(cur_file.properties["Name"]))

folders = context.web.folders
context.load(folders)
context.execute_query()
for folder in folders:
    print("Folder name: {0}".format(folder.properties["Name"]))

定义下载文件(上下文):
response = File.open_binary(context, "/sites/new/Shared Documents/2011-A/file1.csv")
打印(响应)
打印(响应。内容)
使用 open(r"C:UsersaakashbDownloadstestfile1.csv", "wb") 作为 local_file:
local_file.write(response.content)

ctx = 无
url = ' https://company.sharepoint.com/sites/new '
ctx_auth = AuthenticationContext(url=url)
如果 ctx_auth.acquire_token_for_user(username='[email protected]', password='12345'):
ctx = ClientContext(url, ctx_auth)
read_folder_and_files(ctx, '文件')

print('进入函数')

下载文件(ctx)

打印('退出函数')`

1)对不起,我给你的代码结构损坏了。
2)刚刚运行你的代码并检查,它正在做我的代码在列表方面所做的事情。 它列出了根目录中的文件(不在任何文件夹中)。 但我想对文件夹做同样的事情。
3)我也想列出文件夹。 当我使用@vgrem的列出文件夹的代码时,它没有向我显示 Documents 的文件夹,而是显示如下文件夹:

文件夹名称:SitePages
文件夹名称:样式库
文件夹名称:_catalogs
文件夹名称:FormServerTemplates
文件夹名称:_private
文件夹名称:共享链接
文件夹名称:SiteAssets
文件夹名称:图像
文件夹名称:共享文档
文件夹名称:列表
文件夹名称:_cts

我在 SharePoint Doc Lib 中没有任何文件夹。

那么,简而言之,如何列出要下载的 Doc Lib 文件夹及其各自的文件?

你好,
请看这里的问题: https :
特别是在这样的行中:

文件夹 = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])

如果它没有帮助,那么我会回复您以提供更多详细信息。
米。

...我的意思是使用 get_folder_by_server_relative_url 方法而不是 get_by_title,例如

app_settings = {'urlrel': '/sites/abc/Shared Documents/TEST'}

def printFolderContents(ctx, listTitle):

try:

    #list_object = ctx.web.lists.get_by_title(listTitle)
    folder = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])
    #folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()
    #print(folder.url)

    files = folder.files
    ctx.load(files)
    ctx.execute_query()

    for myfile in files:
        print("File name: {0}".format(myfile.properties["Name"]))

except:

    print('Problem printing out library contents')   
    sys.exit(1)

让我知道这是否有帮助...

要下载共享文档库中 TEST 文件夹中的文件,您可以更改上述代码以使其成为一个函数,例如:

def fncGetFolderContents(ctx, listTitle):

try:

    #list_object = ctx.web.lists.get_by_title(listTitle)
    folder = ctx.web.get_folder_by_server_relative_url(app_settings['urlrel'])
    #folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()
    #print(folder.url)

    files = folder.files
    ctx.load(files)
    ctx.execute_query()

    #for myfile in files:
    #    print("File name: {0}".format(myfile.properties["Name"]))

    return files

except:

    print('Problem printing out library contents')   
    sys.exit(1)

并稍微改变下载功能,例如:

def downloadFolderFile(ctx, fileName):

try:
    with open(fileName, "wb") as localFile:            
        relativeUrl = '/sites/{0}/Shared%20Documents/{1}/{2}'.format(site, yourFolder, fileName)
        #relativeUrl = app_settings['urlrel']
        response = File.open_binary(ctx, relativeUrl)
        localFile.write(response.content) 
        localFile.close()

except:

    print('Problem downloading file:', fileName)
    sys.exit(1)

myfiles = fncGetFolderContents(ctx, listTitle)

对于 myfiles 中的 myfile:
print("下载文件:{0}".format(myfile.properties["Name"]))
下载文件夹文件(ctx,myfile.properties[“名称”])

非常感谢大佬! 你们两个回复真的很及时,API 也非常棒!

我会尽快通过它并尝试复制。 但是,有没有办法列出文件夹? 我的意思是,当我知道文件夹名称时,您提供的最新代码将起作用。 如果我自动执行此过程并创建新文件夹并保留文件,它将不适用于新文件夹,对吗? 这就是为什么我还想要列出文件夹,以防万一。 无论如何,目前的解决方案应该适用于我的用例。

非常感谢你们俩。 一旦我运行实验,我会在这里更新。

不要感谢我, @vgrem是罪魁祸首:) ...我不确定,也许还有其他方法可以实现相同的目标....

对,要列出共享文档文档库中的所有文件夹,您可以尝试:

    list_object = ctx.web.lists.get_by_title(listTitle)
    folder = list_object.root_folder        
    ctx.load(folder)
    ctx.execute_query()

    folders = folder.folders
    ctx.load(folders)
    ctx.execute_query()

    for myfolder in folders:
        print("File name: {0}".format(myfolder.properties["Name"]))

米。

极好的。 迭代文件夹内容打印和下载工作!

谢谢,

此代码下载损坏的 pdf 文件。 它们是空的 - 156 字节。 任何想法为什么?

通过使用上面的 cosde,我也得到了只有 1kb 文件名的损坏的 pdf 文件。 任何的想法?

通过使用上面的代码,我也得到了只有 1kb 文件名的损坏的 pdf 文件。 任何的想法?

我想通了,对我来说原因是相对网址。 当我需要列出文件夹内容时,我不需要添加 /sites/sitename/library 等,它只需要 /library。 但是当我已经下载文件时,我需要添加 /sites/sitename/folder/file。

这真的很奇怪,因为我仍然可以在不添加 /sites/sitename/ 的情况下访问和下载文件,但内容已损坏。 同时,如果我在获取文件夹内容时添加 /sites/sitename/ ,则会引发错误,并且仅当我使用库启动相对 url 时才有效。

奇怪的是,每个资源都建议将 /sites/sitename 添加到文件夹内容和文件内容的相对 url。

谢谢你的建议。 你能分享最终的工作代码吗? 如果我们想下载 /sites/sitename/Documents/somefolder 等子文件夹的所有内容,那么最终代码是什么?

谢谢你们。 这有助于解决使用 Sharepoint 包时面临的许多问题和问题。

此页面是否有帮助?
0 / 5 - 0 等级