Python MySQL TypeError:必须是str,而不是元组

时间:2017-10-24 14:59:16

标签: python mysql

我有以下代码连接到MySQL数据库,并检查哪些记录被“1”字段标记为“活动”。

然后,代码会使用下载网址中10字段的内容下载一些文件。

我认为问题在于MySQL查询或for循环来进行下载。

代码是: -

vulntype

对此的追溯是: -

import requests
import os
import MySQLdb
from hurry.filesize import size, si
import logging
import logging.handlers
from logging.config import fileConfig

logging.handlers = logging.handlers
fileConfig('data/logging_config.ini')
logger = logging.getLogger("downloader")


active_vuln_type = None


def get_active_vuln_sets():

    global active_vuln_type
    try:
        logging.info('Connecting to the database...')
        active_vuln_type = con = MySQLdb.connect(*******)
        logging.info('Database connected!')
    except FileNotFoundError as fnf:
        logging.error(fnf)
    except MySQLdb.Error as e:
        logging.error(e)
    try:
        logging.info('Getting active vulnerability sets...')
        cur = con.cursor()
        active = "1"
        cur.execute("""SELECT vulntype FROM vuln_sets WHERE active = %s""", (active))
        active_vuln_type = cur.fetchall()
    except MySQLdb.Error as e:
        logging.exception(e)


def download():
    try:
        logging.info('Downloading vulnerability set files...')
        for x in active_vuln_type:
            basepath = os.path.dirname(__file__)
            filepath = os.path.abspath(os.path.join(basepath, ".."))
            response = requests.get('https://vulners.com/api/'
                                    'v3/archive/collection/?type=' + x)
            with open(filepath + '/vuln_files/' + x + '.zip', 'wb') as f:
                f.write(response.content)
            filesize = size(os.path.getsize
                            (filepath + '/vuln_files/'
                             + x + '.zip'), system=si)
            files = x + ".zip - " + str(filesize)
            logging.info('Downloaded ' + x + '.zip Successfully')
            logging.info('File details: ' + files)
    except Exception as e:
        logging.exception(e)

3 个答案:

答案 0 :(得分:2)

active_vuln_type = cur.fetchall()

此行返回数据库中的行列表。 每一行都是一个元组。当然你只是从表中选择一列,但界面是相同的:每行是一个元组,每列一个值。

for x in active_vuln_type:

此处x是一个类似("vulnerability of some kind",)的元组;注意尾随的逗号。你需要解压缩它:

for db_row in active_vuln_type:
    x = db_row[0]  # The first and column in the row.

除此之外,请考虑描述性地命名x,从一个过程返回active_vuln_type并将其作为参数传递给另一个过程。这将使您的代码更简洁,更容易测试。

def get_active_vuln_sets(db_host, db_user, db_password):
   # Do your stuff, using the db credentials....
   return active_vuln_type

def download(active_vuln_type):
   # Same source as now.

现在你可以download(get_active_vuln_sets('192.168.100.1', 'joe', 'secret'))

或者您可以在不触及数据库的情况下测试/重试相同的事情:download([("CVE-xyxxy",), ("CVE-asdfghjkl",)])

你可以做的另一件事是返回一个干净的名字列表,而不是原始的DB元组:

def get_active_vuln_sets(...):
    # .....
    return [x[0] for x in cur.fetchall()]

现在返回的值将是单个可直接使用的值的列表,因此您的原始download(...)代码可以使用它。

答案 1 :(得分:1)

你得到它是一个元组,所以你需要得到第一个元素x [0]

def download():
    try:
        logging.info('Downloading vulnerability set files...')
        for x in active_vuln_type:
            basepath = os.path.dirname(__file__)
            filepath = os.path.abspath(os.path.join(basepath, ".."))
            response = requests.get('https://vulners.com/api/'
                                    'v3/archive/collection/?type=' + x[0])
            with open(filepath + '/vuln_files/' + x[0] + '.zip', 'wb') as f:
                f.write(response.content)
            filesize = size(os.path.getsize
                            (filepath + '/vuln_files/'
                             + x[0] + '.zip'), system=si)
            files = x[0] + ".zip - " + str(filesize)
            logging.info('Downloaded ' + x[0] + '.zip Successfully')
            logging.info('File details: ' + files)
    except Exception as e:
        logging.exception(e)

答案 2 :(得分:0)

避免这些类型错误的原因:就像我知道的那样,您必须使用 try: 和 except 函数。

使用其他来源获取数据可能不是您想要的结果。 您的 MySQL 数据库是否出现类型错误?通过过滤它们,检查哪些记录被包含“1”的字段标记为“活动”。

str(function(argument))

它喜欢:

try:
print(x)
except TypeError:
print("Variable x is not defined")
except:
print("Something else went wrong")

这就是您可以通过替换传递变量的全部内容。

我不认为它会像您想要的那样完美运行?但根据wholeblog 必须理解整个代码。

如果 if 和 else 语句有效,那么它们会传递一些结果。

谢谢。