我试图在使用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/

10-12 05:44