2015-09-23 44 views
2

我试图为学校项目创建一个新闻应用程序,我从当地报纸的RSS源获取信息,以便将多个报纸合并为一个。尝试向数据库中插入UTF-8数据时出现UnicodeEncodeError

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

当我简单地打印日期(例如:打印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,当我连接到数据库,甚至试图蟒蛇的“试/除外”的功能,但似乎没有任何工作。

我已经签有型(U [“项”。标题)每个条目的类型,他们都是unicode的,现在我需要它们编码的方式,我可以把它们放到我的mysqldatabase

它在rss网站上声明它已经被编码为utf-8,即使我明确地告诉python将它编码为utf-8,它仍然给我错误:'ascii'编解码器不能编码字符我'已经尝试了很多对这个问题的答案,如使用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() 
+0

无关:不要硬编码的脚本中外部环境(终端),打印的Unicode编码来代替:'打印t' – jfs

+0

你试过'use_unicode =真正的connect()参数?同样,不要编码,传递Unicode字符串 - 让数据库驱动程序使用正确的编码进行编码(通过前面的charset参数指定)。 – jfs

+0

无关:不要使用字符串格式来插入sql值,而是使用参数化查询。 – jfs

回答

0

主要问题是您在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() 
+0

这工作!非常感谢,我必须弄清楚你用“uri”和.format(uri = uri)改变了什么,因为我需要在我的学校工作中记录编码和理论背景,我现在做一些研究:) – Sascha

+0

嘿,我只是不得不开始使用它,事实证明,你给我的解决方案不会再给我任何错误,但它也不会显示我想要的所有文章。它也混淆了诸如链接之类的东西,并混淆了很多东西,现在我开始在更多的代码中使用它......你确定这应该起作用吗? – Sascha

+0

是的,这段代码应该可以工作。你必须更具体地说明什么是不工作,并确保它不是因为你的第三方网站已经改变。 –

0

假设cur.execute()需要一个UTF-8编码的字符串:你需要的时候,你把它传递给MySQL的,只是在做STR(将其编码为UTF-8明确)将试图对其进行编码为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编码海峡明显。 unicode对象上的编码方法将生成一个utf-8格式的str(假设Python 2)

+1

这是错误的。您应该将Unicode字符串传递给'.execute()'。驱动程序将在必要时编码:http://stackoverflow.com/a/6203782/1554386 –

0

有可能在RSS提要的文本中存在带有其他编码的字符。 首先,你可以尝试嵌套尝试不同的编码,除了块。其次,你可以添加'忽略'的编码方法。喜欢:

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

希望这会有所帮助。

相关问题