2012-02-07 17 views
22

यहाँ मेरी मकड़ी हैscrapy पाठ एन्कोडिंग

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 

मेरे समस्या यह है कि लौटे तार यूनिकोड कर रहे हैं और मैं उन्हें utf-8 के लिए सांकेतिक शब्दों में बदलना चाहते हैं। मुझे नहीं पता कि यह करने का सबसे अच्छा तरीका कौन सा है। मैंने परिणाम के बिना कई तरीकों की कोशिश की।

अग्रिम धन्यवाद!

उत्तर

32

स्केपर यूनिकोड में स्ट्रिंग देता है, न कि एसीआईआई। utf-8 के लिए सभी स्ट्रिंग्स सांकेतिक शब्दों में बदलना करने के लिए, आप लिख सकते हैं:

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

लेकिन मुझे लगता है कि आप किसी अन्य परिणाम की उम्मीद है। आपका कोड सभी खोज परिणामों के साथ एक आइटम लौटाता है। प्रत्येक परिणाम के लिए आइटम लौटने के लिए:

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 

अद्यतन

JSON निर्यातक लिखते यूनिकोड प्रतीकों डिफ़ॉल्ट रूप से (जैसे \u03a4) बच गए, क्योंकि सभी धाराओं यूनिकोड संभाल कर सकते हैं। इसमें उन्हें यूनिकोड ensure_ascii=False के रूप में लिखने का विकल्प है (json.dumps के लिए दस्तावेज़ देखें)। लेकिन मुझे मानक विकल्प निर्यातक को इस विकल्प को पारित करने का तरीका नहीं मिल रहा है।

तो यदि आप utf-8 एन्कोडिंग में निर्यात किए गए आइटमों को लिखना चाहते हैं, उदा। उन्हें टेक्स्ट एडिटर में पढ़ने के लिए, आप कस्टम आइटम पाइपलाइन लिख सकते हैं।

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

settings.py को यह पाइप लाइन को जोड़ने के लिए मत भूलना:

ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline'] 

आप पाइपलाइन अनुकूलित कर सकते हैं और अधिक मानव पठनीय प्रारूप, उदा डेटा लिखने के लिए आप कुछ फॉर्मेटेड रिपोर्ट जेनरेट कर सकते हैं। JsonWithEncodingPipeline सिर्फ मूल उदाहरण है।

+0

मैं तुम्हें क्या लिखा गया है की थी, लेकिन मैं अभी भी एक ही परिणाम प्राप्त: यूनिकोड वर्ण। यूटीएफ -8 प्राप्त करने का एकमात्र तरीका उपज या वापसी के बजाय प्रिंट vrisko ['eponimia'] का उपयोग करना है। – mindcast

+0

@ मिंडकास्ट, आपको यह कहां मिला? आप वस्तुओं के साथ क्या करते हैं (जेसन फ़ीड, सीएसवी फ़ीड, या शायद कस्टम पाइपलाइन को सहेजना)? – reclosedev

+0

स्क्रैप क्रॉल vrisko -o scraped_data.json -t json या यहां तक ​​कि स्केपर क्रॉल vrisko और मेरी स्क्रीन पर परिणाम देखें। मुझे पता है कि मुझे कुछ याद आती है लेकिन मैं इसे समझ नहीं सकता। आपके प्रयास के लिए धन्यवाद। – mindcast

4

मुझे अजगर और स्केपर के साथ एन्कोडिंग के कारण बहुत सी समस्या थी।

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

मुझे लगता है कि ऐसा करने के लिए एक आसान तरीका लगता है: हर एन्कोडिंग डिकोडिंग समस्याओं से बचने के यह सुनिश्चित हो, तो सबसे अच्छा होगा लिखने के लिए है। यह 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

जैसा कि पहले उल्लेख किया गया था' के साथ SpiderName'.json 'के लिए json डेटा बचाता है, JSON निर्यातक लिखते यूनिकोड प्रतीकों से बच गया और यह उन्हें यूनिकोड ensure_ascii=False के रूप में लिखने के लिए विकल्प है।

आप अपने प्रोजेक्ट के settings.py फाइल करने के लिए इस जोड़ सकते हैं एन्कोडिंग utf-8 में आइटम निर्यात करने के लिए:

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

तब चलाएँ:

scrapy crawl spider_name -o output.jl 
34

Scrapy 1.2.0, a new setting FEED_EXPORT_ENCODING is introduced के बाद से। इसे utf-8 के रूप में निर्दिष्ट करके, JSON आउटपुट से बच नहीं पाएगा।

अपने settings.py में जोड़ने के लिए है कि:

FEED_EXPORT_ENCODING = 'utf-8' 
+3

यह सबसे अच्छा है। धन्यवाद :) – Jalal

3

सही जवाब Lacek जवाब है, अपनी सेटिंग्स में जोड़ें:

FEED_EXPORT_ENCODING = 'utf-8'

और पुन: प्रयास करें, मेरे लिए काम करता है। Scrapy के लिए कॉन्फ़िग फ़ाइल में निम्न पंक्ति जोड़कर

0

प्रयास करें (अर्थात settings.py):

FEED_EXPORT_ENCODING = 'utf-8' 
संबंधित मुद्दे