2015-04-29 61 views
3

我得到这个错误UnicodeEncodeError: 'Latin-1的' 编解码器不能编码字符U '\ u2014'UnicodeEncodeError: 'Latin-1的' 编解码器不能编码字符U ' u2014'

我试图将大量新闻文章加载到MySQLdb中。不过,我在处理非标准字符时遇到了困难,对于各种字符我都会遇到数百个这样的错误。我可以使用.replace()单独处理它们,但我想要一个更完整的解决方案来正确处理它们。

[email protected]:~/scripts/work$ python test_db_load_error.py 
Traceback (most recent call last): 
    File "test_db_load_error.py", line 27, in <module> 
    cursor.execute(sql_load) 
    File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 157, in execute 
    query = query.encode(charset) 
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2014' in position 158: ordinal not in range(256) 

我的脚本;

import MySQLdb as mdb 
from goose import Goose 
import string 
import datetime 

host = 'rds.amazonaws.com' 
user = 'news' 
password = 'xxxxxxx' 
db_name = 'news_reader' 
conn = mdb.connect(host, user, password, db_name) 

url = 'http://www.dailymail.co.uk/wires/ap/article-3060183/Andrew-Lesnie-Lord-Rings-cinematographer-dies.html?ITO=1490&ns_mchannel=rss&ns_campaign=1490' 
g = Goose() 
article = g.extract(url=url) 
body = article.cleaned_text 
body = body.replace("'","`") 
load_date = str(datetime.datetime.now()) 
summary = article.meta_description 
title = article.title 
image = article.top_image 

sql_load = "insert into articles " \ 
     " (title,summary,article,,image,source,load_date) " \ 
     "  values ('%s','%s','%s','%s','%s','%s');" % \ 
     (title,summary,body,image,url,load_date) 
cursor = conn.cursor() 
cursor.execute(sql_load) 
#conn.commit() 

任何帮助,将不胜感激。

+0

正在重新配置你的数据库来存储UTF-8,而不是Latin-1的一个选择吗?它需要对现有数据进行重新编码(数据迁移)。 –

+0

你有什么样的数据库字符编码?你有没有定义它,或者它是MySQL的默认?如果是你有latin1,但也许你需要utf-8取决于你想插入什么 –

+0

你真的应该在这里使用* SQL参数*,而不是使用字符串插值。从'sql_load'行删除'%(....)'并将元组移动到'cursor.execute()'的第二个参数。 'sql_load =“....带有%s占位符的查询字符串...”'和'cursor.execute(sql_load,(title,summary,body,image,url,load_date))''。 –

回答

2

如果你的数据库实际上是配置为Latin-1的,那么你就不能非Latin-1字符存储在它。这包括U+2014, EM DASH

理想的解决方案是切换到为UTF-8配置的数据库。最初创建数据库时以及每次连接时都要通过charset='utf-8'。 (如果你已经有了现有的数据,你可能想用MySQL工具将旧的数据库迁移到新的数据库,而不是Python代码,但基本思想是一样的。)

但是,有时候并不是这样可能。也许你有其他软件无法更新,需要Latin-1,并且需要共享相同的数据库。或者,您可能以无法以编程方式取消混合的方式混合Latin-1文本和二进制数据,或者您的数据库太大而无法迁移等等。在这种情况下,您有两种选择:

  • 在存储和搜索之前将字符串破坏性地转换为Latin-1。例如,您可能需要将em破折号转换为---,或者它可能不是那么重要,您可以将所有非拉丁字符1转换为?(这更快更简单)。

  • 提出一种编码方案,将非拉丁文-1字符走私到数据库中。这意味着一些搜索变得更加复杂,或者只是不能直接在数据库中完成。

+0

如何查找数据库如何以某种方式配置? – Jens

6

当您创建您的mysqldb连接时,将charset='utf8'传递给连接。

conn = mdb.connect(host, user, password, db_name, charset='utf8') 
+1

假设没有任何预先存在的数据,即。否则,您需要在迁移过程中重新编写该数据。 –

+0

默认情况下,[SQLAlchemy](http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#sqlalchemy.create_engine.params.encoding)设置了utf-8。但是,如何确保将其设置为utf-8,或者如何查询现有配置? – Jens

相关问题