質問: ### 前提・実現したいこと https://zaikosokuho.com/のようなサービスを作成しながらpython学習しようと思っています。 amazon 楽天 ヤフーの商品一覧を作りたいのですがすべてが1つのAPIで取得することができない場合 どのような方法があるのでしょうか? 一覧ページには30件表示させページネーションを設けようと思っています。 *もしくはjsで取得しツイッターのようにスクロールで取得させる。 現在各APIより全件取得し表示では30件ずづと考えていますが、パフォーマンス、サーバー負荷を考えるとあまり得策ではない気がしています。 皆さんであればどのようにさせるのでしょうか? ### 使用するAPI `商品A`の一覧を作成する際、 下記のAPIを使用して取得する際 ``` rakuten : rakuten develop yahoo : valuecommerce amzon: amazon develop ``` #### AMAZON | 商品名 | 金額 | | --- | --- | | 商品A | 100 | | 商品A | 110 | | 商品A | 120 | | 商品A | 130 | | 商品A | 140 | | 商品A | 150 | #### 楽天 | 商品名 | 金額 | | --- | --- | | 商品A | 200 | | 商品A | 210 | | 商品A | 220 | | 商品A | 230 | | 商品A | 240 | | 商品A | 250 | #### yahoo | 商品名 | 金額 | | --- | --- | | 商品A | 10 | | 商品A | 310 | | 商品A | 320 | | 商品A | 330 | | 商品A | 340 | | 商品A | 350 | 一覧表示 ---- | 商品名 | 金額 | *補足* | | --- | --- | --- | | 商品A | 10 | yahoo | | 商品A | 100 | amazon | | 商品A | 110 | amazon | | 商品A | 120 | amazon | | 商品A | 130 | amazon | | 商品A | 140 | amazon | --- ### ご教授ください。
回答: シンプルに1商品のみで考えます。 また、各店舗は金額の低い順で返すものとし、ページネーションにも対応しているとします。 ただし、結果として出力したい順をAPIで指定できるのであれば、どんな順番でもよいです。 どのような順番であれ、各店舗のAPIは最大でもページネーションに必要な件数のみ取得すればよいでしょう。 その結果を並び替えて保持しておけばよいです。 ページネーションの結果、そのページ表示に足りなくなれば、その都度各APIから次のページ分を取得すればよいです。 以下、模擬コードです。 なお、このコードでは各ページにおいて厳密に金額の昇順の結果を返しません。 (たとえば3ページ目と4ページ目の結果など) ちゃんとやろうとすれば、各APIの結果の最小値>現結果リストの最大値となるまで各API結果を取得しておく必要があります。 ``` import random import pprint random.seed(110) N_API = 3 # 各APIからの結果数 N_RET = 5 # 結果として返すページ当たりの件数 # 各API。呼び出し毎に金額の低い順にN_API個の値を返す def api(): i = 0 while True: l = [] for _ in range(N_API): i = i + random.randint(0,10) l.append(i) yield l # 各API apis = [('ama', api()), ('rak', api()), ('yah', api())] # 各APIから必要な数の結果を返す # 必要な数:各APIともに最低N_RETだけあればよい def get_api_list(): lst = [] for api in apis: api_ret = [] while len(api_ret) < N_RET: api_ret += [(api[0],v) for v in api[1].__next__()] lst += api_ret return lst lst = [] for i in range(10): # 適当な回(ページ)数 # ページ表示に必要な件数を割った if len(lst) < N_RET: lst += get_api_list() lst.sort(key=lambda x:x[1]) top = lst[:N_RET] print('-----') pprint.pprint(top) 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)] ```