codage de texte scrapy
Voici mon araignée
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
Mon problème est que les chaînes retournées sont unicode et je veux les encoder en utf-8. Je ne sais pas qui est le meilleur moyen pour ce faire. J'ai essayé plusieurs façons sans résultat.
Merci d'avance!
7 réponses
Scrapy renvoie des chaînes en unicode, pas en ascii. Pour encoder toutes les chaînes en utf-8, Vous pouvez écrire:
vriskoit['eponimia'] = [s.encode('utf-8') for s in hxs.select('//a[@itemprop="name"]/text()').extract()]
Mais je pense que vous attendez un autre résultat. Votre code renvoie un élément avec tous les résultats de recherche. Pour renvoyer des articles pour chaque résultat:
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
Mise à Jour
JSON exporter écrit les symboles unicode échappés (par exemple \u03a4
) par défaut, car tous les flux ne peuvent pas gérer unicode. Il a l'option de les écrire en unicode ensure_ascii=False
(voir docs pour json.vidages ). Mais je ne trouve pas le moyen de passer cette option à l'exportateur d'aliments standard.
Donc, si vous voulez que les éléments exportés soient écrits en encodage utf-8
, par exemple pour les lire dans l'éditeur de texte, vous pouvez écrire un pipeline d'éléments personnalisé.
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()
N'oubliez pas d'ajouter ce pipeline à settings.py:
ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline']
Vous pouvez personnaliser le pipeline pour écrire des données dans un format plus lisible par l'homme, par exemple, vous pouvez générer un rapport formaté. JsonWithEncodingPipeline
est juste basique exemple.
Depuis Scrapy 1.2.0, un nouveau paramètre FEED_EXPORT_ENCODING
est introduit. En le spécifiant comme utf-8
, la sortie JSON ne sera pas échappée.
, ce Qui est à ajouter dans votre settings.py
:
FEED_EXPORT_ENCODING = 'utf-8'
J'ai eu beaucoup de problème en raison de l'encodage avec python et scrapy. Pour être sûr d'éviter chaque encodage décodage des problèmes, la meilleure chose à faire est d'écrire :
unicode(response.body.decode(response.encoding)).encode('utf-8')
Je trouve un moyen simple de le faire. Il enregistre les données json à 'SpiderName'.json avec 'utf8'
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
Comme mentionné précédemment, JSON exporter écrit des symboles unicode échappés et il a la possibilité de les écrire comme unicode ensure_ascii=False
.
Pour exporter des éléments en encodage utf-8, Vous pouvez ajouter ceci au fichier settings.py
de votre projet:
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',
}
Puis exécutez:
scrapy crawl spider_name -o output.jl
Essayez d'ajouter la ligne suivante au fichier de configuration pour Scrapy (c'est-à-dire settings.py):
FEED_EXPORT_ENCODING = 'utf-8'