python和scrapy编码问题

时间:2014-07-06 08:47:49

标签: python unicode encoding utf-8 scrapy

我简单无法搞清楚! :( 我正在从一个utf-8编码的站点中删除数据,至少它是这样说的:

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

我正在使用XPath selector extract()调用获取常规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):

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

我在输出之前已经将unicode编码为字节字符串:

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

这是我的pipeline.py以及我如何使用它来打开和写入我的cvs:

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

过去10天我一直在阅读关于utf-8,unicode,编码和解码的内容,但似乎我仍然想念这里的东西?! 我感谢任何帮助或建议。

2 个答案:

答案 0 :(得分: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模块自己处理行结尾。

答案 1 :(得分:-1)

您可以使用"忽略"参数:

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

https://docs.python.org/2/howto/unicode.html#the-unicode-type