Zipear archivos en python

Mi progtwig se ejecuta sin problemas, pero quiero que mis archivos de ftp estén comprimidos en mi disco local

Mi problema: solo se está comprimiendo un archivo 1 después de llamar a mi función main ()

Aquí está mi código:

principal

import os import upload import download import zipfile import ConfigParser import ftputil def main(): #create a folder Temp on d drive for later use path = r'D:\Temp' os.mkdir(path) #parse all the values at config.ini file config = ConfigParser.ConfigParser() config.readfp(open('config.ini')) server = config.get('main', 'Server') username = config.get('main', 'Username') password = config.get('main', 'Password') uploads = config.get('main', 'Upload folder') downloads = config.get('main', 'Download folder') #connect to ftp ftp = ftputil.FTPHost(server, username, password) dirlist = ftp.listdir(downloads) for list in dirlist: ftp.chdir(downloads) target = os.path.join(path, list) ftp.download(list, target) ######################################################### # THis section is where algo fails but the program run# ######################################################## #zipping files absolute_path = r'D:\Temp' dirlist = os.listdir(absolute_path) filepath = r'D:\Temp\project2.zip' for list in dirlist: get_file = os.path.join(absolute_path, list) zip_name = zipfile.ZipFile(filepath, 'w') zip_name.write(get_file, 'Project2b\\' + list) if __name__ == '__main__': print "cannot be" 

Cuando haces esto:

 for list in dirlist: get_file = os.path.join(absolute_path, list) zip_name = zipfile.ZipFile(filepath, 'w') zip_name.write(get_file, 'Project2b\\' + list) 

usted recrea un archivo Zip para cada archivo que desea comprimir, el modo "w" significa que lo vuelve a crear desde cero.

Intenta esto (crea el archivo zip antes del bucle):

 zip_name = zipfile.ZipFile(filepath, 'w') for list in dirlist: get_file = os.path.join(absolute_path, list) zip_name.write(get_file, 'Project2b\\' + list) 

O esto, se abrirá el archivo zip en modo de adición:

 for list in dirlist: get_file = os.path.join(absolute_path, list) zip_name = zipfile.ZipFile(filepath, 'a') zip_name.write(get_file, 'Project2b\\' + list) 

Echa un vistazo al módulo de shutil. Hay un ejemplo que utiliza shutil.make_archive ():

http://docs.python.org/library/shutil.html

Si tienes muchos archivos puedes zipearlos en paralelo:

 import zipfile from pathlib import Path, WindowsPath from typing import List, Text import logging from time import time from concurrent.futures import ThreadPoolExecutor logging.basicConfig( format="%(asctime)s - %(message)s", datefmt="%H:%M:%S", level=logging.DEBUG ) PATH = (r"\\some_directory\subdirectory\zipped") def file_names() -> List[WindowsPath]: p = Path(PATH) file_names = list(p.glob("./*.csv")) logging.info("There are %d files", len(file_names)) return file_names def zip_file(file: WindowsPath) -> None: zip_file_name = Path(PATH, f"{file.stem}.zip") with zipfile.ZipFile(zip_file_name, "w") as zip: zip.write(file, arcname=file.name, compress_type=zipfile.ZIP_DEFLATED) def main(files: List[Text]) -> None: t0 = time() number_of_files = len(files) with ThreadPoolExecutor() as executor: for counter, _ in enumerate(executor.map(zip_file, files), start=1): # update progress every 100 files if counter % 100 == 0: logging.info( "Processed %d/%d. TT: %d:%d", counter, number_of_files, *divmod(int(time() - t0), 60), ) logging.info( "Finished zipping %d files. Total time: %d:%d", len(files), *divmod(int(time() - t0), 60), ) if __name__ == "__main__": files = file_names() main(files) 

La mejor manera de hacer esto es poner instrucciones de depuración en tus bucles for, hay dos posibilidades;

una es que el primer forloop solo descarga un archivo de la carpeta ftp

dos es que el primer bucle descarga todos los archivos pero el segundo bucle comprime solo uno de ellos

use declaraciones impresas para ver qué archivos se descargan / se comprimen en los bucles, buena suerte