2014-07-06 108 views
5

我簡單搞不明白! :( 我從一個UTF-8編碼的網站報廢的數據,以及至少是它說:python and scrapy THE編碼問題

Content-Type: text/html;charset=utf-8 

我正在使用XPath選擇提取定期Unicode字符串()的列表調用:

item['city']= element.select('//div[@id="bubble_2"]/div/text()').extract() 

這是列表:

[u'Westbahnhofstr.\xa010', u'72070\xa0T\xfcbingen'] 

現在我加入列表成一個unicode字符串:

item['city']= "".join(element.select('//div[@id="bubble_2"]/div/text()').extract()) 

到目前爲止好:

u'Beim Nonnenhaus\xa0672070\xa0T\xfcbingen' 

,而我試圖輸出這個unicode字符串要麼屏幕(打印)或文件(寫)出現的問題。無論我嘗試它返回一個錯誤(http://pastebin.com/51DkX2R2):

item['city'].encode('utf-8') 

這是我pipeline.py以及如何我用開:

exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 11: ordinal not in range(128) 

我當然有輸出之前編碼的Unicode到字節串寫信給我的簡歷:

import csv 
import items 
import urlparse 
import codecs 

class DepostPipeline(object): 
    def __init__(self): 
     self.modelsCsv = csv.writer(codecs.open('Dees.csv', mode='w',encoding='utf-8')) 
     self.modelsCsv.writerow(['city']) 

def process_item(self, item, spider): 
    if isinstance(item, items.DetailsItem): 
     item['city'] = item['city'].encode('utf-8') 

     self.modelsCsv.writerow([item['city']]) 
     return item 

最奇怪的是,我的系統(在Windows上的Python)處理Unicode字符串完美:

C:\Console2>python 
Python 2.7.6 (default, Nov 10 2013, 19:24:18) [MSC v.1500 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> s=u'Beim Nonnenhaus\xa0672070\xa0T\xfcbingen' 
>>> print s 
Beim Nonnenhaus 672070 Tübingen 

我一直在閱讀關於utf-8,unicode,編碼和解碼在過去10天很多,但似乎我仍然錯過了這裏的東西?! 我感謝任何幫助或建議。

回答

7

你忽略了.encode()調用的結果:

item['city'].encode('utf-8') 

字符串是不可改變的,而且就地沒有編碼。更好的是,返回對象的類型是不同的。你需要的返回值分配回:

item['city'] = item['city'].encode('utf-8') 

但是,你應該使用codecs.open() CSV文件。 csv模塊將始終寫入字節串,而不是Unicode。

通過使用codecs.open()文件對象,一個隱含的解碼發生回去爲Unicode,這是爲你失敗;這就是爲什麼你會得到一個UnicodeDecodeError例外,而不是一個編碼錯誤:

File "C:\Python27\lib\codecs.py", line 351, in write 
    data, consumed = self.encode(object, self.errors) 
exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 11: ordinal not in range(128) 

使用常規open()調用來代替:

self.modelsCsv = csv.writer(open('Dees.csv', mode='wb')) 

'wb'; csv模塊本身處理行結束符。

+0

對不起,不知何故,我錯過了,從我的代碼,它已經在的地方...我編輯我的職務。感謝您的迴應。 – mrki

+0

完整的錯誤日誌:http://pastebin.com/51DkX2R2 – mrki

+0

@mrki:對,這是因爲你正在使用'codecs.open()';我錯過了。下一次,包括回溯在你的問題將是非常有益的! :-) –