2016-08-17 1 views
1

J'ai écrit un script Python qui s'exécute à partir d'une instance AWS et récupère les fichiers xml d'un serveur S3 pour les placer dans un dossier sur l'instance. Le script fonctionne très bien, à l'exception du fait que, après environ une heure et demie, soit environ le temps qu'il faut pour aller chercher 10.000-15.000 xmls, je reçois l'erreur suivante:Le script webscraping Python sur AWS continue à échouer après 1,5 heures/aller chercher 10 000 xmls

HTTP Error 500: Internal Server Error 

Après cette erreur, je suis a dit que le dossier que je dis le script de placer le dans xml récupéré ne peut être trouvée, à savoir

[Errno 2] No such file or directory: 

J'ai essayé de lancer ce script à la fois de ssh, en utilisant l'écran et en utilisant nohup, mais je reçois le même problème chaque fois. Comme j'ai environ 200 000 xml à récupérer, je voudrais juste exécuter ce script une fois et faire quelque chose d'autre pour les 20 heures et plus dont il a besoin pour fonctionner.

Pour référence, le script que j'ai écrit est ci-dessous:

import os 

import feather 

df = feather.read_dataframe('avail.feather') 

import xmltodict 

urls = df['URL'] 

import urllib.request 
import time 
import requests 

ticker=0 
start = time.time() 
for u in urls[ticker:len(urls)]: 
    #os.chdir('/home/stan/Documents/Dissertation Idea Box/IRS_Data') 
    ticker += 1 
    print("Starting URL",ticker, "of", len(urls),"........." ,(ticker/len(urls))*100, "percent done") 
    if u is None: 
     print("NO FILING") 
     end = time.time() 
     m, s = divmod(end-start, 60) 
     h, m = divmod(m, 60) 
     print("Elapsed Time:","%02d:%02d:%02d" % (h, m, s))   
     continue 

    u = u.replace('https','http') 
    r = requests.get(u)  
    doc = xmltodict.parse(r.content) 
    try: 
     os.chdir("irs990s") 
     urllib.request.urlretrieve(u, u.replace('http://s3.amazonaws.com/irs-form-990/','')) 
     print("FETCHED!","..........",u) 
    except Exception as e: 
     print("ERROR!!!","..........",u) 
     print(e) 
     end = time.time() 
     m, s = divmod(end-start, 60) 
     h, m = divmod(m, 60) 
     print("Elapsed Time:","%02d:%02d:%02d" % (h, m, s)) 
     continue 
    end = time.time() 
    m, s = divmod(end-start, 60) 
    h, m = divmod(m, 60) 
    print("Elapsed Time:","%02d:%02d:%02d" % (h, m, s)) 
    os.chdir('..') 

Répondre

2

Je ne sais pas la première chose à propos de python, mais le problème semble assez évident, tout de même. Lorsque l'erreur S3 se produit, vous continue, qui ignore le reste des instructions dans la boucle la plus proche, et continue avec la valeur suivante, du haut de la boucle ... et cela saute os.chdir('..') à la fin de la boucle, donc votre répertoire de travail actuel est toujours irs990s. À l'itération suivante, os.chdir("irs990s"), bien sûr, échouera, parce que c'est en essayant de trouver un répertoire appelé irs990sà l'intérieur le répertoire then-current, qui est bien sûr déjà irs990s, donc cela échouerait bien sûr.

Voici quelques leçons.

Ne continuez pas à entrer et sortir d'un répertoire en utilisant os.chdir('..') - c'est très mauvais, sujettes à des bugs subtils. Cas au point, voir ci-dessus. Utilisez des chemins absolus. Si vous voulez vraiment des chemins relatifs, c'est bien, mais ne le faites pas de cette façon. Capturez le répertoire de travail au démarrage ou configurez un répertoire de travail de base et utilisez-le pour qualifier complètement vos chemins avec chdir.

Concevez votre code pour anticiper les erreurs occasionnelles de la part de S3, ou de n'importe quel service Web, de n'importe quel fournisseur, et réessayez les erreurs 5XX après un bref délai d'incrémentation - exponential backoff.

+0

Ce conseil est juste sur l'argent. J'ai refait le code ce matin et maintenant il fonctionne depuis 7 heures sans problème. Je vous remercie! – StanO