2016-07-01 2 views
1

Я создаю проект на основе графического интерфейса на Python с модулем tkinter. Он получает базовые данные от онлайн-судьи, например, SPOJ, используя Beautiful Soup. Я новичок в Python, поэтому большинство вещей, которые я написал, это базовые учебные пособия из Интернета. Однако, для определенной части кода, я полностью застрял.IndexError: индекс индекса вне диапазона в функции с помощью BeautifulSoup

import sys 
import urllib.request 
from bs4 import BeautifulSoup 
import re 

userName = 'xilinx' 
spojUrl = 'http://www.spoj.com/users/'+userName 

with urllib.request.urlopen(spojUrl) as x: 
    html = x.read() 
soup = BeautifulSoup(html, 'html.parser') 
# li - list of successful submissions 
li = soup.find_all('table', class_='table table-condensed')[0].find_all('td') 
listOfSolvedProblemCodes = [] 
    for submission in li: 
     problemCode = submission.get_text() 
     if problemCode: 
      listOfSolvedProblemCodes.append(problemCode) 
print (userName+ ' has solved',len(listOfSolvedProblemCodes),'problems on Spoj.') 

Эта часть кода работает нормально, когда я запускаю его с питона submissions.py

После тестирования этой части, я стараюсь, чтобы включить его в больший код, где возникает проблема. Я в том числе здесь соответствующий раздел кода:

В frame.py:

def compStats(): 
    if ch == "SPOJ": 
     stats.show(ch, userName) 

B2 = tkinter.Button(root, text="My Statistics", command=compStats) 
B2.place(anchor = W, x = 30, y = 220, width=200) 

В stats.py:

def show(ch, userName): 

    if ch == 'SPOJ': 

     spojUrl = 'http://www.spoj.com/users/'+userName 

     with urllib.request.urlopen(spojUrl) as x: 
      html = x.read() 
     soup = BeautifulSoup(html, 'html.parser') 
     li = soup.find_all('table', class_='table table-condensed')[0].find_all('td') 
     listOfSolvedProblemCodes = [] 
     for submission in li: 
      problemCode = submission.get_text() 
      if problemCode: 
       listOfSolvedProblemCodes.append(problemCode) 


    # then collect more information from soup and print it through labels in another window 

    det = tkinter.Tk() 
    det.title("Statistics") 
    det.geometry("800x600") 

Но проблема IndexError происходит в stats.py в строке :

li = soup.find_all('table', class_='table table-condensed')[0].find_all('td') 

Exception in Tkinter callback

Traceback (most recent call last):

File "C:\Users\Aa\AppData\Local\Programs\Python\Python35-32\lib\tkinter__init .py", line 1550, in __call

return self.func(*args)

File "frame.py", line 34, in compStats

stats.show(ch, userName)

File "C:\Users\Aa\AppData\Local\Programs\Python\Python35-32\stats.py", line 17, in show

li = soup.find_all('table', class_='table table-condensed')[0].find_all('td')

IndexError: list index out of range

Я не могу понять, почему код не может работать здесь. Пожалуйста помоги!

ответ

3

Первый шаг в отладке заключается в том, чтобы взять сложную строку, которая выдает ошибку и упрощает ее. Затем вы можете проверить промежуточные значения, чтобы убедиться, что предположения, которые вы делаете о коде, верны. В этом случае ваше предположение состоит в том, что soup.find_all('table', ...) действительно что-то наводит.

Например, изменить:

li = soup.find_all('table', class_='table table-condensed')[0].find_all('td') 

к этому:

tables = soup.find_all('table', class_='table table-condensed') 
li = tables[0].find_all('td') 

Далее добавьте оператор печати для изучения tmp:

print("tables is", tables) 

Вы увидите, что tables является вероятно, пустой, поэтому, когда вы пытаетесь сделать tables[0], вы получаете поскольку индекс 0 выходит за пределы допустимого диапазона.

+0

Я попробовал предложенный вами подход и нашел ту же проблему, что и таблицы пустые. Но из html-файла я знаю, что таблицы не должны быть пустыми. И то же самое подтверждается, когда я запускаю этот фрагмент кода отдельно, он дает ответ 3138, то есть число проблем, решаемых, и в этом случае также число тд-тегов. Следовательно, путаница. Почему одна и та же часть кода ведет себя по-другому? – Neha

+0

По той же причине я поставил полный код, который я запускаю отдельно и получаю ответ. Чтобы другие могли также запустить его и проверить. Но как только я помещаю его в функцию, он показывает ошибку индекса за пределами. – Neha

+0

@Neha: если вы получаете разные выходы, вы, вероятно, используете разные входы. Вы подтвердили свое предположение, что во всех случаях вы вводите одни и те же данные - не только одни и те же имена переменных, но и фактическое содержимое переменных? Возможно, «имя пользователя» - это не то, что вы думаете. –

Смежные вопросы