python和scrapy解决了编码问题

python和scrapy解决了编码问题,python,unicode,encoding,utf-8,scrapy,Python,Unicode,Encoding,Utf 8,Scrapy,我简直搞不懂( 我正在废弃utf-8编码站点的数据,至少它是这么说的: Content-Type: text/html;charset=utf-8 我通过XPath选择器extract()调用获得了常规unicode字符串的列表: 名单如下: [u'Westbahnhofstr.\xa010', u'72070\xa0T\xfcbingen'] 现在,我将列表合并为一个unicode字符串: item['city']= "".join(element.select('//div[@id="b

我简直搞不懂( 我正在废弃utf-8编码站点的数据,至少它是这么说的:

Content-Type: text/html;charset=utf-8
我通过XPath选择器extract()调用获得了常规unicode字符串的列表:

名单如下:

[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字符串输出到屏幕(打印)或文件(写入)时出现问题。无论我尝试什么,它都会返回一个错误():

当然,在输出之前,我已经将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、编码和解码的书,但似乎我还是错过了一些东西?!
非常感谢您的帮助或建议。

您忽略了
.encode()
调用的结果:

item['city'].encode('utf-8')
字符串是不可变的,并且没有进行适当编码。更好的是,返回对象的类型不同。您需要重新分配返回值:

item['city'] = item['city'].encode('utf-8')
但是,您不应该对CSV文件使用
codecs.open()
CSV
模块将始终按TestRing而不是Unicode写入

通过使用
codecodes.open()
文件对象,隐式解码将返回到Unicode,这对您来说是失败的;这就是为什么会出现
UnicodeCodeError
异常,而不是编码错误:

  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模块本身处理行尾。

您可以使用“忽略”参数:

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

很抱歉,不知何故,我的代码遗漏了这一点,它已经就位了……我正在编辑我的帖子。感谢您的回复。@mrki:对,这是因为您使用的是
codecs.open()
;我遗漏了这一点。下次,在您的问题中包含回溯将非常有帮助!:-)我真的没有从错误回溯中看到这一点:(你现在救了我的命:)我一直在用open()调用我以前的爬虫程序。这次我真的认为我需要一个utf-8文件来存储字节字符串而不是unicode字符串的详细信息。但是如果我可以选择简单编码,如果我需要打开我的文件进行手动编辑,为什么我现在需要它呢?真是一团糟!虽然这对我来说是一个非常好的经验!谢谢Martijn!utf-8可以处理所有的U尼科德代码点;这里没有什么可以忽略的。
self.modelsCsv = csv.writer(open('Dees.csv', mode='wb'))
item['city'].encode('utf-8', 'ignore')