Você precisa conhecer a manipulação de arquivos em Python para entender como lidar com arquivos ZIP. Se ainda não conhece, veja a seção File Handling do W3Schools.
Conceitos de OOP (programação orientada a objetos) em Python
Conceitos de Python como condicionais, loops, funções, classes etc.
Abra este link para baixar todas as pastas ZIP que usei nas próximas seções.
O que é um arquivo ZIP?
ZIP é um formato de arquivo de arquivamento que oferece compactação de dados sem perdas. Um arquivo ZIP é um único arquivo que contém um ou mais arquivos compactados.
Para que servem os arquivos ZIP?
Arquivos ZIP ajudam você a reunir arquivos relacionados em um só lugar.
Arquivos ZIP ajudam a reduzir o tamanho dos dados.
Arquivos ZIP são transferidos mais rápido do que arquivos individuais em muitas conexões.
Módulo zipfile
Explore todos os métodos e classes do módulo zipfile usando o método dir(). Veja o código para listar todas as classes e métodos do módulo zipfile.
import zipfile # importing the 'zipfile' moduleprint(dir(zipfile))Tecnologia
Você viu um monte de classes e métodos, certo? Mas não vai aprender todos. Vamos focar nas classes e métodos necessários para trabalhar com arquivos ZIP.
Veja algumas exceções, classes e métodos úteis com explicações rápidas.
Exceções
Exceção é uma mensagem usada para exibir o erro exato do jeito que você quiser. Em Python, você usa as palavras-chave try, except, finally para tratar erros.
Se não estiver familiarizado com tratamento de erros, consulte a documentação de Error Handling do Python.
Vamos ver todas as exceções do módulo zipfile.
zipfile.BadZipFile
zipfile.BadZipFile é uma exceção do módulo zipfile. Esse erro é lançado para arquivos ZIP corrompidos. Veja o exemplo abaixo.
## zipfile.BadZipFileimport zipfile
defmain():try:with zipfile.ZipFile('sample_file.zip')asfile:# opening the zip file using 'zipfile.ZipFile' classprint("Ok")except zipfile.BadZipFile:# if the zip file has any errors then it prints the error message which you wrote under the 'except' blockprint('Error: Zip file is corrupted')if __name__ =='__main__': main()## I used a badfile for the testTecnologia
Se você for trabalhar com um arquivo ZIP grande, precisa habilitar o recurso ZIP64 ao abrir o ZIP. Se não habilitar, a exceção LargeZipFile será lançada. Veja o exemplo.
## zipfile.LargeZipFile## Without enabling 'Zip64'import zipfile
defmain():try:with zipfile.ZipFile('sample_file.zip')asfile:print('File size is compatible')except zipfile.LargeZipFile:# it raises an 'LargeZipFile' error because you didn't enable the 'Zip64'print('Error: File size if too large')if __name__ =='__main__': main()Tecnologia
## zipfile.LargeZipFile## With enabling 'ZIP64'import zipfile
defmain():try:with zipfile.ZipFile('sample_file.zip', mode ='r', allowZip64 =True)asfile:# here enabling the 'Zip64'print('File size is compatible')except zipfile.LargeZipFile:print('Error: File size if too large')# if the file size is too large to open it prints the error you have writtenif __name__ =='__main__': main()Tecnologia
Escolha um arquivo ZIP adequado para testar o tratamento de exceções e execute o programa. Vai ficar bem claro.
Classes
Em poucas palavras, uma classe é um conjunto de métodos e atributos. Você usa os métodos e atributos da classe onde quiser criando instâncias dessa classe.
Vamos ver algumas classes do módulo zipfile.
zipfile.ZipFile
A classe mais comum para trabalhar com arquivos ZIP é a ZipFile.
zipfile.ZipFile é usada para escrever e ler arquivos ZIP. Ela tem métodos para manipular esses arquivos.
Agora, explore os métodos da classe ZipFile usando dir(). Veja o código.
import zipfile
print(dir(zipfile.ZipFile))# accessing the 'ZipFile' classTecnologia
Você já usou a classe zipfile.ZipFile para ler arquivos ZIP nos exemplos anteriores.
zipfile.ZipFile inclui vários métodos como extract, open, getinfo, setpassword etc., para trabalhar com arquivos ZIP.
Vamos ver alguns métodos da classe ZipFile.
## zipfile.ZipFileimport zipfile
defmain():with zipfile.ZipFile('sample_file.zip')asfile:# ZipFile.infolist() returns a list containing all the members of an archive fileprint(file.infolist())# ZipFile.namelist() returns a list containing all the members with names of an archive fileprint(file.namelist())# ZipFile.getinfo(path = filepath) returns the information about a member of Zip file.# It raises a KeyError if it doesn't contain the mentioned fileprint(file.getinfo(file.namelist()[-1]))# ZipFile.open(path = filepath, mode = mode_type, pwd = password) opens the members of an archive file# 'pwd' is optional -> if it has password mention otherwise leave it
text_file =file.open(name =file.namelist()[-1], mode ='r')# 'read()' method of the file prints all the content of the file. You see this method in file handling.print(text_file.read())# You must close the file if you don't open a file using 'with' keyword# 'close()' method is used to close the file
text_file.close()# ZipFile.extractall(path = filepath, pwd = password) extracts all the files to current directoryfile.extractall()# after executing check the directory to see extracted filesif __name__ =='__main__': main()Tecnologia
[<ZipInfo filename='extra_file.txt' filemode='-rw-rw-rw-' file_size=59>,<ZipInfo filename='READ ME.txt' filemode='-rw-rw-rw-' file_size=59>,<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>]['extra_file.txt','READ ME.txt','even_odd.py']<ZipInfo filename='even_odd.py' filemode='-rw-rw-rw-' file_size=129>
b"num = int(input('Enter a Number:- '))\r\nif num % 2 == 0:\r\n\tprint('{} is Even'.fromat(num))\r\nelse:\r\n\tprint('{} is Odd'.fromat(num))"Tecnologia
Se quiser aprender todos os métodos da classe ZipFile, use a função help() no método que deseja conhecer.
Agora, veja alguns métodos da classe zipfile.ZipInfo.
## zipfile.ZipInfoimport zipfile
defmain():with zipfile.ZipFile('sample_file.zip')asfile:# 'infolist()' is the object of 'ZipFile' class# 'infolist()' returns a list containing all the folders and files of the zip -> 'ZipInfo' objects# assigning last element of the list to a variable to test all the methods of 'ZipInfo'
archive =file.infolist()
read_me_file = archive[-1]# 'ZipInfo' methods# ZipInfo_object.filename returns the name of the fileprint("Name of the file:- {}".format(read_me_file.filename))# ZipInfo_object.file_size returns the size of the fileprint("Size of the file:- {}".format(read_me_file.file_size))# ZipInfo_object.is_dir() returns True if it's directory otherwise Falseprint("Is directory:- {}".format(read_me_file.is_dir()))# ZipInfo_object.date_time() returns the created date & time of fileprint("File created data & time:- {}".format(read_me_file.date_time))if __name__ =='__main__': main()Tecnologia
Name of the file:- sample_file/README.txt
Size of the file:-59
Is directory:- False
File created data & time:-(2018,10,4,11,32,22)Tecnologia
Vá para a documentação do ZipInfo se quiser saber mais sobre os objetos de ZipInfo.
Métodos
Métodos são blocos de código com uma funcionalidade específica no programa. Por exemplo, se você quer o valor absoluto de um número, pode usar o método embutido do Python chamado abs.
Você pode usá-los onde quiser. Vamos ver alguns métodos do módulo zipfile.
zipfile.is_zipfile()
O método is_zipfile(filename) do módulo zipfile retorna True se o arquivo for um ZIP válido; caso contrário, retorna False.
Veja um exemplo.
## zipfile.is_zip(filename)import zipfile
defmain():print(zipfile.is_zipfile('sample_file.zip'))# it returns Trueif __name__ =='__main__': main()Tecnologia
Nesta seção, você vai aprender a manipular arquivos ZIP como abrir, extrair, escrever etc.
Extraindo um arquivo ZIP
Extraindo os arquivos de um ZIP para o diretório atual usando o método extractall.
## extracting zip fileimport zipfile
defmain():# assigning filename to a variable
file_name ='sample_file.zip'# opening Zip using 'with' keyword in read modewith zipfile.ZipFile(file_name,'r')asfile:# printing all the information of archive file contents using 'printdir' methodprint(file.printdir())# extracting the files using 'extracall' methodprint('Extracting all files...')file.extractall()print('Done!')# check your directory of zip file to see the extracted filesif __name__ =='__main__': main()Tecnologia
File Name Modified Size
sample_file/2018-10-0411:33:220
sample_file/even_odd.py 2018-06-2923:35:54129
sample_file/README.txt 2018-10-0411:32:2259
None
Extracting all files...
Done!Tecnologia
Extraindo um ZIP com senha
Para extrair um ZIP com senha, você precisa passar um valor para o argumento posicional pwd dos métodos extract(pwd = password) ou extractall(pwd = password).
Você deve passar a senha em bytes. Para converter uma str em bytes, use o método embutido bytes do Python com codificação utf-8.
Veja um exemplo.
## extracting zip with passwordimport zipfile
defmain():
file_name ='pswd_file.zip'
pswd ='datacamp'with zipfile.ZipFile(file_name)asfile:# password you pass must be in the bytes you converted 'str' into 'bytes'file.extractall(pwd =bytes(pswd,'utf-8'))if __name__ =='__main__': main()Tecnologia
Você também pode extrair arquivos usando o método setpassword(pwd = password) da classe ZipFile. Veja o exemplo abaixo.
## extracting zip with passwordimport zipfile
defmain():
file_name ='pswd_file.zip'
pswd ='datacamp'with zipfile.ZipFile(file_name)asfile:# 'setpassword' method is used to give a password to the 'Zip'file.setpassword(pwd =bytes(pswd,'utf-8'))file.extractall()if __name__ =='__main__': main()Tecnologia
Criando arquivos ZIP
Para criar um arquivo ZIP, você não precisa de nenhum método extra. Basta passar o nome para a classe ZipFile e ela criará o arquivo compactado no diretório atual.
Veja o exemplo abaixo.
## Creating Zip fileimport zipfile
defmain():
archive_name ='example_file.zip'# below one line of code will create a 'Zip' in the current working directorywith zipfile.ZipFile(archive_name,'w')asfile:print("{} is created.".format(archive_name))if __name__ =='__main__': main()Tecnologia
Você deve abrir arquivos ZIP em modo de escrita para gravar arquivos no pacote. Esse modo sobrescreve todos os arquivos existentes no ZIP.
Veja um exemplo.
## Writing files to zipimport zipfile
defmain():
file_name ='sample_file.zip'# Opening the 'Zip' in writing modewith zipfile.ZipFile(file_name,'w')asfile:# write mode overrides all the existing files in the 'Zip.'# you have to create the file which you have to write to the 'Zip.'file.write('extra_file.txt')print('File overrides the existing files')# opening the 'Zip' in reading mode to checkwith zipfile.ZipFile(file_name,'r')asfile:print(file.namelist())if __name__ =='__main__': main()Tecnologia
File overrides the existing files
['extra_file.txt']Tecnologia
Acrescentando arquivos ao ZIP
Você deve abrir o ZIP em modo de acréscimo (a) para adicionar arquivos ao ZIP. Nesse modo, os arquivos existentes não são sobrescritos.
Veja um exemplo.
## Appending files to zipimport zipfile
defmain():
file_name ='sample_file.zip'# opening the 'Zip' in writing modewith zipfile.ZipFile(file_name,'a')asfile:# append mode adds files to the 'Zip'# you have to create the files which you have to add to the 'Zip'file.write('READ ME.txt')file.write('even_odd.py')print('Files added to the Zip')# opening the 'Zip' in reading mode to checkwith zipfile.ZipFile(file_name,'r')asfile:print(file.namelist())if __name__ =='__main__': main()Tecnologia
Files added to the Zip
['extra_file.txt','READ ME.txt','even_odd.py']Tecnologia
Até aqui, você aprendeu a manipular arquivos ZIP. Agora você consegue abrir, escrever, acrescentar, extrair, criar etc. arquivos ZIP. Vamos escrever um programinha.
Qual é a ideia?
Extraindo vários sub-ZIPs com senha usando loops e zipfile
Você tem um ZIP que contém alguns subarquivos ZIP em níveis. Cada um desses ZIPs tem como senha o próprio nome. O desafio é descompactar todos os ZIPs até chegar ao fim.
Passos para resolver o problema
Extraia o arquivo pai usando o próprio nome como senha.
Obtenha o nome do primeiro filho com o método namelist(). Guarde em uma variável.
Execute um loop por tempo indeterminado.
Verifique se o arquivo é ZIP com is_zipfile(). Se for, faça o seguinte:
Abra o ZIP usando a variável name.
Obtenha a senha do ZIP a partir da variável name.
Extraia o ZIP.
Obtenha e armazene o próximo nome de ZIP na variável name.
caso contrário
Interrompa o loop com break.
Montei o procedimento acima. Se quiser, adapte conforme a organização dos seus arquivos.
## Solutionimport zipfile
defmain():# storing the parent name
parent_file_name ='000.zip'with zipfile.ZipFile(parent_file_name,'r')as parent_file:# extracting the parent file
pswd =bytes(parent_file_name.split('.')[0],'utf-8')
parent_file.extractall(pwd = pswd)# getting the first child
next_zip_name = parent_file.namelist()[0]# looping through the sub zips infinite times until you don't encouter a 'Zip' filewhileTrue:if zipfile.is_zipfile(next_zip_name):# opening the zipwith zipfile.ZipFile(next_zip_name,'r')as child_file:# getting password from the zip name
pswd =bytes(next_zip_name.split('.')[0],'utf-8')# extracting the zip
child_file.extractall(pwd = pswd)# getting the child zip name
next_zip_name = child_file.namelist()[0]else:breakif __name__ =='__main__': main()Tecnologia
Depois de executar o programa acima, você verá que todos os sub-ZIPs foram extraídos para o diretório atual.
Considerações finais
Parabéns por concluir o tutorial!
Espero que tenha gostado. Este artigo ajuda bastante quando você está trabalhando com arquivos ZIP. Agora você já consegue lidar com arquivos ZIP.
Se tiver alguma dúvida sobre o artigo, deixe nos comentários. Eu respondo o quanto antes.
Aprenda sobre os conjuntos do Python: o que são, como criá-los, quando usá-los, funções incorporadas e sua relação com as operações da teoria dos conjuntos.
Mergulhe na ciência de dados com Python para analisar e visualizar seus dados de forma eficaz. Não precisa ter experiência ou conhecimento em programação.
Pré-requisitos para trabalhar com arquivos ZIP
Abra este link para baixar todas as pastas ZIP que usei nas próximas seções.
O que é um arquivo ZIP?
ZIP é um formato de arquivo de arquivamento que oferece compactação de dados sem perdas. Um arquivo ZIP é um único arquivo que contém um ou mais arquivos compactados.
Para que servem os arquivos ZIP?
Módulo zipfile
Explore todos os métodos e classes do módulo zipfile usando o método dir(). Veja o código para listar todas as classes e métodos do módulo zipfile.
Você viu um monte de classes e métodos, certo? Mas não vai aprender todos. Vamos focar nas classes e métodos necessários para trabalhar com arquivos ZIP.
Veja algumas exceções, classes e métodos úteis com explicações rápidas.
Exceções
Exceção é uma mensagem usada para exibir o erro exato do jeito que você quiser. Em Python, você usa as palavras-chave try, except, finally para tratar erros.
Se não estiver familiarizado com tratamento de erros, consulte a documentação de Error Handling do Python.
Vamos ver todas as exceções do módulo zipfile.
zipfile.BadZipFile
zipfile.BadZipFile é uma exceção do módulo zipfile. Esse erro é lançado para arquivos ZIP corrompidos. Veja o exemplo abaixo.
zipfile.LargeZipFile
Se você for trabalhar com um arquivo ZIP grande, precisa habilitar o recurso ZIP64 ao abrir o ZIP. Se não habilitar, a exceção LargeZipFile será lançada. Veja o exemplo.
Escolha um arquivo ZIP adequado para testar o tratamento de exceções e execute o programa. Vai ficar bem claro.
Classes
Em poucas palavras, uma classe é um conjunto de métodos e atributos. Você usa os métodos e atributos da classe onde quiser criando instâncias dessa classe.
Vamos ver algumas classes do módulo zipfile.
zipfile.ZipFile
A classe mais comum para trabalhar com arquivos ZIP é a ZipFile.
zipfile.ZipFile é usada para escrever e ler arquivos ZIP. Ela tem métodos para manipular esses arquivos.
Agora, explore os métodos da classe ZipFile usando dir(). Veja o código.
Você já usou a classe zipfile.ZipFile para ler arquivos ZIP nos exemplos anteriores.
zipfile.ZipFile inclui vários métodos como extract, open, getinfo, setpassword etc., para trabalhar com arquivos ZIP.
Vamos ver alguns métodos da classe ZipFile.
Se quiser aprender todos os métodos da classe ZipFile, use a função help() no método que deseja conhecer.
Ou vá à documentação oficial do Python.
zipfile.ZipInfo
A classe zipfile.ZipInfo representa um membro de uma pasta ZIP.
Primeiro, explore todos os objetos da classe zipfile.ZipInfo usando o método dir(). Veja o código abaixo.
Agora, veja alguns métodos da classe zipfile.ZipInfo.
Vá para a documentação do ZipInfo se quiser saber mais sobre os objetos de ZipInfo.
Métodos
Métodos são blocos de código com uma funcionalidade específica no programa. Por exemplo, se você quer o valor absoluto de um número, pode usar o método embutido do Python chamado abs.
Você pode usá-los onde quiser. Vamos ver alguns métodos do módulo zipfile.
zipfile.is_zipfile()
O método is_zipfile(filename) do módulo zipfile retorna True se o arquivo for um ZIP válido; caso contrário, retorna False.
Veja um exemplo.
Como manipular arquivos ZIP
Nesta seção, você vai aprender a manipular arquivos ZIP como abrir, extrair, escrever etc.
Extraindo um arquivo ZIP
Extraindo os arquivos de um ZIP para o diretório atual usando o método extractall.
Extraindo um ZIP com senha
Para extrair um ZIP com senha, você precisa passar um valor para o argumento posicional pwd dos métodos extract(pwd = password) ou extractall(pwd = password).
Você deve passar a senha em bytes. Para converter uma str em bytes, use o método embutido bytes do Python com codificação utf-8.
Veja um exemplo.
Você também pode extrair arquivos usando o método setpassword(pwd = password) da classe ZipFile. Veja o exemplo abaixo.
Criando arquivos ZIP
Para criar um arquivo ZIP, você não precisa de nenhum método extra. Basta passar o nome para a classe ZipFile e ela criará o arquivo compactado no diretório atual.
Veja o exemplo abaixo.
Escrevendo em arquivos ZIP
Você deve abrir arquivos ZIP em modo de escrita para gravar arquivos no pacote. Esse modo sobrescreve todos os arquivos existentes no ZIP.
Veja um exemplo.
Acrescentando arquivos ao ZIP
Você deve abrir o ZIP em modo de acréscimo (a) para adicionar arquivos ao ZIP. Nesse modo, os arquivos existentes não são sobrescritos.
Veja um exemplo.
Até aqui, você aprendeu a manipular arquivos ZIP. Agora você consegue abrir, escrever, acrescentar, extrair, criar etc. arquivos ZIP. Vamos escrever um programinha.
Qual é a ideia?
Extraindo vários sub-ZIPs com senha usando loops e zipfile
Passos para resolver o problema
Execute um loop por tempo indeterminado.
Verifique se o arquivo é ZIP com is_zipfile(). Se for, faça o seguinte:
Abra o ZIP usando a variável name.
Obtenha a senha do ZIP a partir da variável name.
Extraia o ZIP.
Obtenha e armazene o próximo nome de ZIP na variável name.
caso contrário
Montei o procedimento acima. Se quiser, adapte conforme a organização dos seus arquivos.
Depois de executar o programa acima, você verá que todos os sub-ZIPs foram extraídos para o diretório atual.
Considerações finais
Parabéns por concluir o tutorial!
Espero que tenha gostado. Este artigo ajuda bastante quando você está trabalhando com arquivos ZIP. Agora você já consegue lidar com arquivos ZIP.
Se tiver alguma dúvida sobre o artigo, deixe nos comentários. Eu respondo o quanto antes.
Se você é novo em Python, faça o curso gratuito da DataCamp Intro to Python for Data Science para aprender a linguagem Python ou leia a documentação oficial do Python.
Bons códigos!