如何使用python3避免MySQL中的b'和UTF8文本

2024-09-30 05:24:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我是个新手。所以我尝试解析html页面并将内容放在MySQL中的一列中,但是我似乎无法得到实际的外来字符,比如我得到的是xc3xa1。我的表有utf8mb4作为它的字符集和排序规则utf8mb4\u unicode\u ci。我有以下设置:

Database_cnx = pymysql.connect(user='XXXX', password='XXXX',
                              host='XXXX',
                              database='XXXX',
                              use_unicode=True,
                              charset='utf8mb4')

article_content = str(row[3].encode("utf-8")).replace("'", "\'").replace("\"", "\'")

q_i = ("INSERT INTO article_items (" + ", ".join(article_table_col_name_new) + ")"
"VALUES ({:d}, \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\")".format(row[0], urlparse(row[1]).netloc, row[1], row[2].replace("\"", "'"), article_content, datetime.fromtimestamp(row[4]).strftime("%Y-%m-%d"), updated)
)

所以我怎么能让它只在我的列中显示实际的文章内容,而不是b'字节和utf-8文本。谢谢


Tags: 内容htmlarticlemysqlunicode页面content字符
2条回答

问题是,您将字符串显式编码为UTF-8字节,然后将该UTF-8字节转换为其字符串表示形式。你知道吗

这就是代码的含义:

str(row[3].encode("utf-8"))

如果你不想那么做,就别那么做:

row[3]

下面是一个示例,展示了您正在做的事情:

>>> s = 'à'
>>> s
'à'
>>> s.encode('utf-8')
b'\xc3\xa0'
>>> str(s.encode('utf-8'))
"b'\\xc3\\xa0'"

你想要的是第一个。你知道吗

一般来说,在bytes上调用str几乎没有用。如果不可避免地有一个bytes并且需要一个str,那么可以通过调用decode方法来获得它。但在这种情况下,您不必有bytes。(我的意思是,你可以写row[3].encode("utf-8").decode("utf-8"),但那显然是相当愚蠢的。)


作为旁注,但非常重要的一点是,您不应该试图将值str.format放入SQL字符串中。只需使用查询参数。Here's the obligatory xkcd link这就解释了安全问题,除此之外,您的代码变得更加复杂,甚至效率更低。你知道吗

换言之,与其这样做:

"VALUES ({:d}, \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\", \"{:s}\")".format(row[0], urlparse(row[1]).netloc, row[1], row[2].replace("\"", "'"), article_content, datetime.fromtimestamp(row[4]).strftime("%Y-%m-%d"), updated)

…就这么做:

"VALUES (%s, %s, %s, %s, %s, %s, %s)"

然后,当您稍后执行查询时,传递参数,而无需将所有复杂的转换为字符串、引用和替换嵌入的引号,只需将值作为参数传递给execute。你知道吗

db.execute(q_i, (
    row[0], urlparse(row[i]).netloc, row[1], row[2], article_content, 
    datetime.fromtimestamp(row[4]).strftime("%Y-%m-%d"), updated))

事实上,如果你的下一个列是或可能是一个DATETIME列而不是CHAR/VARCHAR/TEXT/随便什么,你甚至不需要那个strftime;只需传递datetime对象。你知道吗

注意,这意味着您根本不需要对article_content做任何事情。引用内容既不是必要的,也不是一个好主意(除非您有其他特定于应用程序的原因需要避免在文章中使用"字符),而且编码内容并不能解决任何问题,只会导致一个新的问题。你知道吗

instead of á I get xc3xa1

也就是说问题出在将数据插入数据库上。回到那个代码,我们来讨论一下。你知道吗

(这可能是\xc3\xa1,但是反斜杠丢失了。)C3A1á的UTF-8编码的十六进制。你知道吗

您可以通过获取字符串长度来进行双重检查,á的字符串长度应为1(字符)或2(字节),但显然,\xc3\xa1的字符串长度应为8。你知道吗

相关问题 更多 >

    热门问题