3

辞書のリストがあり、JSON URL を検索しながら入力しています。問題は、JSON (Google Books API によって提供される) が常に完全であるとは限らないことです。これは書籍の検索であり、私が見たところ、すべての書籍に ID、タイトル、および著者が含まれていますが、すべての書籍に imageLinks が含まれているわけではありません。例として JSON リンクを次に示します: Search for Harry Potter

常に10 件の結果が返されることに注意してください。この例では、ID は 10 件、タイトルは 10 件、作成者は 10 件ですが、imageLink は 4 件しかありません。

@app.route('/search', methods=["GET", "POST"])
@login_required
def search():
    if request.method == "POST":
        while True:
            try:
                seek = request.form.get("seek")
                url = f'https://www.googleapis.com/books/v1/volumes?q={seek}'
                response = requests.get(url)
                response.raise_for_status()
                search = response.json()
                seek = search['items']
                infobooks = []
                for i in range(len(seek)):
                    infobooks.append({
                        "book_id": seek[i]['id'],
                        "thumbnail": seek[i]['volumeInfo']['imageLinks']['thumbnail'],
                        "title": seek[i]['volumeInfo']['title'],
                        "authors": seek[i]['volumeInfo']['authors']
                    })
                return render_template("index.html", infobooks=infobooks)
            except (requests.RequestException, KeyError, TypeError, ValueError):
                continue
    else:
        return render_template("index.html")

私が使用した方法と上記で示した方法では、10 個の imageLinks (サムネイル) を見つけることができますが、時間がかかります。このリクエストにそれほど時間がかからないための提案はありますか? または、imageLink が見つからないときに「表紙のない本」の画像を挿入する方法はありますか? (私が望むものではありませんが、結果を待たなければならないよりはましです)

4

4 に答える 4

1

あなたの質問からは、問題が何であるかがすぐにはわかりませんでした (したがって、エンゲージメントの欠如)。コードと API を少しいじってみると、この問題をよりよく理解できるようになりました。

問題は、Google ブックス API が各アイテムの画像サムネイルを常に含むとは限らないことです。

この問題に対する現在の解決策は、すべてのフィールドに画像のサムネイルが表示されるまで検索全体を再試行することです。しかし、これが本当に必要かどうか考えてみてください。分けてもいいかもしれませんね。私のテストでは、画像のサムネイルのない本が頻繁に切り替わることがわかりました。つまり、クエリのすべての結果にサムネイルが表示されるまで再試行を続けると、時間がかかります。

ソリューションは、サムネイルについて各本を個別に照会しようとする必要があります。X回試行した後、APIのスパムを避けるために、デフォルトで「画像が利用可能」になります。

投稿で既にわかっているように、元の検索クエリから各本の巻 ID を取得できます。次に、このAPI 呼び出しを使用して、これらの各ボリュームを個別にクエリできます。

これが機能することを検証するコードをいくつか作成しました。そして最後に画像のサムネイルがないのは1冊だけ。このコードにはまだ多くの改善の余地がありますが、それは演習として残しておきます。

import requests

# Max attempts to get an image
_MAX_ATTEMPTS = 5

# No Image Picture
no_img_link = 'https://upload.wikimedia.org/wikipedia/en/6/60/No_Picture.jpg'


def search_book(seek):
    url = f'https://www.googleapis.com/books/v1/volumes?q={seek}'
    response = requests.get(url)
    search = response.json()
    volumes = search['items']

    # Get ID's of all the volumes
    volume_ids = [volume['id'] for volume in volumes]

    # Storage for the results
    book_info_collection = []

    # Loop over all the volume ids
    for volume_id in volume_ids:

        # Attempt to get the thumbnail a couple times
        for i in range(_MAX_ATTEMPTS):
            url = f'https://www.googleapis.com/books/v1/volumes/{volume_id}'
            response = requests.get(url)
            volume = response.json()
            try:
                thumbnail = volume['volumeInfo']['imageLinks']['thumbnail']
            except KeyError:
                print(f'Failed for {volume_id}')
                if i < _MAX_ATTEMPTS - 1:
                    # We still have attempts left, keep going
                    continue
                # Failed on the last attempt, use a default image
                thumbnail = no_img_link
                print('Using Default')

            # Create dict with book info
            book_info = {
                "book_id": volume_id,
                "thumbnail": thumbnail,
                "title": volume['volumeInfo']['title'],
                "authors": volume['volumeInfo']['authors']
            }

            # Add to collection
            book_info_collection.append(book_info)
            break

    return book_info_collection


books = search_book('Harry Potter')
print(books)

于 2021-06-08T00:20:59.753 に答える