'How do I extract and process all the files in a zipfile?

I want to extract and process all the files in a zipped file?

import re
import zipfile
import pathlib
import pandas as pd


# Download mHealth dataset
def parse(zip_file):
    # Extract all the files in output directory
    with zipfile.ZipFile(zip_file, "r") as zfile:

        for file in zfile.extractall():
            if file.is_file():
                old_name = file.stem
                extension = file.suffix
                directory = file.parent

                new_name = re.sub("mHealth_", "", old_name) + extension
                file = file.rename(pathlib.Path(directory, new_name))
        zfile.close()
        return file

Traceback error:

Traceback (most recent call last):   
File "C:\Users\User\PycharmProjects\algorithms\project_kmeans.py", line 47,
in <module>
    df_ = parse(zip_file_)   File "C:\Users\User\PycharmProjects\algorithms\project_kmeans.py", line 12,
in parse
    for file in zfile.extractall(): TypeError: 'NoneType' object is not iterable

Process finished with exit code 1


Solution 1:[1]

You need infolist() or namelist() instead of extractall() to work with for-loop.

extractall() extracts files from zip but it doesn't give file names - so it can't be used with for-loop.

infolist() or namelist() gives file names but it makes other problem because it gives object ZipInfo or string, not Path, so it doesn't have .is_file, .stem, etc. You would have to convert to Path.

import zipfile
import pathlib
import pandas as pd

# Download mHealth dataset
def parse(zip_file):
    
    results = []
    
    # Extract all the files in output directory
    with zipfile.ZipFile(zip_file, "r") as zfile:

        zfile.extractall()  # extract
        
        #for filename in zfile.namelist():
        #    path = pathlib.Path(filename)

        for fileinfo in zfile.infolist():
            filename = fileinfo.filename
            path = pathlib.Path(filename)

            if path.is_file():
                old_name = path.stem
                extension = path.suffix
                directory = path.parent

                new_name = old_name.replace("mHealth_", "") + extension
                path = path.rename(pathlib.Path(directory, new_name))
                print('path:', path)
                results.append([filename, new_name])
                
    df = pd.DataFrame(results, columns=['old', 'new'])
    return df

df = parse('test.zip')
print(df)

Doc: infolist and extractall

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1