【问题标题】:Python JSON import to MongoDB from ZIP filesPython JSON 从 ZIP 文件导入 MongoDB
【发布时间】:2017-10-25 12:13:19
【问题描述】:

我有一个脚本,它从一个文件夹中获取所有 .zip 文件,然后一个接一个地打开 zip 文件,加载其中的 JSON 文件的内容并将其导入 MongoDB。

我得到的错误是the JSON object must be str, bytes or bytearray, not 'TextIOWrapper'

代码是:

import json
import logging
import logging.handlers
import os
from logging.config import fileConfig
from pymongo import MongoClient


def import_json():
    try:
        client = MongoClient('5.57.62.97', 27017)
        db = client['vuln_sets']
        coll = db['vulnerabilities']
        basepath = os.path.dirname(__file__)
        filepath = os.path.abspath(os.path.join(basepath, ".."))
        archive_filepath = filepath + '/vuln_files/'
        filedir = os.chdir(archive_filepath)
        for item in os.listdir(filedir):
            if item.endswith('.json'):
                file_name = os.path.abspath(item)
                fp = open(file_name, 'r')
                json_data = json.loads(fp)
                for vuln in json_data:
                  print(vuln)
                  coll.insert(vuln)
                os.remove(file_name)
    except Exception as e:
        logging.exception(e)

我可以使用单个文件而不是多个文件来完成这项工作,即做一个我写的文件:

from zipfile import ZipFile
import json
import pymongo

archive = ZipFile("vulners_collections/cve.zip")
archived_file = archive.open(archive.namelist()[0])
archive_content = archived_file.read()
archived_file.close()

connection = pymongo.MongoClient("mongodb://localhost")
db=connection.vulnerability
vuln1 = db.vulnerability_collection
vulners_objects = json.loads(archive_content)

for item in vulners_objects:
    vuln1.insert(item)

【问题讨论】:

  • 尝试用with open(file, "r")替换file.open(...) / file.close
  • 我没有使用 glob 的经验,但是从浏览文档中我得到的印象是您的 archive_files 是一个简单的文件路径列表作为字符串,对吗?您不能对字符串执行.open 之类的操作(因此您的错误),因此请尝试使用上面的命令打开文件。
  • 这不行,我只是得到''str' object has no attribute 'read'的错误

标签: python json mongodb


【解决方案1】:

根据我上面的评论:

我没有使用 glob 的经验,但是从浏览文档中我得到的印象是您的 archive_files 是一个简单的文件路径列表作为字符串,对吗?您不能对字符串执行 .open 之类的操作(因此您的错误),因此请尝试将您的代码更改为:

    ...
    archive_filepath = filepath + '/vuln_files/'
    archive_files = glob.glob(archive_filepath + "/*.zip")

    for file in archive_files:
        with open(file, "r") as currentFile:
            file_content = currentFile.read()
            vuln_content = json.loads(file_content)
            for item in vuln_content:
                coll.insert(item)
   ...

file 不是文件对象或任何东西,而只是一个简单的字符串。所以你不能对它执行字符串不支持的方法。

【讨论】:

  • 这让我更进一步,我现在遇到了将编码从 UTF8 更改为 windows-1252 的问题,因为这是 JSON 文件的编码方式。我尝试使用currentFile.encoding = 'windows-1252',但这只会引发只读属性错误
  • @Luke 与 open(file, "r", encoding="windows-1252") 一起使用
  • 原来我忘了先解压文件!但现在我的脚本运行没有错误,但我在 MongoDB 中什么也没有,我添加的打印语句也没有做任何事情。我已经编辑了上面的代码
  • @Luke 你能给你的输入文件举个例子吗?检查archiveListvuln_content的长度是否有数据。
  • 我已经更新了代码,因为我分别处理了 Zipfile 并获得了原始 .json 文件,所以现在我正在尝试遍历这些
【解决方案2】:

您正在通过将迭代器设置为 namelist 方法的结果来重新定义迭代器。你需要一个 for 循环来遍历 zip 文件的内容,当然还有一个新的迭代器变量。

【讨论】:

  • 我尝试创建一个新的 for 循环,但认为我有这个错误:` for file in archive_files: open_files = file.open(file.namelist()[0]) for open_file in open_files: file_content = file.read() file.close vuln_content = json.loads(file_content)`
【解决方案3】:

file.close 是不是错了,正确的调用是 file.close()。

你可以使用json.load()直接加载文件,而不是json.loads()

fp = open(file_name, 'r')
json_data = json.load(fp)
fp.close()

【讨论】:

    猜你喜欢
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 2015-10-13
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    相关资源
    最近更新 更多