pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: anjuke.ershoufang index

本文介绍了一段用于抓取安居客二手房信息的Python爬虫代码,并解决了因MongoDB插入数据时出现的问题。通过对代码进行简单调整,实现了稳定的数据抓取和存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个bug忙了我一下午加一个晚上,终于把它ko掉了

先附上一段爬取安居客二手房信息的代码

import re
import time
import pymongo
import requests
from bson import ObjectId
from lxml import etree
from pprint import pprint
headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
    "cookie": "aQQ_ajkguid=243E5D58-8B13-D7BD-4922-3DE583E03855; ctid=11; _ga=GA1.2.1030980732.1530799904; _gid=GA1.2.506397644.1530799904; 58tj_uuid=c606f59a-2fb9-4c91-9815-741fdf9cfe5d; als=0; lps=http%3A%2F%2Fwww.anjuke.com%2F%3Fpi%3DPZ-baidu-pc-all-biaoti%7Chttps%3A%2F%2Fwww.baidu.com%2Fs%3Fie%3Dutf-8%26f%3D8%26rsv_bp%3D0%26rsv_idx%3D1%26tn%3Dbaidu%26wd%3D%25E5%25AE%2589%25E5%25B1%2585%25E5%25AE%25A2%26rsv_pq%3Dd71198bd000395ca%26rsv_t%3D6172VDlcx2zzRQ%252FLyCdcEidtafr%252BSvVyVXrlZ0lsK3U1MEz8066IF4byz4c%26rqlang%3Dcn%26rsv_enter%3D1%26rsv_sug3%3D5%26rsv_sug1%3D5%26rsv_sug7%3D101; twe=2; sessid=3497C1D2-43A8-6143-B2D7-CFDA33FF0C0E; new_uv=2; __xsptplus8=8.2.1530840314.1530840335.2%232%7Cwww.baidu.com%7C%7C%7C%25E5%25AE%2589%25E5%25B1%2585%25E5%25AE%25A2%7C%23%23Z7v3XnqLDcxTHeMLiqLXQSLHvXrh8k_R%23",
    "referer": "https://shanghai.anjuke.com/?pi=PZ-baidu-pc-all-biaoti"
}

# 连接数据库
client = pymongo.MongoClient('127.0.0.1', 27017)
# 定义数据库名称
db = client.anjuke
# 定义表名
coll = db.ershoufang

def get_info():
    count = 0
    for i in range(23):

        response = requests.get('https://shanghai.anjuke.com/sale/p{}/#filtersort'.format(i), headers=headers)

        item = response.text

        # print(item)
        # 利用etree.HTML,将字符串解析为HTML文档
        html = etree.HTML(item)
        htmls = html.xpath('//*[@id="houselist-mod-new"]/li')
        # print(htmls)


         house = {}
        for h in htmls:
            h_addr = h.xpath('./div[2]/div[1]/a/text()')[0].strip()
            h_type = h.xpath('./div[2]/div[2]/span[1]/text()')[0].strip()
            h_area = h.xpath('./div[2]/div[2]/span[2]/text()')[0].strip()
            h_hight = h.xpath('./div[2]/div[2]/span[3]/text()')[0].strip()
            h_name = h.xpath('./div[2]/div[2]/span[4]/text()')[0].strip()
            try:
                h_youshi1 = h.xpath('./div[2]/div[4]/span[1]/text()')[0].strip()
            except:
                h_youshi1=None
            try:
                h_youshi2 = h.xpath('./div[2]/div[4]/span[2]/text()')[0].strip()
            except:
                h_youshi2=None
            try:
                h_youshi3 = h.xpath('./div[2]/div[4]/span[3]/text()')[0].strip()
            except:
                h_youshi3=None
            h_price = h.xpath('./div[3]/span[1]/strong/text()')[0].strip()
           
            house['h_addr']=h_addr
            house['h_type']=h_type
            house['h_area']=h_area
            house['h_hight']=h_hight
            house['h_name']=h_name
            house['h_youshi1']=h_youshi1
            house['h_youshi2']=h_youshi2
            house['h_youshi3']=h_youshi3
            house['h_price']=h_price
            # pprint(house)
            time.sleep(0.01)
           
            # coll.insert(house)
            save(house)
            count+=1
    print(count)

def save(house):

    coll.insert(house)

def main():
    get_info()

if __name__ == '__main__':

    main()

这个代码只能运行两条数据,


两条数据,一条有‘_id’,一条没有

目前有两条解决方案:

一:在程序中加一个‘_id’,这个字段,自己设置_id字段,代替系统分配:


程序没问题:


二:将house={},这个字典放在for循环里面:


这两种方法都可以解决问题,个人建议还是方法二,代码规范,让系统自己分配id

<think>好的,用户遇到了一个KeyError: 'pymongo'的错误,在尝试访问mongo_cache = app.extensions["pymongo"].cx的时候。我需要先分析可能的原因,然后逐步给出解决方案。 首先,用户可能在Flask应用中使用PyMongo扩展。KeyError意味着在app.extensions中没有找到'pymongo'这个键。这可能是因为扩展没有被正确初始化或者注册。我需要回忆Flask-PyMongo的用法。 通常,使用Flask-PyMongo需要先初始化。用户可能忘记调用init_app或者没有正确配置MONGO_URI。另外,可能扩展的注册名称不是'pymongo',比如有些教程里可能用'mongo'或者其他别名,这时候用户需要确认实际使用的键。 接下来,我应该分步骤指导用户检查他们的代码。第一步是确认是否已经正确安装Flask-PyMongo包,因为有时候依赖没有安装会导致扩展不存在。第二步检查配置,确保MONGO_URI正确设置。第三步查看扩展的初始化代码,是否使用了PyMongo的构造函数,并正确关联到app实例。第四步,如果用户使用了自定义的扩展名称,他们需要调整访问时的键名。 另外,用户可能在初始化时有多个实例导致的问题,或者应用上下文的问题。但首先应该检查最基本的安装、配置和初始化步骤。如果这些都没问题,可能需要查看应用的扩展列表,打印app.extensions.keys()来确认是否存在'pymongo'。 最后,给出示例代码供用户对照,确保他们的代码结构正确。同时提醒他们在遇到错误时如何调试,比如打印扩展列表或检查配置是否正确。</think>遇到`KeyError: 'pymongo'`错误时,说明你的Flask应用没有正确初始化PyMongo扩展。以下是分步排查和解决方案: --- ### 1. **确认PyMongo扩展安装** - 需要先安装`Flask-PyMongo`包: ```bash pip install Flask-PyMongo ``` --- ### 2. **检查配置项** - 在Flask应用配置中**必须包含MongoDB连接URI**: ```python app.config["MONGO_URI"] = "mongodb://localhost:27017/your_database" ``` --- ### 3. **正确初始化PyMongo** - **初始化代码必须存在于应用启动流程中**: ```python from flask_pymongo import PyMongo mongo = PyMongo(app) # 直接绑定app实例 ``` - 或使用工厂模式: ```python mongo = PyMongo() def create_app(): app = Flask(__name__) app.config["MONGO_URI"] = "..." mongo.init_app(app) # 延迟初始化 return app ``` --- ### 4. **访问扩展的正确方式** - 初始化后的扩展会注册到`app.extensions`字典中,但**键名由扩展类名决定**: ```python # 默认情况下键名为'pymongo' mongo_client = app.extensions['pymongo'].cx ``` - 可以通过打印确认所有已注册的扩展: ```python print(app.extensions.keys()) # 查看是否存在'pymongo' ``` --- ### 5. **常见错误场景** - **未调用`init_app()`**:工厂模式下忘记调用初始化方法 - **配置缺失**:`MONGO_URI`未设置或拼写错误 - **多实例冲突**:重复初始化导致覆盖 --- ### 完整示例代码 ```python from flask import Flask from flask_pymongo import PyMongo app = Flask(__name__) app.config["MONGO_URI"] = "mongodb://localhost:27017/mydb" # 初始化PyMongo mongo = PyMongo(app) # 在视图或其他地方访问 def get_data(): # 通过扩展对象直接访问 db = mongo.db # 或通过app.extensions client = app.extensions['pymongo'].cx return db.collection.find() ``` --- 如果问题仍未解决,建议: 1. 检查Flask应用初始化流程 2. 在初始化后立即打印`app.extensions.keys()` 3. 确认MongoDB服务是否正常运行
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值