Office365-rest-python-client: Como posso baixar a pasta do SharePoint que contém vários arquivos?

Criado em 27 mar. 2019  ·  15Comentários  ·  Fonte: vgrem/Office365-REST-Python-Client

Meu código Python 3:

de office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext

url = ' https://company.sharepoint.com/sites/abc '
ctx_auth = AuthenticationContext (url = url)
if ctx_auth.acquire_token_for_user (username='[email protected] ', senha =' 12345 '):
ctx = ClientContext (url, ctx_auth)
lists = ctx.web.lists
ctx.load (listas)
ctx.execute_query ()
para l nas listas:
imprimir (l.properties ['Título'])

A partir do código acima, posso listar os itens do site. Mas meu plano é executar todo esse módulo no AWS Lambda usando Python e fazer o download de documentos do SharePoint e armazenar no AWS S3.

Uma pasta pode ter vários arquivos. Quero baixar a pasta inteira com todos os arquivos. Alguém fez isso? Qualquer ajuda? Um código funcional será de grande ajuda, pois sou totalmente novo em web scraping!

Comentários muito úteis

Não me agradeça, @vgrem é a culpada :) ... e não tenho certeza, talvez existam outras maneiras de conseguir o mesmo ....

à direita, para listar todas as pastas dentro da biblioteca de documentos de Documentos Compartilhados, você pode tentar:

    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"]))

m.

Todos 15 comentários

Oi,
talvez você possa fazer isso em um loop, por exemplo:

  1. retornar o conteúdo da biblioteca de documentos do sharepoint primeiro usando uma função:

listTitle = "Documentos"
site = "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. em seguida, baixe cada arquivo chamando um proc, por exemplo:

def downloadFile (ctx, fileName):

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)

para meuarquivo em meusarquivos:
print ("Baixando arquivo: {0}". format (myfile.properties ["Name"]))
downloadFile (ctx, `myfile.properties [" Nome "])

m.

pls, indente as duas últimas linhas no loop for, não consigo fazer isso.
m.

Ei,

Obrigado por uma resposta tão rápida. Estou conseguindo baixar com sucesso os arquivos, dado, tenho que dar até o nome do arquivo. Mas, para poder baixar recursivamente todos os arquivos, preciso primeiro listar todos os existentes em uma pasta específica que, após várias tentativas, obtive erros de Não Encontrado. Talvez eu esteja errado em algum lugar, porque meu conceito de Título não está certo, então sempre que tento listar uma subpasta dando esse nome como um título, eu falho. Vou examinar seu código e ver se consigo fazer isso.

Enquanto isso, meu código em execução atual (o download funciona bem, listando pastas e arquivos para o root está funcionando, mas sempre que no Título estou dando qualquer nome de pasta específico diferente de Documentos, ele falha):

`from office365.runtime.auth.authentication_context import AuthenticationContext
from office365.sharepoint.client_context import ClientContext
from office365.sharepoint.file import File
from office365.sharepoint.file_creation_information import FileCreationInformation

def read_folder_and_files (contexto, list_title):
"" "Leia um exemplo de pasta" ""
list_obj = context.web.lists.get_by_title (list_title)
folder = list_obj.root_folder
context.load (pasta)
context.execute_query ()
print ("URL da lista: {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"]))

def download_file (contexto):
response = File.open_binary (context, "/ sites / new / Shared Documents / 2011-A / file1.csv")
imprimir (resposta)
imprimir (response.content)
com open (r "C: UsersaakashbDownloadstestfile1.csv", "wb") como local_file:
local_file.write (response.content)

ctx = Nenhum
url = ' https://company.sharepoint.com/sites/new '
ctx_auth = AuthenticationContext (url = url)
if ctx_auth.acquire_token_for_user (username='[email protected] ', password =' ​​12345 '):
ctx = ClientContext (url, ctx_auth)
read_folder_and_files (ctx, 'Documentos')

imprimir ('inserir a função')

download_file (ctx)

print ('saindo da função') `

1) Desculpe pela estrutura quebrada do meu código que eu dei a você.
2) Apenas executei seu código e verifiquei, ele está fazendo exatamente o que meu código está fazendo em termos de listagem. Ele está listando os arquivos na raiz (não dentro de nenhuma pasta). Mas quero fazer o mesmo com as pastas.
3) Também quero listar as pastas. Quando eu uso o código de @vgrem para listar pastas, ele não está me mostrando as pastas dos Documentos, mas mostrando pastas como:

Nome da pasta: SitePages
Nome da pasta: Biblioteca de Estilos
Nome da pasta: _catalogs
Nome da pasta: FormServerTemplates
Nome da pasta: _private
Nome da pasta: Links de compartilhamento
Nome da pasta: SiteAssets
Nome da pasta: imagens
Nome da pasta: Documentos Compartilhados
Nome da pasta: Listas
Nome da pasta: _cts

Quais são nenhuma das pastas que tenho no SharePoint Doc Lib.

Resumindo, como posso listar as pastas do Doc Lib e seus respectivos arquivos a serem baixados?

Oi,
analise o problema aqui: https://github.com/vgrem/Office365-REST-Python-Client/issues/91
especificamente na linha que funciona assim:

folder = ctx.web.get_folder_by_server_relative_url (app_settings ['urlrel'])

Se não ajudar, entrarei em contato para fornecer mais detalhes.
m.

... o que eu quis dizer era usar o método get_folder_by_server_relative_url em vez de get_by_title, por exemplo

app_settings = {'urlrel': '/ sites / abc / Documentos compartilhados / TESTE'}

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)

Me avise se isso ajudar ...

para baixar os arquivos dentro da pasta TEST dentro da biblioteca de Documentos Compartilhados, você pode, por exemplo, alterar o código acima para torná-lo uma função, como:

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)

e altere um pouco a função de download, por exemplo:

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)

para meuarquivo em meusarquivos:
print ("Baixando arquivo: {0}". format (myfile.properties ["Name"]))
downloadFolderFile (ctx, myfile.properties ["Nome"])

Valeu mesmo, cara! Vocês dois estão realmente prontos nas respostas, assim como a API é absolutamente incrível!

Vou passar por isso o mais rápido possível e tentar replicar. Mas existe uma maneira de listar as pastas? Quer dizer, o código mais recente que você forneceu funcionará quando eu souber o nome da pasta. Caso eu automatize o processo e seja criada uma nova pasta e os arquivos sejam mantidos, não vai funcionar para a nova pasta, certo? É por isso que eu também queria a pasta de listagem, apenas para garantir. De qualquer forma, a solução atual deve funcionar para meu caso de uso.

Muito obrigado a vocês dois. Vou atualizar aqui, assim que executar o experimento.

Não me agradeça, @vgrem é a culpada :) ... e não tenho certeza, talvez existam outras maneiras de conseguir o mesmo ....

à direita, para listar todas as pastas dentro da biblioteca de documentos de Documentos Compartilhados, você pode tentar:

    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"]))

m.

Fantástico. A impressão e o download iterativos do conteúdo da pasta funcionaram!

Obrigado,

Este código baixa arquivos PDF corrompidos. Eles estão vazios - 156 bytes. Alguma ideia por quê?

Também estou recebendo arquivos PDF corrompidos com nome de arquivo de apenas 1kb usando o cosde acima. Qualquer ideia?

Também estou recebendo arquivos PDF corrompidos com nome de arquivo de apenas 1kb usando o código acima. Qualquer ideia?

Eu descobri, para mim o motivo era o url relativo. Quando preciso listar o conteúdo da pasta, não preciso adicionar / sites / nome do site / biblioteca etc., basta ser / library. Mas quando já estou baixando os arquivos, preciso adicionar / sites / nome do site / pasta / arquivo.

Isso é realmente estranho, porque eu ainda posso acessar e baixar arquivos sem adicionar / sites / nome do site /, mas o conteúdo está corrompido. Ao mesmo tempo, se eu adicionar / sites / nome do site / quando obtenho o conteúdo da pasta, ocorre um erro e só funciona se eu iniciar o url relativo com uma biblioteca.

É estranho que cada recurso sugira adicionar / sites / nome do site à url relativa para o conteúdo da pasta e do arquivo.

Obrigado pela sugestão. você pode compartilhar o código de trabalho final. Se quisermos baixar todo o conteúdo de uma subpasta como / sites / nome do site / Documentos / alguma pasta, então qual seria o código final?

Obrigado rapazes. Isso ajuda a resolver muitos problemas e questões enfrentados durante o uso do pacote Sharepoint.

Esta página foi útil?
0 / 5 - 0 avaliações