【发布时间】:2016-09-19 21:27:59
【问题描述】:
忍受我。我正在写每一个细节,因为工具链的很多部分都不能优雅地处理 Unicode,而且还不清楚是什么失败了。
前奏曲
我们首先设置并使用最近的 Scrapy。
source ~/.scrapy_1.1.2/bin/activate
由于终端默认是ascii,不是unicode,所以我们设置:
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
另外由于默认情况下 Python 使用 ascii,我们修改编码:
export PYTHONIOENCODING="utf_8"
现在我们准备开始一个 Scrapy 项目。
scrapy startproject myproject
cd myproject
scrapy genspider dorf PLACEHOLDER
我们被告知我们现在有一个蜘蛛。
Created spider 'dorf' using template 'basic' in module:
myproject.spiders.dorf
我们将myproject/items.py修改为:
# -*- coding: utf-8 -*-
import scrapy
class MyprojectItem(scrapy.Item):
title = scrapy.Field()
尝试 1
现在我们写spider,依赖urllib.unquote
# -*- coding: utf-8 -*-
import scrapy
import urllib
from myproject.items import MyprojectItem
class DorfSpider(scrapy.Spider):
name = "dorf"
allowed_domains = [u'http://en.sistercity.info/']
start_urls = (
u'http://en.sistercity.info/sister-cities/Düsseldorf.html',
)
def parse(self, response):
item = MyprojectItem()
item['title'] = urllib.unquote(
response.xpath('//title').extract_first().encode('ascii')
).decode('utf8')
return item
最后我们使用custom item exporter(从 2011 年 10 月开始)
# -*- coding: utf-8 -*-
import json
from scrapy.exporters import BaseItemExporter
class UnicodeJsonLinesItemExporter(BaseItemExporter):
def __init__(self, file, **kwargs):
self._configure(kwargs)
self.file = file
self.encoder = json.JSONEncoder(ensure_ascii=False, **kwargs)
def export_item(self, item):
itemdict = dict(self._get_serialized_fields(item))
self.file.write(self.encoder.encode(itemdict) + '\n')
并添加
FEED_EXPORTERS = {
'json': 'myproject.exporters.UnicodeJsonLinesItemExporter',
}
到myproject/settings.py。
现在我们运行
~/myproject> scrapy crawl dorf -o dorf.json -t json
我们得到
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 25: ordinal not in range(128)
尝试 2
另一种解决方案(Scrapy 1.2 的候选解决方案?)是使用蜘蛛
# -*- coding: utf-8 -*-
import scrapy
from myproject.items import MyprojectItem
class DorfSpider(scrapy.Spider):
name = "dorf"
allowed_domains = [u'http://en.sistercity.info/']
start_urls = (
u'http://en.sistercity.info/sister-cities/Düsseldorf.html',
)
def parse(self, response):
item = MyprojectItem()
item['title'] = response.xpath('//title')[0].extract()
return item
# -*- coding: utf-8 -*-
from scrapy.exporters import JsonItemExporter
class Utf8JsonItemExporter(JsonItemExporter):
def __init__(self, file, **kwargs):
super(Utf8JsonItemExporter, self).__init__(
file, ensure_ascii=False, **kwargs)
与
FEED_EXPORTERS = {
'json': 'myproject.exporters.Utf8JsonItemExporter',
}
在myproject/settings.py.
我们得到以下 JSON 文件。
[
{"title": "<title>Sister cities of D\u00fcsseldorf \u2014 sistercity.info</title>"}
]
Unicode 不是 UTF-8 编码的。虽然对于几个字符来说这是一个微不足道的问题,但如果整个输出都是外语,它就会成为一个严重的问题。
如何获得 UTF-8 unicode 格式的输出?
【问题讨论】:
标签: scrapy