2015-11-04 6 views
7

मैं ब्लॉग स्क्रैप करने के लिए स्केपर का उपयोग कर रहा हूं और फिर डेटा को mongodb में संग्रहीत कर रहा हूं। पहले मुझे अवैध दस्तावेज़ अपवाद मिला। मेरे लिए इतना स्पष्ट है कि डेटा सही एन्कोडिंग में नहीं है। तो ऑब्जेक्ट को बनाए रखने से पहले, मेरी मोंगोपाइपलाइन में मैं जांचता हूं कि दस्तावेज़ 'utf-8 सख्त' में है या नहीं, और केवल तब मैं वस्तु को mongodb पर जारी रखने का प्रयास करता हूं। लेकिन फिर भी मुझे अमान्य डॉक्यूमेंट अपवाद मिलते हैं, अब यह कष्टप्रद है।MongoDB अमान्य दस्तावेज़: ऑब्जेक्ट को एन्कोड नहीं कर सकता

यह मेरा कोड मेरी MongoPipeline वस्तु बनी रहती है कि वस्तुओं

# -*- coding: utf-8 -*- 

# Define your item pipelines here 
# 

import pymongo 
import sys, traceback 
from scrapy.exceptions import DropItem 
from crawler.items import BlogItem, CommentItem 


class MongoPipeline(object): 
    collection_name = 'master' 

    def __init__(self, mongo_uri, mongo_db): 
     self.mongo_uri = mongo_uri 
     self.mongo_db = mongo_db 

    @classmethod 
    def from_crawler(cls, crawler): 
     return cls(
      mongo_uri=crawler.settings.get('MONGO_URI'), 
      mongo_db=crawler.settings.get('MONGO_DATABASE', 'posts') 
     ) 

    def open_spider(self, spider): 
     self.client = pymongo.MongoClient(self.mongo_uri) 
     self.db = self.client[self.mongo_db] 

    def close_spider(self, spider): 
     self.client.close() 

    def process_item(self, item, spider): 

     if type(item) is BlogItem: 
      try: 
       if 'url' in item: 
        item['url'] = item['url'].encode('utf-8', 'strict') 
       if 'domain' in item: 
        item['domain'] = item['domain'].encode('utf-8', 'strict') 
       if 'title' in item: 
        item['title'] = item['title'].encode('utf-8', 'strict') 
       if 'date' in item: 
        item['date'] = item['date'].encode('utf-8', 'strict') 
       if 'content' in item: 
        item['content'] = item['content'].encode('utf-8', 'strict') 
       if 'author' in item: 
        item['author'] = item['author'].encode('utf-8', 'strict') 

      except: # catch *all* exceptions 
       e = sys.exc_info()[0] 
       spider.logger.critical("ERROR ENCODING %s", e) 
       traceback.print_exc(file=sys.stdout) 
       raise DropItem("Error encoding BLOG %s" % item['url']) 

      if 'comments' in item: 
       comments = item['comments'] 
       item['comments'] = [] 

       try: 
        for comment in comments: 
         if 'date' in comment: 
          comment['date'] = comment['date'].encode('utf-8', 'strict') 
         if 'author' in comment: 
          comment['author'] = comment['author'].encode('utf-8', 'strict') 
         if 'content' in comment: 
          comment['content'] = comment['content'].encode('utf-8', 'strict') 

         item['comments'].append(comment) 

       except: # catch *all* exceptions 
        e = sys.exc_info()[0] 
        spider.logger.critical("ERROR ENCODING COMMENT %s", e) 
        traceback.print_exc(file=sys.stdout) 

     self.db[self.collection_name].insert(dict(item)) 

     return item 

और फिर भी MongoDB है मैं मिल निम्न अपवाद:

au coeur de l\u2019explosion de la bulle Internet n\u2019est probablement pas \xe9tranger au succ\xe8s qui a suivi. Mais franchement, c\u2019est un peu court comme argument !Ce que je sais dire, compte tenu de ce qui pr\xe9c\xe8de, c\u2019est quelles sont les conditions pour r\xe9ussir si l\u2019on est vraiment contraint de rester en France. Ce sont des sujets que je d\xe9velopperai dans un autre article.', 
    'date': u'2012-06-27T23:21:25+00:00', 
    'domain': 'reussir-sa-boite.fr', 
    'title': u'Peut-on encore entreprendre en France ?\t\t\t ', 
    'url': 'http://www.reussir-sa-boite.fr/peut-on-encore-entreprendre-en-france/'} 
    Traceback (most recent call last): 
     File "h:\program files\anaconda\lib\site-packages\twisted\internet\defer.py", line 588, in _runCallbacks 
     current.result = callback(current.result, *args, **kw) 
     File "H:\PDS\BNP\crawler\crawler\pipelines.py", line 76, in process_item 
     self.db[self.collection_name].insert(dict(item)) 
     File "h:\program files\anaconda\lib\site-packages\pymongo\collection.py", line 409, in insert 
     gen(), check_keys, self.uuid_subtype, client) 
    InvalidDocument: Cannot encode object: {'author': 'Arnaud Lemasson', 
    'content': 'Tellement vrai\xe2\x80\xa6 Il faut vraiment \xc3\xaatre motiv\xc3\xa9 aujourd\xe2\x80\x99hui pour monter sa bo\xc3\xaete. On est pr\xc3\xa9lev\xc3\xa9 de partout, je ne pense m\xc3\xaame pas \xc3\xa0 embaucher, cela me co\xc3\xbbterait bien trop cher. Bref, 100% d\xe2\x80\x99accord avec vous. Le probl\xc3\xa8me, je ne vois pas comment cela pourrait changer avec le gouvernement actuel\xe2\x80\xa6 A moins que si, j\xe2\x80\x99ai pu lire il me semble qu\xe2\x80\x99ils avaient en t\xc3\xaate de r\xc3\xa9duire l\xe2\x80\x99IS pour les petites entreprises et de l\xe2\x80\x99augmenter pour les grandes\xe2\x80\xa6 A voir', 
    'date': '2012-06-27T23:21:25+00:00'} 
    2015-11-04 15:29:15 [scrapy] INFO: Closing spider (finished) 
    2015-11-04 15:29:15 [scrapy] INFO: Dumping Scrapy stats: 
    {'downloader/request_bytes': 259, 
    'downloader/request_count': 1, 
    'downloader/request_method_count/GET': 1, 
    'downloader/response_bytes': 252396, 
    'downloader/response_count': 1, 
    'downloader/response_status_count/200': 1, 
    'finish_reason': 'finished', 
    'finish_time': datetime.datetime(2015, 11, 4, 14, 29, 15, 701000), 
    'log_count/DEBUG': 2, 
    'log_count/ERROR': 1, 
    'log_count/INFO': 7, 
    'response_received_count': 1, 
    'scheduler/dequeued': 1, 
    'scheduler/dequeued/memory': 1, 
    'scheduler/enqueued': 1, 
    'scheduler/enqueued/memory': 1, 
    'start) 
    time': datetime.datetime(2015, 11, 4, 14, 29, 13, 191000)} 

@eLRuLL मैं की टिप्पणी से एक और अजीब बात निम्नलिखित किया:

>>> s = "Tellement vrai\xe2\x80\xa6 Il faut vraiment \xc3\xaatre motiv\xc3\xa9 aujourd\xe2\x80\x99hui pour monter sa bo\xc3\xaete. On est pr\xc3\xa9lev\xc3\xa9 de partout, je ne pense m\xc3\xaame pas \xc3\xa0 embaucher, cela me" 
>>> s 
'Tellement vrai\xe2\x80\xa6 Il faut vraiment \xc3\xaatre motiv\xc3\xa9 aujourd\xe2\x80\x99hui pour monter sa bo\xc3\xaete. On est pr\xc3\xa9lev\xc3\xa9 de partout, je ne pense m\xc3\xaame pas \xc3\xa0 embaucher, cela me' 
>>> se = s.encode("utf8", "strict") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 14: ordinal not in range(128) 
>>> se = s.encode("utf-8", "strict") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 14: ordinal not in range(128) 
>>> s.decode() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 14: ordinal not in range(128) 

तो मेरा सवाल है। अगर यह पाठ एन्कोड नहीं किया जा सकता है। तो क्यों, मेरी मोंगोपाइपलाइन पकड़ने की कोशिश कर रही है इस विस्तार से नहीं? क्योंकि केवल वे ऑब्जेक्ट्स जो कोई अपवाद नहीं उठाते हैं उन्हें आइटम ['टिप्पणियां'] में जोड़ा जाना चाहिए?

+0

क्या आपने आइटम को पहले स्थानांतरित करने और फिर प्रत्येक फ़ील्ड को अपडेट करने का प्रयास किया है? – eLRuLL

+0

@eLRuLL जैसा कि आपने सुझाव दिया था कि मैंने आइटम को कन्वर्ट करने की कोशिश की है, फिर एन्कोडेड utf8 सख्त मानों से सभी फ़ील्ड को अपडेट कर रहा है, लेकिन वह भी वही अमान्य DocumentException –

उत्तर

2

अंत में मैंने इसे समझ लिया। समस्या एन्कोडिंग के साथ नहीं थी। यह दस्तावेजों की संरचना के साथ था।

क्योंकि मैं मानक मोंगोपाइपलाइन उदाहरण पर चला गया जो नेस्टेड स्केपर वस्तुओं से निपटता नहीं है। [CommentItem]

तो मेरी BlogItem CommentItems की एक सूची है "Url" ... टिप्पणी =:

मैं क्या कर रहा हूँ है: BlogItem। अब समस्या यहां आया, डेटाबेस मैं करता हूँ में वस्तु बने के लिए:

self.db[self.collection_name].insert(dict(item)) 

तो यहाँ मैं एक dict को BlogItem को पार्स कर रहा हूँ। लेकिन मैं CommentItems की सूची को पार्स नहीं कर रहा हूं। और क्योंकि ट्रेसबैक टिप्पणी इटैम को एक तरह की तरह दिखाता है, यह मेरे लिए नहीं हुआ कि समस्याग्रस्त वस्तु एक नियम नहीं है!

item['comments'].append(dict(comment)) 

अब MongoDB एक वैध दस्तावेज के रूप में यह मानता है:

तो अंत में जिस तरह से इस समस्या को दूर करने के लिए जब इस तरह के रूप टिप्पणी सूची टिप्पणी जोड़कर लाइन बदलने के लिए है।

आखिरकार, आखिरी भाग के लिए जहां मैं पूछता हूं कि मुझे पाइथन कंसोल पर अपवाद क्यों मिल रहा है और स्क्रिप्ट में नहीं।

कारण यह है कि मैं अजगर कंसोल पर काम कर रहा था, जो केवल एसीआई का समर्थन करता है। और इस प्रकार त्रुटि।

1

सबसे पहले, जब आप "somestring".encode(...) करते हैं, "somestring" नहीं बदल रहा है, लेकिन यह एक नया एन्कोडेड स्ट्रिंग देता है, ताकि आप की तरह कुछ का उपयोग करना चाहिए:

item['author'] = item['author'].encode('utf-8', 'strict') 

और अन्य क्षेत्रों के लिए एक ही।

+0

उठाता है लक्ष्य यह सत्यापित करना था कि एन्कोडिंग संभव है या नहीं। यदि चर को utf8 में एन्कोड किया जा सकता है। और यदि यह एक अपवाद फेंकता है, तो मैं इस वस्तु को शामिल नहीं करता हूं। प्लस के रूप में mongodb डिफ़ॉल्ट रूप से जारी रखने से पहले अपनी वस्तुओं को एन्कोड करता है, मैंने सोचा कि इन एन्कोडेड ऑब्जेक्ट्स को स्टोर करना बेकार होगा। जैसा आपने सुझाव दिया उतना कम मैंने कभी नहीं किया। लेकिन अभी भी वही त्रुटि मिलती है। मैं सवाल अपडेट कर रहा हूं। –

+0

बीटीडब्ल्यू, जब मैं कोशिश करता हूं: 's = 'टेलीलेमेंट vrai \ xe2 \ x80 \ xa6 Il ...'; s2 = s.encode ('utf-8', 'सख्त') 'मुझे' यूनिकोडडेकोड एरर ' – eLRuLL

+0

मिल रहा है, इसका मतलब यह होगा कि टिप्पणी [' सामग्री '] एन्कोड नहीं की गई थी। या स्पष्ट एनकोड त्रुटि जो उठाई जानी चाहिए, उठाया नहीं गया है। –

संबंधित मुद्दे