【问题标题】:requests.get(X).json(): JSONDecodeError: Expecting value: line 1 column 1 (char 0)requests.get(X).json():JSONDecodeError:预期值:第 1 行第 1 列(字符 0)
【发布时间】:2021-06-22 20:37:48
【问题描述】:

我想从一个 api 中获取所有提名(未获奖)的电影,以便我可以清理它并查看与每部电影相关的预算。

我的代码:

class Oscars():
    '''
    Hits data file url that I downloaded and pushed to git - https://raw.githubusercontent.com/TobyChen320/yipitdata/main/data/movies -
    And returns every Oscar nominated movie and its budget along with the average budget.
    '''
    def __init__(self):
        self.base_url = 'https://raw.githubusercontent.com/TobyChen320/yipitdata/main/data/movies'
        # create a list of dictionaries that stores film title, year, url, and budget
        self.losing_films = []
  
    def search(self):
        '''
        Searches the data to return losing movies.
        This will also add the movies that fit the criteria into losing_films.
        '''
        main = requests.get(self.base_url).json()
        yearly_list = main['results']
        # loop through the results from main to get each year's nominations
        for year in yearly_list:
            yearly_films = year['films']
        # loop through each film every year to find the winners
            for films in yearly_films:
                # if the film is not a winner add to losing_films list
                if films['Winner'] != True:
                    loser = {}
                    loser['film'] = films['Film']
                    loser['year'] = year['year']
                    loser['url'] = films['Detail URL']
                    self.losing_films.append(loser)

    def get_budget(self):
        '''
        Returns budget of each non-winning film from its Detail URL page.
        '''
        for film in self.losing_films:
            movie = requests.get(film['url']).json()
            # if there is no budget data; I just set it to None (You can change this to fill the missing value with whatever you desire depending on what you are looking for)
            film['budget'] = movie.get('Budget', None)

错误:

JSONDecodeError:预期值:第 1 行第 1 列(字符 0)

如果我要将if films['Winner'] != True 更改为if films['Winner'] == True;代码运行没有问题,但它会给我赢家。我想知道我的逻辑缺陷在哪里以及如何解决。

【问题讨论】:

  • 在解析 JSON 之前检查响应代码。
  • print(requests.get(self.base_url)) 显示什么?
  • 你得到的响应不是 JSON - 你需要在解码之前检查它。
  • @ForceBru print(requests.get(self.base_url)) 给我 200 的主要 api。问题是从films['Detail URL'] 访问某些网址。 @Markus Rosjat 给了我一个很好的解决方案,它使用了.status_code == 200(我不知道那里有这么方便的东西)。

标签: python json python-requests


【解决方案1】:

好的,让我们进行一些挖掘,这只是快速而肮脏的,以表明详细信息 URL 会在没有预算键的情况下发回 dicts ..

import requests

test = requests.get('https://raw.githubusercontent.com/TobyChen320/yipitdata/main/data/movies')

foo = test.json()['results']

for f in foo:
    films = f['films']
    for film in films:
        if film['Winner'] != True:
            test2 = requests.get(film['Detail URL'])
            print([ k for k in test2.json().keys()])

给你类似的东西

python3.9 ~/test_request.py
[' Production company ', ' Release dates ', ' Running time ', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Edited by', 'Language', 'Produced by', 'Starring', 'Title', 'Written by']
[' Release dates ', ' Running time ', 'Based on', 'Box office', 'Budget', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Edited by', 'Language', 'Produced by', 'Screenplay by', 'Starring', 'Title', 'Written by']
[' Release dates ', ' Running time ', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Language', 'Produced by', 'Starring', 'Title', 'Written by']
[' Release dates ', ' Running time ', 'Box office', 'Budget', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Edited by', 'Language', 'Music by', 'Produced by', 'Starring', 'Title', 'Written by']
[' Release dates ', ' Running time ', 'Box office', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Edited by', 'Language', 'Produced by', 'Starring', 'Title', 'Written by']
[' Release dates ', ' Running time ', 'Budget', 'Cinematography', 'Country', 'Directed by', 'Distributed by', 'Edited by', 'Language', 'Music by', 'Starring', 'Title', 'Written by']

如您所见,第一个 url 中没有 Budget 键,因此您可能想在尝试访问该值之前检查该键。

if 'Budget' in test2.json().keys():

对于我的片段中的thest,这只会打印带有预算键的结果

更新

您的某些 URL 返回的 status_code 不是 200,因此不会有要转换为 JSON 的数据

Les Misérables
http://oscars.yipitdata.com/films/Les_Mis%C3%A9rables_(2012_film)
403

因此您可能需要在执行 .json() 之前检查状态代码

def get_budget(self):
    '''
    Returns budget of each non-winning film from its Detail URL page.
    '''
    for film in self.losing_films:
        movie = requests.get(film['url'])
        if movie.status_code == 200:

            # if there is no budget data; I just set it to None (You can change this to fill the missing value with whatever you desire depending on what you are looking for)
            film['budget'] = movie.json().get('Budget', None)

干杯

马库斯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 2013-05-10
    • 2019-02-25
    相关资源
    最近更新 更多