我试图在使用Flask构建应用程序时使用Goodread的api获取书籍的评论数据。这是我正在从称为CS50 Web编程系列的教程系列中执行的项目的一部分。
因此,我一直在尝试使用Python的Request
模块提取数据,并将该数据存储在变量中,然后进行Jsonify。这样,当用户键入/api/<a book's isbn number>
时,它应该返回一本书的Jsonified数据。
@app.route('/api/<isbn>', methods = ['GET'])
def isbn(isbn):
#import api from Goodreads (stats)
r = requests.get("https://www.goodreads.com/book/review_counts.json", params={"key": "L3FHyOR3IhCo3kctcUz3zg", "isbns": "isbn"}).json()
res = db.execute("SELECT * FROM books WHERE isbn = :isbn", {"isbn": isbn}).fetchone()
print ('res')
if res is None:
return "404 error"
return jsonify({
"title": res.title,
"author": res.author,
"year": res.year,
"isbn": res.isbn,
"review_count": r.reviews_count,
"average_score": r.average_rating
})
输入isbn时出现的错误看起来像这样。 http://prntscr.com/ojnwbw
看来我在定义
r
的那一行上犯了一个主要问题。有人可以帮助解决此问题吗? 最佳答案
删除“ isbn”周围的引号,如下所示:
坏:
>>> requests.get('https://www.goodreads.com/book/review_counts.json', params={"key": "[MY_API_KEY]", "isbns": "isbn"}).json()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
很好,发送变量的值而不是变量:
>>> isbn="0441172717"
>>> requests.get('https://www.goodreads.com/book/review_counts.json', params={"key": "[MY_API_KEY]", "isbns": isbn}).json()
{'books': [{'id': 47173379, 'isbn': '0441172717', 'isbn13': '9780441172719', 'ratings_count': 3, 'reviews_count': 8, 'text_reviews_count': 0, 'work_ratings_count': 625868, 'work_reviews_count': 1034615, 'work_text_reviews_count': 17000, 'average_rating': '4.22'}]}
更好:
...
r = requests.get("https://www.goodreads.com/book/review_counts.json", params={"key": "[MY_API_KEY]", "isbns": isbn})
if r.status_code != 200:
raise ValueError
...
最好:首先检查isbn的有效性,然后将db.execute()放在第一位。如果您的数据库没有结果,为什么还要打扰goodreads.com?除非,您指望goodreads.com来确保用户输入正确无误,并且可以防止您被注入...?
接下来,不要在公共问题中使用您的真实API密钥;)
最后,如果出现错误,requests.get(...)。json()将无法工作:
>>> requests.get('https://www.goodreads.com/book/review_counts.json')
<Response [422]>
来自goodreads.com/api:“您可以将ISBN10和ISBN13混合使用,但是如果您未指定任何内容,则会收到422错误;如果未找到,则将收到404错误。”
您正在发送“ isbns = isbn”,即没有真正有效的isbn。
希望这可以帮助!
从您的进一步评论中回答您的问题:
将上面的响应重新格式化为“漂亮的JSON”(用于复制+粘贴JSON字符串以美化的在线方式的Google JSON查看器),我们看到:
{
'books':[
{
'id':47173379,
'isbn':'0441172717',
'isbn13':'9780441172719',
'ratings_count':3,
'reviews_count':8,
'text_reviews_count':0,
'work_ratings_count':625902,
'work_reviews_count':1034690,
'work_text_reviews_count':17002,
'average_rating':'4.22'
}
]
}
现在,您也许可以看到响应是Dict(Response)-> Array(books)-> Dicts。
>>> r = requests.get('https://www.goodreads.com/book/review_counts.json', params={"key": "L3FHyOR3IhCo3kctcUz3zg", "isbns": isbn}).json()
>>> print(r)
{'books': [{'id': 47173379, 'isbn': '0441172717', 'isbn13': '9780441172719', 'ratings_count': 3, 'reviews_count': 8, 'text_reviews_count': 0, 'work_ratings_count': 625905, 'work_reviews_count': 1034694, 'work_text_reviews_count': 17002, 'average_rating': '4.22'}]}
>>> print(r['books'])
[{'id': 47173379, 'isbn': '0441172717', 'isbn13': '9780441172719', 'ratings_count': 3, 'reviews_count': 8, 'text_reviews_count': 0, 'work_ratings_count': 625905, 'work_reviews_count': 1034694, 'work_text_reviews_count': 17002, 'average_rating': '4.22'}]
>>> print(r['books'][0])
{'id': 47173379, 'isbn': '0441172717', 'isbn13': '9780441172719', 'ratings_count': 3, 'reviews_count': 8, 'text_reviews_count': 0, 'work_ratings_count': 625905, 'work_reviews_count': 1034694, 'work_text_reviews_count': 17002, 'average_rating': '4.22'}
>>> print(r['books'][0]['reviews_count'])
8
因此,您对属性错误的答案是使用:“ r ['books'] [0] ['reviews_count']”而不是“ r.reviews_count”以及“ r ['books'] [0] ['?其他属性的????']“格式。您还可以通过以下格式处理多个ISBN:“ ########,########,#######,...”,并根据API。
关于python - 使用Python和Flask制作应用时,出现json.decoder.JSONDecodeError,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57192919/