MongoDB InvalidDocument:无法对对象进行编码

2024-01-18

我正在使用 scrapy 来抓取博客,然后将数据存储在 mongodb 中。起初我得到了 InvalidDocument 异常。对我来说很明显的是数据的编码不正确。因此,在持久化对象之前,在我的 MongoPipeline 中,我检查文档是否为“utf-8 strict”,然后我才尝试将对象持久化到 mongodb。但我仍然遇到无效文档异常,现在这很烦人。

这是我的代码,我的 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 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)

那么我的问题是。如果该文本无法编码。那为什么,我的 MongoPipeline try catch没有抓住这个例外?因为只有不引发任何异常的对象才应该附加到 item['comments'] ?


最后我想通了。问题不在于编码。这是与文档的结构有关。

因为我使用了标准 MongoPipeline 示例,该示例不处理嵌套的 scrapy 项目。

我正在做的是: 博客项目: “网址” ... 评论 = [评论项]

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

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

所以在这里我将 BlogItem 解析为字典。但我没有解析 CommentItems 列表。而且因为回溯显示 CommentItem 有点像字典,所以我没有想到有问题的对象不是字典!

所以最后解决这个问题的方法是在将评论附加到评论列表时更改行,如下所示:

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

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

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

原因是因为我正在使用 python 控制台,它只支持 ascii。因此出现了错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB InvalidDocument:无法对对象进行编码 的相关文章

随机推荐

  • xunit 构造函数在每次测试之前运行

    我有一个测试类 在每次测试执行之前都会调用构造函数 目前 以下测试之间不共享构造函数初始化的数据 我希望初始化数据设置一次并在所有测试中共享 这是我的代码 Category Basics Collection DBCollection Ex
  • 从通知启动应用程序将其从最近的应用程序历史记录中删除

    当我从通知启动其中一个应用程序时 我遇到了问题 它永远不会出现在 最近使用的应用程序 列表中 如果没有通知 一切都会按预期进行 我启动应用程序 导航到并退出它 使用主页按钮或后退按钮 之后我可以长按主页按钮返回到它 gt 确定 当我收到通知
  • Proguard 不会混淆 gui 组件

    我想使用 ProGuard 来混淆我的 Android 应用程序 这很好用 但我的 gui 类 扩展了 Activity View 和 SherlockActivity 并没有被混淆 这是 proguard cfg injars bin c
  • Yii2:如何访问模板邮件中的参数?

    我有以下代码 Yii app gt mailer gt compose layouts html name gt this gt name email gt this gt email subject gt this gt subject
  • 防止调试 PhoneGap 应用程序

    我使用 PhoneGap 创建了一个 iOS 应用程序 我了解到将 iPhone 连接到 Mac 在 iPhone 上启用 Safari 调试 然后在 Mac 上使用 Safari 来查看属于该应用程序的所有 HTML 和 JavaScri
  • 如何在 iOS 中从图像处理中检测对象?

    我有一个图像 图像中有一个玻璃杯 两个勺子 此图像显示在 iPad 上 现在我希望当用户仅触摸勺子时 勺子颜色将变为绿色 图像的其余部分保持不变 我不知道该怎么做 从哪里开始呢 任何想法或建议都将受到高度欢迎 使用 CALayer 使用所需
  • 习惯从类型继承元类?

    我一直在尝试理解 python 元类 因此一直在浏览一些示例代码 据我了解 Python 元类可以是任何可调用的 所以 我可以让我的元类像 def metacls clsName bases atts return type clsName
  • 使用 PadRight 方法填充字符串

    我正在尝试在 C 中的字符串末尾添加空格 Trip Name1 PadRight 20 还尝试过 Trip Name1 PadRight 20 这些似乎都不起作用 不过我可以用任何其他字符填充字符串 为什么 我应该更具体 这是完整的代码 l
  • 在 Laravel 5 中动态编辑 .env 是个好主意吗?

    我正在构建一个管理面板 所以我需要做一些核心设置我的 Laravel 5 应用程序 如 smtp 设置等 可通过前端界面配置给最终用户 我最初的想法是使用数据库作为设置存储和缓存 以避免每次访问配置值时发出数据库调用 然而 看来 外观在配置
  • 在摘要报告侦听器文件名中使用时间函数

    在 JMeter 5 1 1 中 我有一个摘要报告 我试图将其保存为带时间戳的文件 文件名值如下所示 D Load Tests example com Results time yyyy MM dd HH mm ss summary csv
  • 在类 Unix 系统上获得以秒或毫秒为单位的正常运行时间

    我需要一种方法 可以给出自系统启动以来经过的毫秒数或秒数 我可以解析 proc uptime 但我不能因为这个 I 0 和解析而损失性能 我正在使用 Linux 和 C C 也许我可以添加一些 Qt Boost 但最好是原生的 为什么你读不
  • Entity Framework 4 与 LINQ to SQL,适用于中小型应用程序,与 SQL Server 配合使用

    早在 4 月份 VS2010 发布时 我就在 Stack Overflow 上看到过一些关于 L2S 与 EF4 的讨论 即 既然 Entity Framework 4 0 已经发布 就转储 Linq To Sql 吗 https stac
  • 尝试在 Flutter 上运行此处示例时出错

    所以我正在尝试将 Here 集成到我的 flutter 应用程序中 所以我正在关注这个页面flutter sdk 导航 https developer here com documentation flutter sdk navigate
  • 更新到 Mac OSX 10.9.4 后找不到 npm 命令

    将操作系统更新到 Mavericks 后 我无法在终端上执行 npm 命令 当我尝试这个时 node usr local lib node modules npm bin npm cli js v它正在工作并显示版本 1 4 3 我不知道这
  • Flash 功能中的冲突检测? (命中测试对象)

    你好 所以我最近一直在使用hitTestObject检测我正在制作的 Android 应用程序中的碰撞 经过一番测试后 我意识到游戏正在检测 假 碰撞 我的意思是它正在检测碰撞not当物体的像素接触时 但是 经过一些研究后 我发现boxes
  • 如何让每个
  • 标签一个接一个地慢慢出现
  • 我希望当页面加载时列表项慢慢地一个接一个地出现在屏幕上 这是jquery中的代码 我使用过show 但它不起作用 我确实在这里查找问题 其中一些正在使用附加方法 但这不是我要寻找的 html ul li A li li B li li C
  • Angular 4自带的form element组件

    我是角度初学者 我可能需要一些帮助 首先 我将展示它如何工作 然后我将写下我希望它如何工作 这是使用 ngModel 时的常规方式
  • 如何在具有可变宽度 Unicode 字符的 Swift 字符串上使用 NSRegularExpression?

    我无法获取NSRegularExpression匹配字符串中含有较宽 Unicode 字符的模式 看起来问题出在范围参数上 Swift 计算单个 Unicode 字符 而 Objective C 将字符串视为由 UTF 16 代码单元组成
  • 如何使用CPU在深度睡眠模式下执行任何操作

    我是新来的android 我花了大约三个星期的时间来处理我的申请 我需要在正常模式下发送和接收数据包sleep mode My app必须交换数据 5 秒 我尝试使用alarmmanager但在 android 5 上它不起作用 在andr
  • MongoDB InvalidDocument:无法对对象进行编码

    我正在使用 scrapy 来抓取博客 然后将数据存储在 mongodb 中 起初我得到了 InvalidDocument 异常 对我来说很明显的是数据的编码不正确 因此 在持久化对象之前 在我的 MongoPipeline 中 我检查文档是