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

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

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

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

Q&A

2回答

722閲覧

商品価格比較サービスロジックについて。

m6450423493

総合スコア1

Python

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

0グッド

2クリップ

投稿2020/08/17 10:47

前提・実現したいこと

https://zaikosokuho.com/のようなサービスを作成しながらpython学習しようと思っています。

amazon 楽天 ヤフーの商品一覧を作りたいのですがすべてが1つのAPIで取得することができない場合

どのような方法があるのでしょうか?

一覧ページには30件表示させページネーションを設けようと思っています。
*もしくはjsで取得しツイッターのようにスクロールで取得させる。

現在各APIより全件取得し表示では30件ずづと考えていますが、パフォーマンス、サーバー負荷を考えるとあまり得策ではない気がしています。

皆さんであればどのようにさせるのでしょうか?

使用するAPI

商品Aの一覧を作成する際、
下記のAPIを使用して取得する際

rakuten : rakuten develop yahoo : valuecommerce amzon: amazon develop

AMAZON

商品名金額
商品A100
商品A110
商品A120
商品A130
商品A140
商品A150

楽天

商品名金額
商品A200
商品A210
商品A220
商品A230
商品A240
商品A250

yahoo

商品名金額
商品A10
商品A310
商品A320
商品A330
商品A340
商品A350

一覧表示

商品名金額*補足*
商品A10yahoo
商品A100amazon
商品A110amazon
商品A120amazon
商品A130amazon
商品A140amazon

ご教授ください。

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

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

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

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

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

guest

回答2

0

アクセスするたびにリアルタイムで価格を取得するのは負荷を考えると難しいので、
「API を使って価格を取得して、ローカルのデータベースに保存する処理」をスクリプトで書いておき、それを crontab とかで一定間隔 (例えば、1時間ごと) で実行、ページを表示する際はそのローカルのデータベースにキャッシュしたデータを引っ張ってくればいいのではないでしょうか。

投稿2020/08/17 11:01

tiitoi

総合スコア21956

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

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

m6450423493

2020/08/17 11:05

とても参考になります。 ありがとうございます。 一点疑問な点として価格.comのように全商品対応となるとこの方法だと難しいのかと思いますがその際どのようにするものなのでしょうか? 質問ばかりで申し訳ありませんがよろしくお願いします。
tiitoi

2020/08/17 11:08 編集

> 全商品対応となるとこの方法だと難しいのかと思います どのような点が難しいと考えているのでしょうか? 各ショッピングサイトの API の詳細についてはわかりかねますが、API で取得できる内容であれば、対象商品が複数あるとしてもそれをローカルのデータベースにキャッシュしておくことには変わりないのではないでしょうか?
m6450423493

2020/08/17 11:14

難しい理由ですが楽天で出品されている商品は、2018年6月現在においての楽天市場の商品の出品数は「253,558,740点」です。 もう少しわかりやすい表記に直すと、2.5億点の商品が楽天市場に出品され、販売されているわけです。 とのことです、これらをすべてローカルのデータベースにキャッシュさせるということでしょうか? それとも検索がかかった際に一回目のみAPiから取得しキャッシュ させるという意味でしょうか? よろしくおねがしいます。
tiitoi

2020/08/17 11:30 編集

いろいろなカテゴリが対象であるとしても、売上上位100件とかある程度制限は必要かと思います。 なので、例えば 30カテゴリあって、各カテゴリの上位100件とかであれば、30*100 = 3000 レコードなので、十分可能なデータ量だと思います。 例えば、以下の価格比較サイトを見てみると、カテゴリごとに上位100件までが載っています。 右上にかかれている更新日が現時刻より古いことから、回答に記載したようなローカルにキャッシュするアプローチであると推測できます。 https://www.saiyasune.com/I2505.html 自分ひとりしか使わないサービスなら、処理時間も気にしなくていいので、その場で API から必要な分だけとってきてもいいと思いますが、Web サイトとして公開するのであれば、アクセスのたびに API でデータをとってきたら、API の使用上限にすぐ引っかかります。
guest

0

シンプルに1商品のみで考えます。
また、各店舗は金額の低い順で返すものとし、ページネーションにも対応しているとします。

ただし、結果として出力したい順をAPIで指定できるのであれば、どんな順番でもよいです。
どのような順番であれ、各店舗のAPIは最大でもページネーションに必要な件数のみ取得すればよいでしょう。
その結果を並び替えて保持しておけばよいです。
ページネーションの結果、そのページ表示に足りなくなれば、その都度各APIから次のページ分を取得すればよいです。

以下、模擬コードです。
なお、このコードでは各ページにおいて厳密に金額の昇順の結果を返しません。
(たとえば3ページ目と4ページ目の結果など)
ちゃんとやろうとすれば、各APIの結果の最小値>現結果リストの最大値となるまで各API結果を取得しておく必要があります。

Python

1import random 2import pprint 3 4random.seed(110) 5 6N_API = 3 # 各APIからの結果数 7N_RET = 5 # 結果として返すページ当たりの件数 8 9# 各API。呼び出し毎に金額の低い順にN_API個の値を返す 10def api(): 11 i = 0 12 while True: 13 l = [] 14 for _ in range(N_API): 15 i = i + random.randint(0,10) 16 l.append(i) 17 yield l 18 19# 各API 20apis = [('ama', api()), ('rak', api()), ('yah', api())] 21 22# 各APIから必要な数の結果を返す 23# 必要な数:各APIともに最低N_RETだけあればよい 24def get_api_list(): 25 lst = [] 26 for api in apis: 27 api_ret = [] 28 while len(api_ret) < N_RET: 29 api_ret += [(api[0],v) for v in api[1].__next__()] 30 lst += api_ret 31 return lst 32 33lst = [] 34for i in range(10): # 適当な回(ページ)数 35 36 # ページ表示に必要な件数を割った 37 if len(lst) < N_RET: 38 lst += get_api_list() 39 lst.sort(key=lambda x:x[1]) 40 41 top = lst[:N_RET] 42 print('-----') 43 pprint.pprint(top) 44 lst = lst[N_RET:]

結果例

----- [('yah', 5), ('yah', 5), ('ama', 6), ('yah', 6), ('rak', 10)] ----- [('yah', 14), ('ama', 15), ('yah', 15), ('yah', 17), ('ama', 18)] ----- [('rak', 18), ('rak', 19), ('ama', 24), ('rak', 27), ('ama', 31)] ----- [('yah', 25), ('yah', 26), ('yah', 32), ('rak', 33), ('ama', 35)] ----- [('yah', 40), ('rak', 41), ('ama', 42), ('yah', 47), ('rak', 51)] ----- [('yah', 51), ('ama', 52), ('ama', 52), ('rak', 54), ('rak', 58)] ----- [('ama', 60), ('rak', 62), ('ama', 66), ('rak', 67), ('rak', 72)] ----- [('yah', 56), ('yah', 61), ('yah', 64), ('yah', 66), ('yah', 70)] ----- [('yah', 72), ('ama', 75), ('rak', 75), ('rak', 77), ('rak', 84)] ----- [('ama', 85), ('ama', 87), ('rak', 87), ('rak', 88), ('ama', 90)]

投稿2020/08/17 12:00

編集2020/08/17 12:11
can110

総合スコア38341

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問