質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

3019閲覧

PythonからMongoDBにドキュメントを登録する際に発生する重複エラーを取り除きたい

toyokiti

総合スコア13

MongoDB

MongoDBはオープンソースのドキュメント指向データベースの1つです。高性能で、多くのリトルエンディアンシステムを利用することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/01/05 08:15

##■環境
macOS:Mojave 10.14.6
python: 3.6.5
MongoDB: v4.2.2

##■解決したいこと
株の情報を取得するWebクローラーを作成しております。
その際に、Webから取得した情報をMongoDBに登録する際エラーが発生し登録ができません。
インサート文"collection.insert_one"をfor文で回して複数のドキュメントを登録します。
for文の1周目は登録できるのですが、2周目でエラーが発生します。

pythonもMongoDBも今回触り始めたばかりで素人質問かもしれません。
お忙しい中恐縮ですが、ご教授いただけると幸いです。

##■エラー
下記エラーが出て、DBに登録ができません。
疑問としては、
brandNo: nullとなっておりますが、brandNoというフィールドは用意しておりません。
・1周目の登録と2周目の登録で、各フィールドに重複内容がないことは確認いたしました。

pymongo.errors.DuplicateKeyError: E11000 duplicate key error collection: kabu.allbrands index: brandNo_1 dup key: { brandNo: null }

##■コード

import re import time #timeモジュールをインポートする import requests import lxml.html from typing import Iterator #型ヒントのためにインポート from pymongo import MongoClient #MongoClientのインポート import pdb #まずpdbをインポート def main(): """ クローラーのメインの処理 """ client = MongoClient('localhost', 27017) #ローカルホストのMongoDBに接続する。 collection = client.kabu.allbrands #kabuデータベースのallbrandsコレクションを得る collection.create_index('code', unique=True) #データを一意に識別するキーを格納するcodeをユニークなインデックスに指定 session = requests.Session() #複数ページにアクセスするためSession()を使用 codeLists = range(3000,3100) #銘柄コードの範囲 #ここからのfor文でMongoDBに情報を登録します。 for code in codeLists: time.sleep(1) #1秒間ウェイトを入れる base_url = 'https://kabutan.jp/stock/?code={}'.format(str(code)) #詳細ページのURL print(base_url) response = session.get(base_url)#responseを取得 [200]で返ってくる try: brand = scrape_detail_page(response)#scrape_list_page()関数を呼び出しジェネレーターイテレータを取得する collection.insert_one(brand) #銘柄情報をMongoDBに保存 print(brand) except IndexError: pass def scrape_detail_page(response: requests.Response)->dict: """ 詳細ページのResponseから株価の情報をdictで取得する """ html = lxml.html.fromstring(response.text) brand = { '_id': extract_code(response.url), 'code': extract_code(response.url), #銘柄のコード extract_key()を呼び出す 'name': html.cssselect('#kobetsu_right > div.company_block > h3')[0].text_content() , #銘柄名(正式名称) 'market': html.cssselect('#stockinfo_i1 > div.si_i1_1 > span')[0].text_content(),#上場市場名 'url': response.url } return brand def extract_code(url:str)->str: """ URLからキー(URLの末尾の銘柄コード)を抜き出す """ m = re.search(r'=(\d{4})',url) return m.group(1) if __name__=='__main__': main()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

一度、データベースを削除してからリトライしたらうまく動きました。
お騒がせして申し訳ありません。

投稿2020/01/05 09:39

toyokiti

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問