これが私のクモです
from scrapy.contrib.spiders import CrawlSpider,Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from vrisko.items import VriskoItem
class vriskoSpider(CrawlSpider):
name = 'vrisko'
allowed_domains = ['vrisko.gr']
start_urls = ['http://www.vrisko.gr/search/%CE%B3%CE%B9%CE%B1%CF%84%CF%81%CE%BF%CF%82/%CE%BA%CE%BF%CF%81%CE%B4%CE%B5%CE%BB%CE%B9%CE%BF']
rules = (Rule(SgmlLinkExtractor(allow=('\?page=\d')),'parse_start_url',follow=True),)
def parse_start_url(self, response):
hxs = HtmlXPathSelector(response)
vriskoit = VriskoItem()
vriskoit['eponimia'] = hxs.select("//a[@itemprop='name']/text()").extract()
vriskoit['address'] = hxs.select("//div[@class='results_address_class']/text()").extract()
return vriskoit
私の問題は、返された文字列がユニコードであり、utf-8にエンコードしたいということです。私はこれを行うための最良の方法がわからない。結果なしでいくつかの方法を試しました。
前もって感謝します!
Scrapyは、ASCIIではなくUnicodeで文字列を返します。すべての文字列をutf-8にエンコードするには、次のように記述できます。
vriskoit['eponimia'] = [s.encode('utf-8') for s in hxs.select('//a[@itemprop="name"]/text()').extract()]
しかし、あなたは別の結果を期待していると思います。コードは、すべての検索結果を含むoneアイテムを返します。各結果のアイテムを返すには:
hxs = HtmlXPathSelector(response)
for eponimia, address in Zip(hxs.select("//a[@itemprop='name']/text()").extract(),
hxs.select("//div[@class='results_address_class']/text()").extract()):
vriskoit = VriskoItem()
vriskoit['eponimia'] = eponimia.encode('utf-8')
vriskoit['address'] = address.encode('utf-8')
yield vriskoit
更新
JSONエクスポーターは、すべてのストリームがUnicodeを処理できるわけではないため、デフォルトでエスケープされたUnicodeシンボル(たとえば、\u03a4
)を書き込みます。 unicode ensure_ascii=False
( json.dumps のドキュメントを参照)として記述するオプションがあります。しかし、このオプションを標準のフィードエクスポーターに渡す方法が見つかりません。
エクスポートされたアイテムをutf-8
エンコーディングで記述したい場合、例えばテキストエディターで読み込むには、カスタムアイテムパイプラインを記述できます。
pipelines.py:
import json
import codecs
class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = codecs.open('scraped_data_utf8.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
このパイプラインをsettings.pyに追加することを忘れないでください:
ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline']
パイプラインをカスタマイズして、人間が読める形式でデータを書き込むことができます。書式設定されたレポートを生成できます。 JsonWithEncodingPipeline
は基本的な例です。
Scrapy 1.2.0以降、 新しい設定FEED_EXPORT_ENCODING
が導入されました 。 utf-8
として指定することにより、JSON出力はエスケープされません。
それはあなたのsettings.py
を追加することです:
FEED_EXPORT_ENCODING = 'utf-8'
pythonとスクレイピーでエンコードするために多くの問題がありました。すべてのエンコードデコードの問題を確実に回避するために、最善のことは書くことです:
unicode(response.body.decode(response.encoding)).encode('utf-8')
Scrapyの設定ファイルに次の行を追加してみてください(つまりsettings.py):
FEED_EXPORT_ENCODING = 'utf-8'
簡単な方法を見つけました。 JSONデータを 'utf8'で 'SpiderName'.jsonに保存します
from scrapy.exporters import JsonItemExporter
class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = open(spider.name + '.json', 'wb')
self.exporter = JsonItemExporter(self.file, encoding='utf-8', ensure_ascii=False)
self.exporter.start_exporting()
def spider_closed(self, spider):
self.exporter.finish_exporting()
self.file.close()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
前述のように、JSONエクスポーターはエスケープされたUnicodeシンボルを書き込み、Unicode ensure_ascii=False
。
Utf-8エンコーディングでアイテムをエクスポートするには、これをプロジェクトのsettings.py
ファイル:
from scrapy.exporters import JsonLinesItemExporter
class MyJsonLinesItemExporter(JsonLinesItemExporter):
def __init__(self, file, **kwargs):
super(MyJsonLinesItemExporter, self).__init__(file, ensure_ascii=False, **kwargs)
FEED_EXPORTERS = {
'jsonlines': 'yourproject.settings.MyJsonLinesItemExporter',
'jl': 'yourproject.settings.MyJsonLinesItemExporter',
}
次に実行します:
scrapy crawl spider_name -o output.jl