У меня проблемы с настройкой простого поиска всех внешних элементов, соответствующих моему запросу, в html-документе.Я спрашиваю здесь с надеждой, что есть простая функция bs4
, которая делает это, но это не так.
Рассмотрим следующий html-пример, где я хочу, чтобы все внешние <div>
имели класс "wanted"
(я ожидаю получить список 2 ):
import bs4
text = """
<div>
<div class="inner">
<div class="wanted">
I want this.
<div class="wanted">
I don't want that!
</div>
</div>
</div>
<div class="inner">
<div class="wanted">
I want this too.
</div>
</div>
</div>"""
soup = bs4.BeautifulSoup(text, 'lxml')
# 1. Trying all at once
fetched = soup.findAll('div', class_='wanted')
print(len(fetched)) # 3
fetched = soup.findAll('div', class_='wanted', recursive=False)
print(len(fetched)) # 0
fetched = soup.findChildren('div', class_='wanted')
print(len(fetched)) # 3
fetched = soup.findChildren('div', class_='wanted', recursive=False)
print(len(fetched)) # 0
# 2. Trying one after the other
fetched = []
fetched0 = soup.find('div', class_='wanted')
while fetched0:
fetched.append(fetched0)
descendants = list(fetched0.descendants)
fetched0 = descendants[-1].findNext('div', class_='wanted')
print(len(fetched)) # 2 Hurra!
# 3. Destructive method: if you don't care about the parents of this element
fetched = []
fetched0 = soup.find('div', class_='wanted')
while fetched0:
fetched.append(fetched0.extract())
fetched0 = soup.find('div', class_='wanted')
print(len(fetched))
Так что ничто в части # 1.
не дает ожидаемого результата.Поэтому в чем разница между findAll
и findChildren
??И findNextSibling
не имеет значения, учитывая вложенность здесь.
Теперь часть # 2.
работает, но зачем писать столько кода?Разве нет более элегантного решения?Что касается части # 3.
, нужно быть осторожным с предполагаемыми последствиями.
Каковы ваши предложения об этом поиске?Я действительно нашел кратчайший путь?Могу ли я использовать магию выбора CSS?