2016-10-19 3 views
0

Ich arbeite an einer Reihe von Skripts, die URLs aus einer Datenbank abruft und die textstat package verwendet, um die Lesbarkeit der Seite basierend auf einer Reihe von vordefinierten Berechnungen zu berechnen. Die folgende Funktion nimmt eine URL (von einer CouchDB), berechnet die definierten Lesbarkeitswerte und speichert die Ergebnisse dann im selben CouchDB-Dokument.Weiter auf Ausnahme in Python

Das Problem, das ich habe, ist mit der Fehlerbehandlung. Als ein Beispiel erfordert die Berechnung der Flesche-Lese-Ease-Punktzahl eine Zählung der Gesamtzahl von Sätzen auf der Seite. Wenn dies als Null zurückkehrt, wird eine Ausnahme ausgelöst. Gibt es eine Möglichkeit, diese Ausnahme zu erfassen, eine Notiz der Ausnahme in der Datenbank zu speichern und zur nächsten URL in der Liste überzugehen? Kann ich dies in der Funktion unten (bevorzugt) tun, oder muss ich das Paket selbst bearbeiten?

Ich weiß Variationen dieser Frage wurden zuvor gefragt. Wenn Sie eines kennen, das meine Frage beantworten könnte, weisen Sie mich bitte in diese Richtung. Meine Suche war bisher fruchtlos. Danke im Voraus.

def get_readability_data(db, url, doc_id, rank, index): 
    readability_data = {} 
    readability_data['url'] = url 
    readability_data['rank'] = rank 
    user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' 
    headers = { 'User-Agent' : user_agent } 
    try: 
     req = urllib.request.Request(url) 
     response = urllib.request.urlopen(req) 
     content = response.read() 
     readable_article = Document(content).summary() 
     soup = BeautifulSoup(readable_article, "lxml") 
     text = soup.body.get_text() 
     try: 
      readability_data['flesch_reading_ease'] = textstat.flesch_reading_ease(text) 
      readability_data['smog_index'] = textstat.smog_index(text) 
      readability_data['flesch_kincaid_grade'] = textstat.flesch_kincaid_grade(text) 
      readability_data['coleman_liau'] = textstat.coleman_liau_index(text) 
      readability_data['automated_readability_index'] = textstat.automated_readability_index(text) 
      readability_data['dale_chall_score'] = textstat.dale_chall_readability_score(text) 
      readability_data['linear_write_formula'] = textstat.linsear_write_formula(text) 
      readability_data['gunning_fog'] = textstat.gunning_fog(text) 
      readability_data['total_words'] = textstat.lexicon_count(text) 
      readability_data['difficult_words'] = textstat.difficult_words(text) 
      readability_data['syllables'] = textstat.syllable_count(text) 
      readability_data['sentences'] = textstat.sentence_count(text) 
      readability_data['readability_consensus'] = textstat.text_standard(text) 
      readability_data['readability_scores_date'] = time.strftime("%a %b %d %H:%M:%S %Y") 

      # use the doc_id to make sure we're saving this in the appropriate place 
      readability = json.dumps(readability_data, sort_keys=True, indent=4 * ' ') 
      doc = db.get(doc_id) 
      data = json.loads(readability) 
      doc['search_details']['search_details'][index]['readability'] = data 
      #print(doc['search_details']['search_details'][index]) 
      db.save(doc) 
      time.sleep(.5) 

     except: # catch *all* exceptions 
      e = sys.exc_info()[0] 
      write_to_page("<p>---ERROR---: %s</p>" % e) 

    except urllib.error.HTTPError as err: 
     print(err.code) 

Dies ist der Fehler, den ich erhalten:

Error(ASL): Sentence Count is Zero, Cannot Divide 
Error(ASyPW): Number of words are zero, cannot divide 
Traceback (most recent call last): 
    File "new_get_readability.py", line 114, in get_readability_data 
    readability_data['flesch_reading_ease'] = textstat.flesch_reading_ease(text) 
    File "/Users/jrs/anaconda/lib/python3.5/site-packages/textstat/textstat.py", line 118, in flesch_reading_ease 
    FRE = 206.835 - float(1.015 * ASL) - float(84.6 * ASW) 
TypeError: unsupported operand type(s) for *: 'float' and 'NoneType' 

Dies ist der Code, der die Funktion aufruft:

if __name__ == '__main__': 
    db = connect_to_db(parse_args()) 
    print("~~~~~~~~~~" + " GETTING IDs " + "~~~~~~~~~~") 
    ids = get_ids(db) 
    for i in ids: 
     details = get_urls(db, i) 
     for d in details: 
      get_readability_data(db, d['url'], d['id'], d['rank'], d['index']) 
+0

Sie natürlich wissen, wie 'verwenden try' /' except' so bin ich ein schweres Problem mit zu verstehen, was das Problem ist. –

+1

überprüfen Sie ASL und ASW, einer von ihnen möglicherweise keine – TurtleIzzy

+0

Danke, @MarkRansom. Ich dachte, ich würde versuchen/außer, aber es verhält sich nicht so, wie ich es erwarten würde (also gibt es irgendwo eine Wissenslücke). Diese Ausnahme wird von einer der Funktionen im textstat-Paket ausgelöst. Daher möchte ich wissen, ob ich das Paket selbst bearbeiten muss, um es zu umgehen, oder ob es eine andere Option gibt. – Ryan

Antwort

0

Es ist im Allgemeinen gute Praxis try: except: Blöcke so gering wie möglich zu halten . Ich würde Ihre textstat Funktionen in eine Art Decorator wickeln, die die Ausnahme abfangen, die Sie erwarten, und gibt die Funktionsausgabe und die Ausnahme zurück, die gefangen wird.

zum Beispiel:

def catchExceptions(exception): #decorator with args (sorta boilerplate) 
    def decorator(func): 
     def wrapper(*args, **kwargs): 
      try: 
       retval = func(*args, **kwargs) 
      except exception as e: 
       return None, e 
      else: 
       return retval, None 
     return wrapper 
    return decorator 

@catchExceptions(ZeroDivisionError) 
def testfunc(x): 
    return 11/x 

print testfunc(0) 
print '-----' 
print testfunc(3) 

druckt:

(None, ZeroDivisionError('integer division or modulo by zero',)) 
----- 
(3, None) 
Verwandte Themen