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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

867閲覧

スクレイピングで取得したデータを1件ごとに辞書を作成しそこに保存する方法を教えて下さい

Pow

総合スコア23

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/09/16 13:22

質問内容

スクレイピングで取得したデータを、React.jsに渡す為、JSONファイルに出力したいです。
しかし、最後に取得したデータのみがループ回数分出力されてしまいます。

下記のコードでは3件の店舗情報を取得したのですが、これを店舗ごとにそれぞれ
別の辞書に保存したJSONファイルに出力するにはどのようにすれば良いでしょうか。
原因は辞書の変数"dict"を繰り返し使用している為と考えていますが、対策がわかりません。

ご回答の程、よろしくお願いいたします。

環境

Python: 3.9.6

コード

python

1import requests 2from bs4 import BeautifulSoup 3import re 4import time 5import json 6 7num = 1 8list = [] 9dict = {} 10 11for i in range(3): 12 url = "https://example.com/example/" + str(num) + "/" 13 page = requests.get(url) 14 soup = BeautifulSoup(page.text, "html.parser") 15 16 # 店舗情報を取得 17 name = soup.h2.string 18 area = soup.select("a.area")[0]["title"] 19 genre = soup.select("a.genre")[0]["title"] 20 21 # 辞書に追加 22 dict["name"] = name 23 dict["area"] = area 24 dict["genre"] = genre 25 list.append(dict) 26 27 # リストをJSONファイルへ出力 28 with open("mydata.json", mode="wt", encoding="utf-8") as file: 29 json.dump(list, file, ensure_ascii=False, indent=2) 30 31 num += 1 32 time.sleep(1)

json

1// 実際の結果 2 3[ 4 { 5 "name": "酒処えぐざんぷる", 6 "area": "えぐざんぷる地区", 7 "genre": "居酒屋", 8 }, 9 { 10 "name": "酒処えぐざんぷる", 11 "area": "えぐざんぷる地区", 12 "genre": "居酒屋", 13 }, 14 { 15 "name": "酒処えぐざんぷる", 16 "area": "えぐざんぷる地区", 17 "genre": "居酒屋", 18 }, 19]

json

1// 求めている結果 2 3[ 4 { 5 "name": "レストラン サンプル", 6 "area": "さんぷる地区", 7 "genre": "洋食", 8 }, 9 { 10 "name": "寿司 てすと", 11 "area": "てすと地区", 12 "genre": "和食", 13 }, 14 { 15 "name": "酒処えぐざんぷる", 16 "area": "えぐざんぷる地区", 17 "genre": "居酒屋", 18 }, 19]

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

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

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

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

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

guest

回答2

0

ベストアンサー

  • 辞書はループ内で宣言する。(同じ内容になる原因を排除)
  • ファイルへの書き込みはループの外の1回でよい。
  • listdictという型名と同じ変数名は使わない。

python

1import json 2 3num = 1 4l = [] 5for i in range(3): 6 d = {} 7 d["name"] = f'{i}' # スクレイピング結果 8 l.append(d) 9 num += 1 10 11# リストをJSONファイルへ出力 12with open("mydata.json", mode="wt", encoding="utf-8") as file: 13 json.dump(l, file, ensure_ascii=False, indent=2)

投稿2021/09/16 13:43

can110

総合スコア38341

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

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

Pow

2021/09/16 14:12

ご回答ありがとうございます。 無事、正常に出力出来ました。 何故、辞書をループ内で宣言すると同じ内容にならないのでしょうか?
can110

2021/09/17 00:04

ループ内で毎回空「d = {}」の辞書がイチから作られるからです。 よってリストに追加されるのは別々の辞書になります。
Pow

2021/09/17 01:06

お陰様で理解が出来ました。 ありがとうございます。
guest

0

以下のdictionaryの定義をforの中に入れれば解消されるかと思います。

python

1dict = {}

dictという変数名は組み込み型を上書きしてしまうので、変数名は変更した方が良いかと思います。

https://docs.python.org/ja/3/library/stdtypes.html#dict

投稿2021/09/16 13:38

編集2021/09/16 13:51
yamap55

総合スコア1376

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

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

Pow

2021/09/16 14:15

ご回答ありがとうございます。 解決いたしました。 何故、dictionaryの定義をforの中で行うと上書きされないのでしょうか?
Pow

2021/09/17 01:09

idを出力し、同名の別の変数という事が確認ができ、理解しました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問