【问题标题】:zipfile.Zipfile open specific file within a Zip folderzipfile.Zipfile 打开 Zip 文件夹中的特定文件
【发布时间】:2019-10-11 17:52:10
【问题描述】:

我是 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()

【问题讨论】:

  • 您是否还在为寻找 zip 文件或从 zip 中提取单个文件而苦恼?到目前为止你的代码是什么?
  • @Trapli 感谢您的回复。这是我坚持的代码。
  • @Trapli elif "data-real-and-mh" in url_resp.url: with zipfile.ZipFile('file{0}'.format(str(file_num)), "r") as z: zip_files=print(z.namelist()) # 显示 zip 文件夹中的可用文件 if "APPRAISAL_ENTITY_INFO" in zip_files: z.extract(path=dest_folder, member="2019-04-04_005519_APPRAISAL_ENTITY_INFO.txt")
  • 对不起,未格式化的代码...我对网站的工作方式不熟悉。我感谢你的帮助。我正在尝试确定动态指向 member="YYYY-MM-DD_APPRAISAL_ENTITY_INFO.txt" 的最佳方式,因为文件名会随着日期的变化而变化。

标签: python-3.x zipfile


【解决方案1】:

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

在这部分之前你的代码很好:

                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

您已经将 zip 文件名命名为 saved_archive,但您尝试以 zip 文件的形式打开其他文件。为什么'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.keywordslistcontentstr。字符串中的列表永远不会有意义。就像['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 循环中实现 for 循环
                    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))

【讨论】:

  • 非常感谢您的指导!我正在编写脚本,并会告诉你结果如何 - 再次感谢!!!
  • 感谢您的帮助。作为更新,我在程序中尝试了这个新添加的代码:with zipfile.ZipFile('file{0}'.format(str(file_num)), "r") as z: zip_files = z.namelist() # print(zip_files) 用于 zip_files 中的内容:而 urls.keywords 在内容中:z.extract(path=dest_folder, member=content)
  • 但是,我收到此错误:虽然 urls.keywords in content: TypeError: 'in ' 需要字符串作为左操作数,而不是列表
  • 我从“urls.keywords”关键字 = [“APPRAISAL_ENTITY_INFO”、“SalesExport”、“account_info”、“account_apprl_year”、“res_detail”、“applied_std_exempt”、“land”创建了这个列表, "acct_exempt_value" ]
  • 我希望能够遍历关键字列表,仅提取与列表匹配的内容。您对我如何做到这一点有什么建议吗?
猜你喜欢
  • 2014-11-07
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 2011-04-06
  • 2019-01-17
  • 2017-03-12
相关资源
最近更新 更多