您已添加您希望它快速加载。这意味着您不能在 python 中进行重试,因为您在 python 中进行的任何重试都意味着更长的页面加载时间。
这意味着您必须在浏览器中进行加载。您可以使用与纯 python 方法相同的方法。首先,您只需使用请求中的所有图像,并对所有没有图像的卷发出额外的请求。这意味着您有 2 个端点,一个用于 volume_information。另一个端点只获取一个卷的数据。
请注意,我使用术语卷而不是书,因为这也是 Google API 使用的。
现在,JavaScript 不是我的强项,所以我在这里提供的解决方案还有很大的改进空间。
我用烧瓶做了这个例子。此示例应该可以帮助您实施适合您的特定应用的解决方案。
额外说明:在我的测试中,我注意到,某些区域比其他区域更频繁地响应所有缩略图。API 根据您的 IP 地址发送不同的响应。如果我将我的 IP 设置在美国,我经常会得到所有缩略图而无需重试。我正在使用 VPN 来执行此操作,但可能还有其他解决方案。
应用程序.py
import time
from flask import Flask, render_template, request, jsonify
import requests
app = Flask(__name__)
@app.route('/')
def landing():
return render_template('index.html', volumes=get_volumes('Harry Potter'))
@app.route('/get_volume_info')
def get_volume_info_endpoint():
volume_id = request.args.get('volume_id')
if volume_id is None:
# Return an error if no volume id was provided
return jsonify({'error': 'must provide argument'}), 400
# To stop spamming the API
time.sleep(0.250)
# Request volume data
url = f'https://www.googleapis.com/books/v1/volumes/{volume_id}'
response = requests.get(url)
volume = response.json()
# Get the info using the helper function
volume_info = get_volume_info(volume, volume_id)
# Return json object with the info
return jsonify(volume_info), 200
def get_volumes(search):
# Make request
url = f'https://www.googleapis.com/books/v1/volumes?q={search}'
response = requests.get(url)
data = response.json()
# Get the volumes
volumes = data['items']
# Add list to store results
volume_info_collection = []
# Loop over the volumes
for volume in volumes:
volume_id = volume['id']
# Get volume info using helper function
volume_info = get_volume_info(volume, volume_id)
# Add it to the result
volume_info_collection.append(volume_info)
return volume_info_collection
def get_volume_info(volume, volume_id):
# Get basic information
volume_title = volume['volumeInfo']['title']
volume_authors = volume['volumeInfo']['authors']
# Set default value for thumbnail
volume_thumbnail = None
try:
volume_thumbnail = volume['volumeInfo']['imageLinks']['thumbnail']
except KeyError:
# Failed we keep the None value
print('Failed to get thumbnail')
# Fill in the dict
volume_info = {
'volume_id': volume_id,
'volume_title': volume_title,
'volume_authors': volume_authors,
'volume_thumbnail': volume_thumbnail
}
# Return volume info
return volume_info
if __name__ == '__main__':
app.run()
模板 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
let tracker = {}
function get_thumbnail(id) {
let url = '/get_volume_info?volume_id=' + id
fetch(url).then(function (response) {
return response.json();
}).then(function (data) {
console.log(data);
return data['volume_thumbnail']
}).catch(function () {
console.log("Error");
});
}
function image_load_failed(id) {
let element = document.getElementById(id)
if (isNaN(tracker[id])) {
tracker[id] = 0
}
console.log(tracker[id])
if (tracker[id] >= 5) {
element.src = 'https://via.placeholder.com/128x196C/O%20https://placeholder.com/'
return
}
element.src = get_thumbnail(id)
tracker[id]++
}
</script>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>Authors</th>
<th>Thumbnail</th>
</tr>
{% for volume in volumes %}
<tr>
<td>{{ volume['volume_id'] }}</td>
<td>{{ volume['volume_title'] }}</td>
<td>{{ volume['volume_authors'] }}</td>
<td><img id="{{ volume['volume_id'] }}" src="{{ volume['volume_thumbnail'] }}"
onerror="image_load_failed('{{ volume['volume_id'] }}')"></td>
</tr>
{% endfor %}
</table>
</body>
</html>