codificación de texto scrapy


Aquí está mi araña

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

Mi problema es que las cadenas devueltas son unicode y quiero codificarlas en utf-8. No sé cuál es la mejor manera de hacer esto. Probé varias maneras sin resultado.

Gracias de antemano!

 24
Author: mindcast, 2012-02-07

7 answers

Scrapy devuelve cadenas en unicode, no ascii. Para codificar todas las cadenas a utf-8, puede escribir:

vriskoit['eponimia'] = [s.encode('utf-8') for s in hxs.select('//a[@itemprop="name"]/text()').extract()]

Pero creo que esperas otro resultado. Su código devuelve un elemento con todos los resultados de búsqueda. Para devolver elementos para cada resultado:

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

Update

JSON exporter escribe símbolos unicode escapados (por ejemplo, \u03a4) de forma predeterminada, porque no todos los flujos pueden manejar unicode. Tiene la opción de escribirlos como unicode ensure_ascii=False (ver documentos para json.dumps ). Pero no puedo encontrar la manera de pasar esta opción al exportador de alimentación estándar.

Así que si desea que los elementos exportados se escriban en codificación utf-8, por ejemplo, para leerlos en el editor de texto, puede escribir una canalización de elementos personalizada.

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()

No olvides agregar esta canalización a settings.py:

 ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline']

Puede personalizar la canalización para escribir datos en un formato más legible por humanos, por ejemplo, puede generar algún informe formateado. JsonWithEncodingPipeline es solo básico ejemplo.

 33
Author: reclosedev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-09 15:40:57

Desde Scrapy 1.2.0, se introduce un nuevo ajuste FEED_EXPORT_ENCODING . Al especificarlo como utf-8, la salida JSON no se escapará.

Que es añadir en su settings.py:

FEED_EXPORT_ENCODING = 'utf-8'
 40
Author: Lacek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 13:40:20

Tuve muchos problemas debido a la codificación con python y scrapy. Para asegurarse de evitar todos los problemas de decodificación de codificación, lo mejor que puede hacer es escribir:

unicode(response.body.decode(response.encoding)).encode('utf-8')
 4
Author: mikeulkeul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-20 11:47:27

La respuesta correcta es la respuesta de Lacek, agregue a su configuración:

FEED_EXPORT_ENCODING = 'utf-8'

E inténtalo de nuevo, funciona para mí.

 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-26 16:32:49

Encuentro una manera sencilla de hacerlo. Guarda los datos json en 'SpiderName'.json con "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
Author: Guan-Ming Huang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-16 15:33:00

Como se mencionó anteriormente, JSON exporter escribe símbolos unicode escapados y tiene la opción de escribirlos como unicode ensure_ascii=False.

Para exportar elementos en codificación utf-8, puede agregar esto al archivo settings.py de su proyecto:

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',
}

Luego ejecute:

scrapy crawl spider_name -o output.jl
 0
Author: banzayats,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-04 07:01:06

Intente agregar la siguiente línea al archivo de configuración de Scrapy (es decir, settings.py):

FEED_EXPORT_ENCODING = 'utf-8'
 0
Author: FreeCat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 08:28:49