2015-09-23 86 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 

希望這會有所幫助。

相關問題