【问题标题】:UnicodeEncodeError when trying to insert UTF-8 data into Mysql尝试将 UTF-8 数据插入 Mysql 时出现 UnicodeEncodeError
【发布时间】:2015-09-23 20:58:17
【问题描述】:

我正在尝试为一个学校项目创建一个新闻应用程序,在该应用程序中我从当地报纸的 RSS 提要中获取信息,以便将多份报纸合并为一份。

当我尝试将收集到的数据插入 Mysql 数据库时遇到问题。

当我简单地打印我的日期时(例如:print urlnzz.entries[0].description),德语字符如 ü ä ö é à 没有问题。

当我尝试将数据插入 Mysql 数据库时,我得到"UnicodeEncodeError: 'ascii' codec can't encode character.."。奇怪的是,这只发生在 .title 和 .description 上,而不是 .category (即使那里也有 ü 等)

我一直在寻找答案已经有一段时间了,我用

更改了变量的编码
t = urlbernerz.entries[i].title


print t.encode('utf-8')

当我连接到数据库时将字符集更改为utf-8,甚至尝试了python的“try / except”功能,但似乎没有任何效果。

我已经用 type(u['entries'].title) 检查了每个条目的类型,它们都是 unicode,现在我需要以一种可以将它们放入我的 mysql 数据库的方式对它们进行编码

在 rss 网站上,它声明它已经编码为 utf-8,即使我明确告诉 python 也将其编码为 utf-8,它仍然给我错误:'ascii' codec can't encode字符 u'\xf6'

我已经尝试了很多关于这个主题的答案,例如使用 str() 或使用 chardet,但似乎没有任何效果。这是我的代码

import MySQLdb
import feedparser
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

db = MySQLdb.connect(host="127.0.0.1", 
                     user="root",
                      passwd="",
                      db="FeedStuff",
                     charset='UTF8')
db.charset="utf8"
cur = db.cursor()




urllistnzz =['international', 'wirtschaft', 'sport']
urllistbernerz =['kultur', 'wissen', 'leben']


for u in range (len(urllistbernerz)):
    urlbernerz = feedparser.parse('http://www.bernerzeitung.ch/'+urllistbernerz[u]+'/rss.html')
    k = len(urlbernerz['entries'])
    for i in range (k):
        cur.execute("INSERT INTO articles (title, description, date, category, link, source) VALUES (' "+ str(urlbernerz.entries[i].title)+"  ', ' " + str(urlbernerz.entries[i].description)+ " ', ' " + urlbernerz.entries[i].published + " ', ' " + urlbernerz.entries[i].category + " ', ' " + urlbernerz.entries[i].link + " ',' Berner Zeitung')")

for a in range (len(urllistnzz)):
    urlnzz = feedparser.parse('http://www.nzz.ch/'+urllistnzz[a]+'.rss')
    k = len(urlnzz['entries'])
    for i in range (k):
        cur.execute("INSERT INTO articles (title, description, date, category, link, source) VALUES (' "+str(urlnzz.entries[i].title)+" ', ' " + str(urlnzz.entries[i].description)+ " ', ' " + urlnzz.entries[i].published + " ', ' " + urlnzz.entries[i].category + " ', ' " + urlnzz.entries[i].link + " ', 'NZZ')")



db.commit()

cur.close()
db.close()

【问题讨论】:

  • 不相关:不要在脚本中硬编码外部环境(终端)的编码,而是打印 Unicode:print t
  • 你试过use_unicode=Trueconnect()参数吗?同样,不要编码,传递 Unicode 字符串——让 db 驱动程序使用正确的编码(前面通过 charset 参数指定)进行编码。
  • 不相关:不要使用字符串格式插入 sql 值,而是使用参数化查询。

标签: python mysql utf-8 character-encoding rss


【解决方案1】:

RSS 提要的文本中可能存在其他编码的字符。 首先,您可以在嵌套的 try except 块中尝试不同的编码。其次,您可以在编码方法中添加“忽略”。喜欢:

try:
    s = raw_s.encode('utf-8', 'ignore')
except UnicodeEncodeError:
    try:
        s = raw_s.encode('latin-1', 'ignore')
    except UnicodeEncodeError:
        print raw_s

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    主要问题是您在 Unicode 对象上调用 str()。取决于许多因素,这可能会导致 Python 尝试将 Unicode 编码为 ASCII,而这对于非 ASCII 字符是不可能的。

    您应该尝试在代码中尽可能长时间地将 Unicode 对象保留为 Unicode 对象,并且仅在完全必要时进行转换。幸运的是,MySQL 驱动程序是 Unicode 兼容的,因此您可以将 Unicode 字符串传递给它,它会在内部进行编码。您唯一需要做的就是告诉驱动程序使用 UTF-8。 Feedparser 也是 Unicode 兼容的,它会自动将 rss 提要解码为 Unicode 字符串(没有编码的字符串)。

    您的代码的某些部分也将受益于使用 Python 的内置功能,例如 for each in something:String.format() 和长文本的三引号 (""")。

    把这一切放在一起看起来像:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    
    import MySQLdb
    import feedparser
    
    db = MySQLdb.connect(host="127.0.0.1",
                         user="root",
                          passwd="",
                          db="FeedStuff",
                         charset='UTF8')
    
    urllistnzz =['international', 'wirtschaft', 'sport']
    urllistbernerz =['kultur', 'wissen', 'leben']
    
    cur = db.cursor()
    
    for uri in urllistbernerz:
        urlbernerz = feedparser.parse('http://www.bernerzeitung.ch/{uri}/rss.html'.format(uri=uri))
    
        for entry in urlbernerz.entries:
            insert_sql = u"""INSERT INTO articles (title, description, date, category,
                            link, source) VALUES ("{e.title}", "{e.description}",
                            "{e.published}", "{e.category}", "{e.link}", "Berner Zeitung")
                            """.format(e=entry)
    
            cur.execute(insert_sql)
    
    for uri in urllistnzz:
        urlnzz = feedparser.parse('http://www.nzz.ch/{uri}.rss'.format(uri=uri) )
    
        for entry in urlnzz.entries:
            insert_sql = u"""INSERT INTO articles (title, description, date, category,
                            link, source) VALUES ("{e.title}", "{e.description}",
                            "{e.published}", "{e.category}", "{e.link}", "NZZ")
                            """.format(e=entry)
    
            cur.execute(insert_sql)
    
    db.commit()
    
    cur.close()
    db.close()
    

    【讨论】:

    • 这成功了!非常感谢,我必须弄清楚你用“uri”和.format(uri = uri)改变了什么,因为我需要在我的学校工作中记录编码和理论背景,所以我'现在会做一些研究:)
    • 嘿,我刚开始使用它,结果你给我的解决方案不再给我任何错误,但它也没有显示我想要的所有文章.它还混淆了诸如链接之类的东西并弄乱了很多东西,现在我开始在进一步的代码中使用它......你确定这应该工作吗?
    • 是的,这段代码应该可以工作。您必须更具体地说明什么不起作用,并确保不是因为您的第 3 方网站发生了变化。
    • 我在上面的问题中添加了更多细节,评论太大了。即使我将计数器直接放入您建议的代码中,这两个数字也不匹配,而且我在数据库中获得的信息混合真的很奇怪。谢谢你的时间顺便说一句:D
    • 当您遇到此类问题时,您应该尝试调试您的代码。问问自己“我怎么会得到归于错误来源的文章?”。我很快发现我在代码中留下了一个错字——第二次迭代是for entry in urlbernerz.entries: 而不是for entry in urlnzz.entries:。上面的代码现在已修复。了解for x in iteratable 语法是明智的
    【解决方案3】:

    假设cur.execute() 需要一个 utf-8 编码的字符串:当您将它传递给 MySQL 时,您需要将其显式编码为 utf-8,只需执行 str() 将尝试将其编码为 ascii,这将失败并产生您的错误:

       cur.execute("INSERT INTO articles (title, description, date, \
       category, link, source) VALUES ('"+ \
       urlnzz.entries[i].title.encode('utf-8') +" ', ' " + \
       urlnzz.entries[i].description.encode('utf-8') + " ', ' " +  \
       urlnzz.entries[i].published + " ', ' " +  \
       urlnzz.entries[i].category + " ', ' " + urlnzz.entries[i].link + " ', 'NZZ')")
    

    unicode 对象与 utf-8 编码中的 str 不同。 unicode 对象上的 encode 方法将生成一个 utf-8 格式的 str(假设 Python 2)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-10-18
    相关资源
    最近更新 更多