Zipfile password recovery program
1. Follow the styleguide (PEP8)

don't import modules which you're not using (random)
more, imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
I always like to put my imports in alphabetical order, so that it gets easier to find them.
you should have two newlines before defining your methods
you should also have a space after every ,
you should put a space before and after operators (x = 'something'); this is not required when defining arguments.
instead of commenting code in the middle of the method, try to split the logic of your program in separate functions.
you should be using the new .format() style

2. Working on the code:

you should really let the user choose where the files actually are
don't use bare excepts.
you can directly use .encode() if you want to convert a string to bytes. That's actually the pythonic way of doing it as per this SO discussion
when reading a file, you can omit the r mode, as that's the default one

3. Efficiency
The problem does not come from the zip module but rather from the cartesian product you're doing. As @jonsharpe mentioned in his comments, your program has to go through a lot of passwords.
The final code would look like this:
&quot;&quot;&quot;
Zipfile password cracker using a dictionary attack and, if not successful, 
switches to bruteforce
&quot;&quot;&quot;

import itertools
import string
import time
import zipfile


ARCHIVE_PATH = 'test.zip'
DICTIONARY_PATH = 'dictionary.txt'


def dictionary_attack():
    &quot;&quot;&quot;Tries at first a dictionary attack&quot;&quot;&quot;

    t0 = time.time()
    with open(DICTIONARY_PATH) as f:
        for password in f:
            password = password.rstrip().encode()
            try:
                zipfile.ZipFile(ARCHIVE_PATH).extractall(pwd=password)
                t1 = time.time()
                print('Password found: {}\nTime spent: {} seconds'.format(password.decode(), t1 - t0))

                return True
            except RuntimeError:
                pass
    return False


def bruteforce_attack(nbcharmax):
    &quot;&quot;&quot;If the password hasn't been found yet, the function switches to bruteforce&quot;&quot;&quot;

    alphabet = string.ascii_letters + string.digits + string.punctuation

    t0 = time.time()
    for i in range(1, nbcharmax):
        for j in itertools.product(alphabet, repeat=i):
            password = ''.join(j).encode()
            try:
                zipfile.ZipFile(ARCHIVE_PATH).extractall(pwd=password)
                t1 = time.time()
                print('Password found: {}\nTime spent: {} seconds'.format(password.decode(), t1 - t0))

                return True
            except RuntimeError:
                pass
    return False

if __name__ == &quot;__main__&quot;:
    if not dictionary_attack():
        bruteforce_attack(4)