zipfile.Zipfile打开Zip文件夹中的特定文件

时间:2019-10-11 17:52:10

标签: python-3.x zipfile

我是Python的新手,我正在尝试构建一个程序,该程序可以从各种网站下载和提取zip文件。我粘贴了我为此编写的两个程序。第一个程序是一个名为“ urls”的“子”程序,我将其导入第二个程序。我正在尝试遍历每个URL,并在每个URL中遍历每个数据文件,最后检查“关键字”列表是否是文件名的一部分,如果是,则下载并解压缩该文件。我被困在需要循环浏览“关键字”列表以检查要下载的文件名的部分。你能帮忙吗?感谢您的任何建议或指导。谢谢。安迪

**Program #1 called "urls":**

urls = [
    "https://www.dentoncad.com/content/data-extracts/1-appraisal-data-extracts/1-2019/1-preliminary/2019-preliminary" \
    "-protax-data.zip",
    "http://www.dallascad.org/ViewPDFs.aspx?type=3&id=//DCAD.ORG\WEB\WEBDATA\WEBFORMS\DATA%20PRODUCTS\DCAD2020_" \
    "CURRENT.ZIP"
]

keywords = [
    "APPRAISAL_ENTITY_INFO",
    "SalesExport",
    "account_info",
    "account_apprl_year",
    "res_detail",
    "applied_std_exempt",
    "land",
    "acct_exempt_value"
]`enter code here`

    enter code here

**Program #2 (primary program):**

import requests
import zipfile
import os
import urls


def main():
    print_header()
    dwnld_zfiles_from_web()


def print_header():
    print('---------------------------------------------------------------------')
    print('               DOWNLOAD ZIP FILES FROM THE WEB APP')
    print('---------------------------------------------------------------------')
    print()


def dwnld_zfiles_from_web():
    file_num = 0

    dest_folder = "C:/Users/agbpi/OneDrive/Desktop/test//"

    # loop through each url within the url list, assigning it a unique file number each iteration
    for url in urls.urls:
        file_num = file_num + 1
        url_resp = requests.get(url, allow_redirects=True, timeout=5)

        if url_resp.status_code == 200:
            saved_archive = os.path.basename(url)
            with open(saved_archive, 'wb') as f:
                f.write(url_resp.content)

                # for match in urls.keywords:

                print("Extracting...", url_resp.url)

                with zipfile.ZipFile('file{0}'.format(str(file_num)), "r") as z:
                    zip_files = z.namelist()
                    # print(zip_files)
                    for content in zip_files:
                        while urls.keywords in content:
                            z.extract(path=dest_folder, member=content)
                    # while urls.keywords in zip_files:
                    #     for content in zip_files:
                    #         z.extract(path=dest_folder, member=content)

                print("Finished!")


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:0)

好的,根据更新的问题更新答案。

在这部分之前,您的代码还可以:

                with zipfile.ZipFile('file{0}'.format(str(file_num)), "r") as z:
                    zip_files = z.namelist()
                    # print(zip_files)
                    for content in zip_files:
                        while urls.keywords in content:
                            z.extract(path=dest_folder, member=content)

问题1

您已经将压缩文件名命名为saved_archive,但是您尝试将其他文件作为压缩文件打开。为什么'file{0}'.format(str(file_num))?您应该只with zipfile.ZipFile(saved_archive, "r") as z:

问题2

while有点像if语句,但是它不能用作过滤器(似乎您想要这样做)。 while的作用是检查语句的条件(在while部分之后)是否为True-ish,如果是,则执行缩进代码。并且,第一个False-ish评估开始后,代码执行就会继续进行。因此,如果您的条件评估会产生这些结果[True, False, True],则第一个会触发缩进的代码运行,第二个会导致退出,而第三个会由于先前的退出条件而被忽略。但是条件无效,导致:

问题3

url.keywordslist,而contentstr。字符串列表永远没有意义。就像['apple', 'banana'] in 'b''b'将没有这样的成员。您可以颠倒逻辑,但是请记住,'b' in ['apple', 'banana']将是False'banana' in ['apple', 'banana']将是True

在您的情况下,这意味着以下条件:'_SalesExport.txt' in urls.keywords将为False!为什么?因为url.keywords是:

[
    "APPRAISAL_ENTITY_INFO",
    "SalesExport",
    "account_info",
    "account_apprl_year",
    "res_detail",
    "applied_std_exempt",
    "land",
    "acct_exempt_value"
]

SalesExport不是 _SalesExport.txt

要实现部分匹配检查,您需要将列表项(字符串)与字符串进行比较。 "SalesExport" in "_SalesExport.txt"True,但是"SalesExport" in ["_SalesExport.txt"]False,因为SalesExport不是列表的成员。

您可以做三件事:

  1. 将您的keywords列表更新为精确的文件名,以便content in kw_list可以正常工作(这意味着,如果zip文件中有目录结构,则也必须包含该目录结构)
                    for content in zip_files:
                        if content in urls.keywords:
                            z.extract(path=dest_folder, member=content)
  1. 在for cycle中实现for cycle
                    for content in zip_files:
                        for kw in urls.keywords:
                            if kw in content:
                                z.extract(path=dest_folder, member=content)
  1. 使用发电机
matches = [x for x in zip_files if any(y for y in urls.keywords if y in x)]
for m in matches:
    z.extract(path=dest_folder, member=m)


最后,一个建议:

超时

注意

url_resp = requests.get(url, allow_redirects=True, timeout=5)

“超时”控制两项,连接超时和读取超时。由于响应可能需要5秒钟以上的时间,因此您可能需要更长的读取超时时间。您可以将超时指定为元组:(连接超时,读取超时)。因此,更好的参数是:

url_resp = requests.get(url, allow_redirects=True, timeout=(5, 120))