web-dev-qa-db-fra.com

encodage de texte rugueux

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 quelle est la meilleure façon de procéder. J'ai essayé plusieurs façons sans résultat.

Merci d'avance!

29
mindcast

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 la 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

L'exportateur JSON écrit des symboles Unicode échappés (par exemple \u03a4) par défaut, car tous les flux ne peuvent pas gérer unicode. Il a la possibilité de les écrire en unicode ensure_ascii=False (voir les documents pour json.dumps ). Mais je ne trouve pas de moyen de passer cette option à l'exportateur de flux standard.

Donc, si vous souhaitez que les éléments exportés soient écrits en utf-8 codage, par exemple pour les lire dans l'éditeur de texte, vous pouvez écrire un pipeline d'éléments personnalisés.

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 exemple vous pouvez générer un rapport formaté. JsonWithEncodingPipeline n'est qu'un exemple basique.

35
reclosedev

Depuis Scrapy 1.2.0, n nouveau paramètre FEED_EXPORT_ENCODING est introduit . En le spécifiant comme utf-8, La sortie JSON ne sera pas échappée.

C'est d'ajouter dans votre settings.py:

FEED_EXPORT_ENCODING = 'utf-8'
58
Lacek

J'ai eu beaucoup de problèmes en raison de l'encodage avec python et scrapy. Pour être sûr d'éviter tous les problèmes de décodage de l'encodage, la meilleure chose à faire est d'écrire:

unicode(response.body.decode(response.encoding)).encode('utf-8')
4
mikeulkeul

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

FEED_EXPORT_ENCODING = 'utf-8'
2
FreeCat

Je trouve un moyen simple de le faire. Il enregistre les données json dans '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
Guan-Ming Huang

Comme mentionné précédemment, l'exportateur JSON écrit les symboles unicode échappés et il a la possibilité de les écrire en unicode ensure_ascii=False.

Pour exporter des éléments en encodage utf-8, vous pouvez l'ajouter 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',
}

Exécutez ensuite:

scrapy crawl spider_name -o output.jl
0
banzayats