8文本

roqulrg3  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(304)

我是个新手。所以我尝试解析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文本。谢谢

3wabscal

3wabscal1#

而不是á 我得到xc3xa1
也就是说问题出在将数据插入数据库上。回到那个代码,我们来讨论一下。
(这可能是 \xc3\xa1 ,但反斜杠在某处消失了。) C3A1 是的utf-8编码的十六进制 á .
您可以通过获取字符串长度来进行双重检查——字符串长度应为1(字符)或2(字节) á ,但显然是8 \xc3\xa1 .

qvtsj1bj

qvtsj1bj2#

问题是,您将字符串显式编码为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'"

你想要的是第一个。
一般来说,打电话 strbytes 几乎没有用。如果你不可避免地 bytes 你需要一个 str ,你可以打电话给 decode 方法。但在这种情况下,你不会不可避免地有 bytes . (我是说,你可以写 row[3].encode("utf-8").decode("utf-8") ,但这显然是相当愚蠢的。)
作为一个旁注,但一个非常重要的一个你不应该试图 str.format 将值转换为sql字符串。只需使用查询参数。下面是解释安全问题的强制性xkcd链接,除此之外,您的代码变得更加复杂,甚至效率更低。
换言之,与其这样做:

"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 . 引用的东西既不是必要的,也不是一个好主意(除非你有一些其他的,应用程序特定的原因,你需要避免) " 文章中的字符),而编码的东西并没有解决任何问题,只会引起一个新的问题。

相关问题