MongoDB InvalidDocument:无法编码对象

我正在使用scrapy来取消博客,然后将数据存储在mongodb中。 起初我得到了InvalidDocument异常。 对我来说非常明显的是,数据不是正确的编码。 所以在持久化对象之前,在我的MongoPipeline中,我检查文档是否在'utf-8 strict'中,然后我尝试将对象保存到mongodb中。 但仍然我得到InvalidDocument异常,现在很烦人。

这是我的代码,我的MongoPipeline对象持久对象mongodb

# -*- 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

我仍然得到以下异常:

au coeur de lu2019explosion de la bulle Internet nu2019est probablement pas xe9tranger au succxe8s qui a suivi. Mais franchement, cu2019est un peu court comme argument !Ce que je sais dire, compte tenu de ce qui prxe9cxe8de, cu2019est quelles sont les conditions pour rxe9ussir si lu2019on est vraiment contraint de rester en France. Ce sont des sujets que je dxe9velopperai 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 ?ttt ',
     'url': 'http://www.reussir-sa-boite.fr/peut-on-encore-entreprendre-en-france/'}
    Traceback (most recent call last):
      File "h:program filesanacondalibsite-packagestwistedinternetdefer.py", line 588, in _runCallbacks
        current.result = callback(current.result, *args, **kw)
      File "H:PDSBNPcrawlercrawlerpipelines.py", line 76, in process_item
        self.db[self.collection_name].insert(dict(item))
      File "h:program filesanacondalibsite-packagespymongocollection.py", line 409, in insert
        gen(), check_keys, self.uuid_subtype, client)
    InvalidDocument: Cannot encode object: {'author': 'Arnaud Lemasson',
     'content': 'Tellement vraixe2x80xa6 Il faut vraiment xc3xaatre motivxc3xa9 aujourdxe2x80x99hui pour monter sa boxc3xaete. On est prxc3xa9levxc3xa9 de partout, je ne pense mxc3xaame pas xc3xa0 embaucher, cela me coxc3xbbterait bien trop cher. Bref, 100% dxe2x80x99accord avec vous. Le problxc3xa8me, je ne vois pas comment cela pourrait changer avec le gouvernement actuelxe2x80xa6 A moins que si, jxe2x80x99ai pu lire il me semble quxe2x80x99ils avaient en txc3xaate de rxc3xa9duire lxe2x80x99IS pour les petites entreprises et de lxe2x80x99augmenter pour les grandesxe2x80xa6 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 vraixe2x80xa6 Il faut vraiment xc3xaatre motivxc3xa9 aujourdxe2x80x99hui pour monter sa boxc3xaete. On est prxc3xa9levxc3xa9 de partout, je ne pense mxc3xaame pas xc3xa0 embaucher, cela me"
>>> s
'Tellement vraixe2x80xa6 Il faut vraiment xc3xaatre motivxc3xa9 aujourdxe2x80x99hui pour monter sa boxc3xaete. On est prxc3xa9levxc3xa9 de partout, je ne pense mxc3xaame pas xc3xa0 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)

那么我的问题是。 如果这个文本不能被编码。 那么,为什么,是我MongoPipeline尝试捕捉不要再追此异常? 因为只有不引发异常的对象应该附加到item ['comments']上?


最后我明白了。 问题不在于编码。 这是与文件的结构。

因为我没有处理嵌套scrapy项目的标准MongoPipeline示例。

我正在做的是:BlogItem:“url”... comments = [CommentItem]

所以我的BlogItem有一个CommentItems列表。 现在问题来了,为了坚持对象在我做的数据库中:

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

所以我在这里解析BlogItem为字典。 但我不解析CommentItems的列表。 并且由于回溯显示CommentItem类似于字典,因此我没有想到有问题的对象不是字典!

所以最后解决这个问题的方法是在将注释附加到注释列表中时改变这一行:

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

现在MongoDB认为它是一个有效的文档。

最后,对于最后一部分,我问为什么我在python控制台上得到一个异常,而不是在脚本中。

原因是因为我正在研究只支持ascii的python控制台。 因此错误。


首先,当你做"somestring".encode(...) ,不会改变"somestring" ,但它会返回一个新的编码字符串,所以你应该使用类似于:

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

其他领域也是如此。

链接地址: http://www.djcxy.com/p/30331.html

上一篇: MongoDB InvalidDocument: Cannot encode object

下一篇: Combine several SKScenes in Sprite Kit