2012-02-07 18 views
22

Aquí está mi arañascrapy codificación de texto

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 codificarlos a UTF-8. No sé cuál es la mejor manera de hacer esto. Intenté varias maneras sin resultado.

¡Gracias de antemano!

Respuesta

32

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

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

pero creo que se puede esperar otro resultado. Su código devuelve un elemento con todos los resultados de búsqueda. Para devolver los artículos 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 

actualización

JSON exportador escribe símbolos Unicode escaparon (por ejemplo \u03a4) por defecto, porque no todas las corrientes pueden manejar Unicode. Tiene la opción de escribirlos como unicode ensure_ascii=False (ver documentos para json.dumps). Pero no puedo encontrar la forma de pasar esta opción al exportador de feeds estándar.

Por lo tanto, si desea que los artículos exportados se escriban en la codificación utf-8, p. para leerlos en el editor de texto, puede escribir la canalización de elementos personalizados.

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 se olvide de añadir este gasoducto para settings.py:

ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline'] 

Puede personalizar tubería para escribir datos en formato legible más humano, por ejemplo, puedes generar algún informe formateado. JsonWithEncodingPipeline es solo un ejemplo básico.

+0

He hecho lo que he escrito, pero sigo teniendo los mismos resultados: caracteres Unicode. La única forma de obtener utf-8 es usar print vrisko ['eponimia'] en lugar de yield o return. – mindcast

+0

@mindcast, ¿Dónde lo obtuviste? ¿Qué hace con los artículos (guardar en json feed, csv feed o tal vez tubería personalizada)? – reclosedev

+0

scrapy crawl vrisko -o scraped_data.json -t json o incluso scrapy crawl vrisko y vea los resultados en mi pantalla. Sé que extraño algo, pero no puedo entenderlo. Gracias por su esfuerzo. – mindcast

4

Tuve un gran problema debido a la codificación con python y scrapy. Para asegúrese de evitar todos los problemas de codificación decodificación, lo mejor que puede hacer es escribir:

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

me parece una forma sencilla de hacer eso. Se guarda los datos JSON para '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 
0

Como se mencionó anteriormente, JSON exportador escribe símbolos Unicode escapado y tiene la opción de escribir como Unicode ensure_ascii=False.

Para exportar elementos a la codificación UTF-8 se puede añadir este archivo a su proyecto de 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', 
} 

A continuación, ejecute:

scrapy crawl spider_name -o output.jl 
3

respuesta correcta es Lacek respuesta, añadir a su configuración:

FEED_EXPORT_ENCODING = 'utf-8'

y vuelve a intentarlo, que funciona para mí.

0

Trate de añadir la siguiente línea en el fichero de configuración para Scrapy (es decir settings.py):

FEED_EXPORT_ENCODING = 'utf-8' 
Cuestiones relacionadas