python和scrapy解决了编码问题
我简直搞不懂( 我正在废弃utf-8编码站点的数据,至少它是这么说的: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
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')