美丽的汤,列表索引超出范围

时间:2019-10-20 18:05:43

标签: python python-3.x parsing web-scraping beautifulsoup

我查看了站点html源,发现我需要namePlayer,它是4列和'a'标签。我试图用answers.append'namePlayer': cols[3].a.text找到它

但是当我遵循它时,我得到了IndexError。然后我尝试将索引更改为2,3,4,5,但是什么也没有。

问题:为什么我得到IndexError:当一切正常时列出索引超出范围(我认为:D)

来源:

#!/usr/bin/env python3

import re
import urllib.request
from bs4 import BeautifulSoup

class AppURLopener(urllib.request.FancyURLopener):
    version = "Mozilla/5.0"


def get_html(url):
    opener = AppURLopener()
    response = opener.open(url)
    return response.read()

def parse(html):
    soup = BeautifulSoup(html)
    table = soup.find(id='answers')

    answers = []

    for row in table.find_all('div')[16:]:
        cols = row.find_all('div')

    answers.append({
        'namePlayer': cols[3].a.text
    })


    for answer in answers:
        print(answers)


def main():
    parse(get_html('http://jaze.ru/forum/topic?id=50&page=1'))

if __name__ == '__main__':
    main()

3 个答案:

答案 0 :(得分:0)

听起来好像您正在提供一个列表元素不存在的索引。请记住,索引从0开始。例如:0、1、2、3。因此,如果我要求元素10,则会出现索引错误。

答案 1 :(得分:0)

您正在循环中覆盖colscols的最后一个长度为零,因此是您的错误。

for row in table.find_all('div')[16:]:
    cols = row.find_all('div')
    print(len(cols))

运行上面的命令,您将看到cols的长度为0。

这也可能在循环的其他地方发生,因此您应该测试长度并确定逻辑是否需要更新。另外,您需要考虑是否有子a标签。

因此,您可以例如执行以下操作(要求bs4 4.7.1 +):

answers = []

for row in table.find_all('div')[16:]:
    cols = row.find_all('div:has(>a)')
    if len(cols) >= 3:
         answers.append({
        'namePlayer': cols[3].a.text
    })

请注意,answers已正确缩进,因此您正在使用每个cols值。这可能不适合您的确切用例,因为我不确定您想要的结果是什么。如果您声明所需的输出,我将进行相应的更新。


编辑:

playerNames

from bs4 import BeautifulSoup as bs
import requests

r = requests.get('https://jaze.ru/forum/topic?id=50&page=1')
soup = bs(r.content, 'lxml')
answer_blocks = soup.select('[id^=answer_]')
names = [i.text.strip() for i in soup.select('[id^=answer_] .left-side a')]
unique_names = {i.text.strip() for i in soup.select('[id^=answer_] .left-side a')}

您可以保留订单并使用OrderedDict进行重复数据删除(由@Michael-该问答中的其他解决方案)

from bs4 import BeautifulSoup as bs
import requests
from collections import OrderedDict

r = requests.get('https://jaze.ru/forum/topic?id=50&page=1')
soup = bs(r.content, 'lxml')
answer_blocks = soup.select('[id^=answer_]')
names = [i.text.strip() for i in soup.select('[id^=answer_] .left-side a')]
unique_names = OrderedDict.fromkeys(names).keys()

答案 2 :(得分:0)

为什么使用for循环查找所有div标签:

asm("some asm here using %[array1] and %[array2]"
    : "+m"(*(unsigned(*)[N])array1)
    : [array1]"r"(array1), [array2]"r"(array2),
      "m"(*(unsigned(*)[N])array1),
      "m"(*(unsigned(*)[N])array2)
    : /* possible clobbers, like "cc" */);

使用此标签,您可以获得所需的所有标签

for row in table.find_all('div')[16:]:
        cols = row.find_all('div')

因此只需使用此代码更改代码,您就会得到答案。