Захват различных элементов с BeautifulSoup: избегайте дублирования во вложенных элементах

Я хочу получить различный контент (классы) с сохраненного локального сайта (документация по python) с помощью BeautifulSoup4, поэтому я использую этот код для этого (index.html - это сохраненный сайт: https://docs.python.org/3/library/stdtypes.html)

from bs4 import BeautifulSoup
soup = BeautifulSoup(open("index.html"))
f = open('test.html','w')
f.truncate
classes= soup.find_all('dl', attrs={'class': ['class', 'method','function','describe', 'attribute', 'data', 'clasmethod', 'staticmethod']})
print(classes,file=f) 
f.close()

Обработчик файлов предназначен только для вывода результатов и не влияет на саму проблему.

Моя проблема в том, что результаты вложены. Например, метод "__eq__ (экспортер)" будет найден 1. внутри класса и 2. как автономный метод.

Поэтому я хочу удалить все результаты внутри других результатов, чтобы все результаты были на одном иерархическом уровне. Как я могу это сделать? Или вообще возможно "игнорировать" этот контент на первом этапе? Я надеюсь, вы понимаете, о чем я.

1 ответ

Решение

Вы не можете сказать find игнорировать вложенные dl элементы; все, что вы можете сделать, это игнорировать совпадения, которые появляются в .descendants:

matches = []
for dl in soup.find_all('dl', attrs={'class': ['class', 'method','function','describe', 'attribute', 'data', 'clasmethod', 'staticmethod']})
    if any(dl in m.descendants for m in matches):
        # child of already found element
        continue
    matches.append(dl)

Если вам нужны вложенные элементы и нет родителей, используйте:

matches = []
for dl in soup.find_all('dl', attrs={'class': ['class', 'method','function','describe', 'attribute', 'data', 'clasmethod', 'staticmethod']})
    matches = [m for m in matches if dl not in m.descendants]
    matches.append(dl)

Если вы хотите отделить дерево и удалить элементы из дерева, используйте:

matches = soup.find_all('dl', attrs={'class': ['class', 'method','function','describe', 'attribute', 'data', 'clasmethod', 'staticmethod']})
for element in matches:
    element.extract()  # remove from tree (and parent `dl` matches)

но вы можете настроить извлечение текста вместо этого.

Другие вопросы по тегам