2016-10-19 16 views
0

データベースからURLを取得し、textstat packageを使用して一連の定義済み計算に基づいてページの可読性を計算する一連のスクリプトを作成しています。以下の関数はURL(CouchDBから)を取得し、定義された可読性スコアを計算してから、そのスコアを同じCouchDBドキュメントに保存します。Pythonで例外が発生し続ける

問題はエラー処理にあります。一例として、Flesch Reading Easeスコア計算には、ページ上の文の総数が必要です。これがゼロとして返されると、例外がスローされます。この例外をキャッチし、データベースに例外のメモを保存し、リストの次のURLに移動する方法はありますか?以下の機能(推奨)でこれを行うことはできますか、またはパッケージ自体を編集する必要がありますか?

私はこの質問のバリエーションが以前に尋ねられていることを知っています。私の質問に答えるかもしれないことが分かっているなら、その方向で私を指摘してください。これまで私の検索は無益でした。前もって感謝します。

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) 

これは私が受け取るエラーです:

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' 

これは、関数を呼び出すコードです:

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

あなたは明らかに私は問題が何であるかを理解する困難な問題を抱えている 'try' /' except'を使用する方法を知っています。 –

+1

ASLとASWをチェックすると、いずれかがNone – TurtleIzzy

+0

ありがとう、@ MarkRansom。私はtry/exceptも理解していると思っていたが、期待通りに動作していない(どこかに知識のギャップがある)。この例外は、textstatパッケージの関数の1つによってスローされています。そのため、パッケージ自体を編集する必要があるかどうか、または別のオプションがあるかどうかを知りたいと思います。 – Ryan

答えて

0

可能な限り小さくtry: except:ブロックを維持するために、一般的に良い方法です。私はtextstat関数を何らかの並べ替えのデコレータでラップして、期待する例外をキャッチし、関数出力とキャッチされた例外を返します。例えば

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) 

プリント:

(None, ZeroDivisionError('integer division or modulo by zero',)) 
----- 
(3, None) 
関連する問題