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!

24
demandé sur mindcast 2012-02-07 21:51:50

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.

33
répondu reclosedev 2012-02-09 15:40:57

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'
40
répondu Lacek 2016-12-27 13:40:20

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')
4
répondu mikeulkeul 2017-03-20 11:47:27

Réponse Correcte est Lacek réponse, ajouter à vos paramètres:

FEED_EXPORT_ENCODING = 'utf-8'

Et essayez à nouveau, fonctionne pour moi.

3
répondu 2017-01-26 16:32:49

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
1
répondu Guan-Ming Huang 2016-10-16 15:33:00

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
0
répondu banzayats 2016-11-04 07:01:06

Essayez d'ajouter la ligne suivante au fichier de configuration pour Scrapy (c'est-à-dire settings.py):

FEED_EXPORT_ENCODING = 'utf-8'
0
répondu FreeCat 2017-07-06 08:28:49