BeautifulSoup. Неверный индекс элемента - PullRequest
1 голос
/ 11 октября 2019

Я проанализировал ol элемент html и столкнулся с проблемой индексации элементов.

Предположим, у нас есть следующий элемент:

html_document = """
<ol>
    <li>Test lists</li>
    <li>Second option</li>
    <li>Third option</li>
</ol>
"""

Итак,давайте разберемся:

soup = BeautifulSoup(html_document)
all_li = tuple(soup.find_all('li'))
result = [el.parent.index(el) for el in all_li]
print(result)  # [1, 3, 5]

Почему 1,3,5? Или я что-то пропустил?

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

В определении метода index() мы видим следующий код:

    def index(self, element):
        """
        Find the index of a child by identity, not value. Avoids issues with
        tag.contents.index(element) getting the index of equal elements.
        """
        for i, child in enumerate(self.contents):
            if child is element:
                return i
        raise ValueError("Tag.index: element not in tag")

Так что на самом деле вам нужно взглянуть на свойство .contents, которое показывает следующие члены (дочерние элементытег <ol>):

0 <class 'bs4.element.NavigableString'> 
1 <class 'bs4.element.Tag'> <li>Test lists</li>
2 <class 'bs4.element.NavigableString'> 
3 <class 'bs4.element.Tag'> <li>Second option</li>
4 <class 'bs4.element.NavigableString'> 
5 <class 'bs4.element.Tag'> <li>Third option</li>
6 <class 'bs4.element.NavigableString'> 

Другими словами, родительский элемент для ваших тегов <li>, <ol>, имеет других дочерних элементов - навигационные строки, которые вы не захватываете напрямую, потому что вы толькоискал элементы списка (soup.find_all('li')).

1 голос
/ 11 октября 2019

Вы используете родительский тег. Просто используйте дочерний тег.

html_document = """
<ol>
    <li>Test lists</li>
    <li>Second option</li>
    <li>Third option</li>
</ol>
"""

soup = BeautifulSoup(html_document,'lxml')
all_li = tuple(soup.find_all('li'))
result = [all_li.index(el) for el in all_li]
print(result)

вывод:

[0, 1, 2]
...