2017-04-10 1 views
0

J'ai le code python suivant qui fonctionne correctement pour utiliser l'API de reddit et rechercher la page d'accueil de différents subreddits et leurs soumissions croissantes.Comment éviter d'avoir une KeyError sporadique: 'data' lors de l'utilisation de l'API Reddit en python?

from pprint import pprint 
import requests 
import json 
import datetime 
import csv 
import time 

subredditsToScan = ["Arts", "AskReddit", "askscience", "aww", "books", "creepy", "dataisbeautiful", "DIY", "Documentaries", "EarthPorn", "explainlikeimfive", "food", "funny", "gaming", "gifs", "history", "jokes", "LifeProTips", "movies", "music", "pics", "science", "ShowerThoughts", "space", "sports", "tifu", "todayilearned", "videos", "worldnews"] 

ofilePosts = open('posts.csv', 'wb') 
writerPosts = csv.writer(ofilePosts, delimiter=',') 

ofileUrls = open('urls.csv', 'wb') 
writerUrls = csv.writer(ofileUrls, delimiter=',') 

for subreddit in subredditsToScan: 
    front = requests.get(r'http://www.reddit.com/r/' + subreddit + '/.json') 
    rising = requests.get(r'http://www.reddit.com/r/' + subreddit + '/rising/.json') 

    front.text 
    rising.text 

    risingData = rising.json() 
    frontData = front.json() 

    print(len(risingData['data']['children'])) 
    print(len(frontData['data']['children'])) 
    for i in range(0, len(risingData['data']['children'])): 
     author = risingData['data']['children'][i]['data']['author'] 
     score = risingData['data']['children'][i]['data']['score'] 
     subreddit = risingData['data']['children'][i]['data']['subreddit'] 
     gilded = risingData['data']['children'][i]['data']['gilded'] 
     numOfComments = risingData['data']['children'][i]['data']['num_comments'] 
     linkUrl = risingData['data']['children'][i]['data']['permalink'] 
     timeCreated = risingData['data']['children'][i]['data']['created_utc'] 

     writerPosts.writerow([author, score, subreddit, gilded, numOfComments, linkUrl, timeCreated]) 
     writerUrls.writerow([linkUrl]) 



    for j in range(0, len(frontData['data']['children'])): 
     author = frontData['data']['children'][j]['data']['author'].encode('utf-8').strip() 
     score = frontData['data']['children'][j]['data']['score'] 
     subreddit = frontData['data']['children'][j]['data']['subreddit'].encode('utf-8').strip() 
     gilded = frontData['data']['children'][j]['data']['gilded'] 
     numOfComments = frontData['data']['children'][j]['data']['num_comments'] 
     linkUrl = frontData['data']['children'][j]['data']['permalink'].encode('utf-8').strip() 
     timeCreated = frontData['data']['children'][j]['data']['created_utc'] 

     writerPosts.writerow([author, score, subreddit, gilded, numOfComments, linkUrl, timeCreated]) 
     writerUrls.writerow([linkUrl]) 

Il fonctionne bien et écorchures les données avec précision, mais il est constamment interrompu, apparemment au hasard, et a un accident de temps d'exécution, en disant:

Traceback (most recent call last): 
    File "dataGather1.py", line 27, in <module> 
    for i in range(0, len(risingData['data']['children'])): 
KeyError: 'data' 

Je ne sais pas pourquoi cette erreur est INTERVENUES sur et off et pas toujours. J'ai pensé que j'appelais peut-être trop l'API, alors ça m'empêche d'y accéder, alors j'ai mis un peu de sommeil dans mon code, mais cela n'a pas aidé. Des idées?

Répondre

1

Lorsqu'il n'y a pas de données sur la réponse de l'API, il n'y a pas de données clés sur le dictionnaire, donc vous obtenez une erreur keyError sur certains subreddits. Vous devez utiliser un try try

0

Le fichier json que vous analysez ne contient pas l'élément 'data'. Ainsi, vous obtenez une erreur. Je pense que votre intuition est correcte cependant. Il s'agit probablement d'une limitation de débit, ou vous demandez des entrées masquées/effacées.

Reddit est très strict sur l'accès à leur API sans jouer sympa. Cela signifie que vous devez enregistrer votre application et utiliser un user-agent significatif pour vos requêtes, et vous devriez probablement utiliser la bibliothèque python pour ce genre de chose: https://praw.readthedocs.io/en/latest/

Sans m'inscrire, il semble à mon expérience que l'API directe reddit de REST est encore plus stricte que la règle de 1 requête par 2 secondes qu'ils ont (eu?).

0

Python déclenche une erreur KeyError chaque fois qu'un objet dict() est demandé (en utilisant le format a = adict [key]) et que la clé n'est pas dans le dictionnaire.

Il semble que lorsque vous obtenez cette erreur, la valeur de vos données est vide.

Vous pourriez essayer d'obtenir la longueur du dictionnaire avant d'exécuter la boucle for. Si c'est vide, ça ne fonctionnera pas. Une vérification d'erreur intéressante ici pourrait aider.

size = len(risingData) 
if size: 
    for i in range(0,size): 
    …