【问题标题】:IndexError: list index out of range in a function using BeautifulSoupIndexError:在使用 BeautifulSoup 的函数中列出超出范围的索引
【发布时间】:2016-11-03 19:07:32
【问题描述】:

我正在使用模块 tkinter 在 Python 中制作一个基于 GUI 的项目。它从在线评委那里获取基本数据,例如,使用 Beautiful Soup 的 SPOJ。我是 Python 的新手,所以我写的大部分内容都是来自互联网的基本教程。然而,对于一段特定的代码,我完全被困住了。

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.')

这部分代码在我使用 python submits.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')

Tkinter 回调异常

Traceback(最近一次调用最后一次):

文件 "C:\Users\Aa\AppData\Local\Programs\Python\Python35-32\lib\tkinter__init .py",第 1550 行,在 __call 中

返回 self.func(*args)

文件“frame.py”,第 34 行,在 compStats 中

stats.show(ch, userName)

文件 "C:\Users\Aa\AppData\Local\Programs\Python\Python35-32\stats.py", 第 17 行,显示中

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

IndexError: 列表索引超出范围

我无法理解为什么代码无法在这里工作。请帮忙!

【问题讨论】:

    标签: python tkinter beautifulsoup indexoutofrangeexception


    【解决方案1】:

    调试此问题的第一步是采用引发错误的复杂行并使其更简单。然后,您可以检查中间值,以查看您对代码所做的假设是否正确。在这种情况下,您的假设是 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 超出范围。

    【讨论】:

    • 我尝试了您建议的方法并发现了同样的问题,即表格为空。但是从 html 文件中,我知道表格不应该为空。当我单独运行这段代码时,同样的事情得到了证实,它给出了答案 3138,即解决的问题数量,在这种情况下,还有 td 标签的数量。因此,混乱。为什么同一段代码的行为不同?
    • 出于同样的原因,我把我单独运行的完整代码放了出来,得到了答案。这样其他人也可以运行它并检查。但是一旦我把它放入函数中,它就会显示索引超出范围的错误。
    • @Neha:如果你得到不同的输出,你可能会给出不同的输入。您是否验证了您在所有情况下都提供相同输入的假设——不仅仅是相同的变量名称,而是变量的实际内容?也许username 不是你想的那样。
    • 非常感谢!作为 Python 的新手,变量的范围让我陷入了很多困境,以至于我什至无法意识到这可能是原因!现在会弄清楚这一点。 :)
    • @Neha:调试任何问题的第一步:验证您的假设。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 2021-06-30
    • 2019-04-08
    • 2019-04-24
    • 1970-01-01
    相关资源
    最近更新 更多