2017-01-25 8 views
0

ここに私の状況です:私のコードは電子メール内のHTMLテーブルのデータを解析します。私がやっているロードブロッキングは、下の写真にあるように、テーブルの真ん中に空白の空行があることです。この空白スペースは、セルからテキストを抽出しようとするため、私のコードは失敗します(IndexError: list index out of range)。IndexErrorをバイパスする方法

Pythonに言うことができますか? "この空白の行から来るこのエラーが発生した場合は、ここで停止してテキストを取得した行を取り出し、残りのコードを実行してくださいそれら "...?

これは、この問題のダム解決策のように聞こえるかもしれませんが、私のプロジェクトでは、常にテーブルの最新の日付からデータを取り込みます。常に最初の数行の中にあります。

「このエラーが発生した場合は、無視して続行してください」と言うことができる場合は、その方法を学習したいと思います。そうでなければ、私はこれを回避する別の方法を見つけなければならないでしょう。すべての助けをありがとう。ギャップの

テーブル:enter image description here

マイコード:

from bs4 import BeautifulSoup, NavigableString, Tag 
import pandas as pd 
import numpy as np 
import os 
import re 
import email 
import cx_Oracle 

dsnStr = cx_Oracle.makedsn("sole.nefsc.noaa.gov", "1526", "sole") 
con = cx_Oracle.connect(user="user", password="password", dsn=dsnStr) 

def celltext(cell): 
    '''  
     textlist=[] 
     for br in cell.findAll('br'): 
      next = br.nextSibling 
      if not (next and isinstance(next,NavigableString)): 
       continue 
      next2 = next.nextSibling 
      if next2 and isinstance(next2,Tag) and next2.name == 'br': 
       text = str(next).strip() 
       if text: 
        textlist.append(next) 
     return (textlist) 
    ''' 
    textlist=[] 
    y = cell.find('span') 
    for a in y.childGenerator(): 
     if isinstance(a, NavigableString): 
      textlist.append(str(a)) 
    return (textlist) 

path = 'Z:\\blub_2' 

for filename in os.listdir(path): 
    file_path = os.path.join(path, filename) 
    if os.path.isfile(file_path): 
     html=open(file_path,'r').read() 
     soup = BeautifulSoup(html, 'lxml') # Parse the HTML as a string 
     table = soup.find_all('table')[1] # Grab the second table 

df_Quota = pd.DataFrame() 

for row in table.find_all('tr'):  
    columns = row.find_all('td') 
    if columns[0].get_text().strip()!='ID': # skip header 
     Quota = celltext(columns[1]) 
     Weight = celltext(columns[2]) 
     price = celltext(columns[3]) 

     print(Quota) 

     Nrows= max([len(Quota),len(Weight),len(price)]) #get the max number of rows 

     IDList = [columns[0].get_text()] * Nrows 
     DateList = [columns[4].get_text()] * Nrows 

     if price[0].strip()=='Package': 
      price = [columns[3].get_text()] * Nrows 

     if len(Quota)<len(Weight):#if Quota has less itmes extend with NaN 
      lstnans= [np.nan]*(len(Weight)-len(Quota)) 
      Quota.extend(lstnans) 

     if len(price) < len(Quota): #if price column has less items than quota column, 
      val = [columns[3].get_text()] * (len(Quota)-len(price)) #extend with 
      price.extend(val)          #whatever is in 
                    #price column 

     #if len(DateList) > len(Quota): #if DateList is longer than Quota, 
      #print("it's longer than") 
      #value = [columns[4].get_text()] * (len(DateList)-len(Quota)) 
      #DateList = value * Nrows 

     if len(Quota) < len(DateList): #if Quota is less than DateList (due to gap), 
      stu = [np.nan]*(len(DateList)-len(Quota)) #extend with NaN 
      Quota.extend(stu) 

     if len(Weight) < len(DateList): 
      dru = [np.nan]*(len(DateList)-len(Weight)) 
      Weight.extend(dru) 

     FinalDataframe = pd.DataFrame(
     { 
     'ID':IDList,  
     'AvailableQuota': Quota, 
     'LiveWeightPounds': Weight, 
     'price':price, 
     'DatePosted':DateList 
     }) 

     df_Quota = df_Quota.append(FinalDataframe, ignore_index=True) 
     #df_Quota = df_Quota.loc[df_Quota['DatePosted']=='5/20'] 
     df_Q = df_Quota['DatePosted'].iloc[0] 
     df_Quota = df_Quota[df_Quota['DatePosted'] == df_Q] 
print (df_Quota) 

for filename in os.listdir(path): 
    file_path = os.path.join(path, filename) 
    if os.path.isfile(file_path): 
     with open(file_path, 'r') as f: 
      pattern = re.compile(r'Sent:.*?\b(\d{4})\b') 
      email = f.read() 
      dates = pattern.findall(email) 
      if dates: 
       print("Date:", ''.join(dates)) 

#cursor = con.cursor() 
#exported_data = [tuple(x) for x in df_Quota.values] 
#sql_query = ("INSERT INTO ROUGHTABLE(species, date_posted, stock_id, pounds, money, sector_name, ask)" "VALUES (:1, :2, :3, :4, :5, 'NEFS 2', '1')") 
#cursor.executemany(sql_query, exported_data) 
#con.commit() 

#cursor.close() 
#con.close() 
+0

'catch'があった場合だけ...' 'try' catch'とIndexError'は –

+0

@Sarathspを無視'引く上を使用しています。 – tdelaney

+0

例外ハンドラを使用したり、それらのインデックスを作成する前にサイズのチェックを行うことができます。これは非常に多くのコードであり、このエラーが実際に起こっている場所についてのヒントはありません。これを簡単な例に煮詰めることができれば、それは解決策に役立ちます。 – tdelaney

答えて

1

継続は空/問題のある行をスキップするために使用するキーワードです。 IndexErrorは、空の列リストのcolumns[0]にアクセスしようとしたおかげです。例外がある場合は次の行にスキップしてください。

for row in table.find_all('tr'): 
    columns = row.find_all('td') 
    try: 
     if columns[0].get_text().strip()!='ID': 
     # Rest as above in original code. 
    except IndexError: 
     continue 
+0

だから、同じ行に同じエラーが発生しました( 'price = celltext(columns [3])') – theprowler

+1

つまり、空の行だけでなく、より少ない列の行おそらく4より)。その後、明らかな解決策はtry..exceptです。 ** continue **を 'except IndexError'ブロックに移動します。 –

1

使用try: ... except: ...

try: 
    #extract data from table 
except IndexError: 
    #execute rest of program 
関連する問題