2017-01-25 3 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

просто использовать '' try' catch' и ловить 'IndexError' игнорировать –

+0

@Sarathsp ... если был' catch'. – 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). Тогда очевидное решение - попытка ... кроме. Переместите ** continue ** в блок 'except IndexError'. –

1

Использование try: ... except: ...:

try: 
    #extract data from table 
except IndexError: 
    #execute rest of program