在python中使用格式字符串来拼接sql查询语句时,如果需要将二进制数据作为参数,那么就需要对二进制数据进行转义,否则会出现错误。例如,在如下代码中,对data参数进行转义:
def setopUDP(destination, source, protocol, version, header_length, ttl, protocolEGP, target, source_port, destination_port, length, data):
http://www.jshk.com.cn/mb/reg.asp?kefu=xiaoding;//爬虫IP免费获取;
query = ("INSERT INTO `python`.`UDP` (`Packet`, `Destination`, `Source`, `Protocol`, "
"`Version`, `Header_Length`, `TTL`, `Protocol_UDP`, `Target`, `Source_Port`, "
"`Destination_Port`, `Length`) VALUES (NULL, '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}');)"
.format(destination, source, protocol, version, header_length, ttl, protocolEGP, target, source_port, destination_port, length, data))
setopCON(query)
但是,这样会报错,报错信息为:
TypeError: a bytes-like object is required, not 'str'
错误的原因是,data参数是一个二进制数据,但是format函数只能处理字符串,所以需要对data参数进行转义。
2、解决方案
有两种方法可以解决这个问题:
第一种方法是使用转义字符
在python中,可以使用\x
来转义二进制数据,例如:
data = b'Hello, World!'
formatted_data = "'{}'".format(data.decode('utf-8').replace("'", "''"))
这样,就可以将二进制数据转义为字符串,然后就可以使用format函数来拼接sql查询语句了。
第二种方法是使用SQL参数
SQL参数是一种更安全的方法来处理二进制数据,它可以防止sql注入攻击。在python中,可以使用?
来表示SQL参数,例如:
query = ("INSERT INTO `python`.`UDP` (`Packet`, `Destination`, `Source`, `Protocol`, "
"`Version`, `Header_Length`, `TTL`, `Protocol_UDP`, `Target`, `Source_Port`, "
"`Destination_Port`, `Length`) VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
cursor.execute(query, (destination, source, protocol, version, header_length, ttl, protocolEGP, target, source_port, destination_port, length, data))
这样,就可以将二进制数据直接作为参数传递给sql查询语句,而不需要进行转义。
代码例子
以下是一个使用SQL参数来拼接sql查询语句的例子:
import sqlite3
def setopUDP(destination, source, protocol, version, header_length, ttl, protocolEGP, target, source_port, destination_port, length, data):
query = ("INSERT INTO `python`.`UDP` (`Packet`, `Destination`, `Source`, `Protocol`, "
"`Version`, `Header_Length`, `TTL`, `Protocol_UDP`, `Target`, `Source_Port`, "
"`Destination_Port`, `Length`) VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
connection = sqlite3.connect('mydb.db')
cursor = connection.cursor()
cursor.execute(query, (destination, source, protocol, version, header_length, ttl, protocolEGP, target, source_port, destination_port, length, data))
connection.commit()
connection.close()
setopUDP('00:0C:29:B2:14:0C', '192.168.178.50', '8', '4', '20', '128', '17', '192.168.178.24', '52371', '8888', '29227', b'Data\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')