【问题标题】:python and scrapy THE encoding issuepython和scrapy编码问题
【发布时间】:2014-07-06 08:47:48
【问题描述】:

我简直想不通! :( 我正在从一个 utf-8 编码的网站上抓取数据,至少它是这么说的:

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

我正在使用 XPath 选择器 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、编码和解码的大量内容,但似乎我仍然错过了什么?! 感谢您提供任何帮助或建议。

【问题讨论】:

    标签: python unicode encoding utf-8 scrapy


    【解决方案1】:

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

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

    字符串是不可变的,并且不是就地编码的。更好的是,返回对象的类型是不同的。您需要重新分配返回值:

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

    但是,对于 CSV 文件,您应该使用 codecs.open()csv 模块将始终写入字节串,而不是 Unicode。

    通过使用codecs.open() 文件对象,一个隐含的decode 发生以返回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 模块自己处理行尾。

    【讨论】:

    • 抱歉,不知何故我从我的代码中遗漏了它,它已经到位......我正在编辑我的帖子。感谢您的回复。
    • @mrki:对,那是因为你使用的是codecs.open();我错过了。下次,在您的问题中包含回溯将非常有帮助! :-)
    • 我真的没有从错误引用中看到这一点 :( 你现在正在救我的命 :) 我一直在我以前的所有爬虫中使用 open() 调用。这次我真的认为我需要一个 utf-8 文件来将详细信息存储为字节字符串而不是 unicode 字符串。但是,如果我需要打开文件进行手动编辑,为什么我现在需要它,如果我可以选择编码。真是一团糟!虽然对我来说是一次非常好的经历!谢谢马丁!
    【解决方案2】:

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

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

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

    【讨论】:

    • UTF-8 可以处理所有个Unicode码点;这里没有什么可以忽略的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多