Ответ 1
Попробуй это
li = soup.find('li', {'class': 'text'})
children = li.findChildren("a" , recursive=False)
for child in children:
print child
Я хочу получить все теги <a>
являющиеся потомками <li>
:
<div>
<li class="test">
<a>link1</a>
<ul>
<li>
<a>link2</a>
</li>
</ul>
</li>
</div>
Я знаю, как найти элемент с определенным классом, как это:
soup.find("li", { "class" : "test" })
Но я не знаю, как найти всех <a>
которые являются детьми <li class=test>
но нет других.
Как я хочу выбрать:
<a>link1</a>
Попробуй это
li = soup.find('li', {'class': 'text'})
children = li.findChildren("a" , recursive=False)
for child in children:
print child
В DOC есть очень маленький раздел, в котором показано, как найти/найти прямых детей.
https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-recursive-argument
В вашем случае, как вы хотите, link1, который является первым прямым потомком:
# for only first direct child
soup.find("li", { "class" : "test" }).find("a", recursive=False)
Если вы хотите, чтобы все прямые дети:
# for all direct children
soup.find("li", { "class" : "test" }).findAll("a", recursive=False)
Возможно, вы хотите сделать
soup.find("li", { "class" : "test" }).find('a')
попробуйте следующее:
li = soup.find("li", { "class" : "test" })
children = li.find_all("a") # returns a list of all <a> children of li
другие напоминания:
Метод find получает только первый входящий дочерний элемент. Метод find_all получает все элементы-потомки и хранится в списке.
Еще один метод - создать функцию фильтра, которая возвращает True
для всех желаемых тегов:
def my_filter(tag):
return (tag.name == 'a' and
tag.parent.name == 'li' and
'test' in tag.parent['class'])
Затем просто вызовите find_all
с аргументом:
for a in soup(my_filter): # or soup.find_all(my_filter)
print a
"Как найти все, которые являются детьми a
<li class=test>
но не любые другие?"
Учитывая приведенный ниже HTML- select_one
(я добавил еще один <a>
чтобы показать разницу между select
и select_one
):
<div>
<li class="test">
<a>link1</a>
<ul>
<li>
<a>link2</a>
</li>
</ul>
<a>link3</a>
</li>
</div>
Решение состоит в том, чтобы использовать дочерний комбинатор (>
), который помещается между двумя селекторами CSS:
>>> soup.select('li.test > a')
[<a>link1</a>, <a>link3</a>]
Если вы хотите найти только первого ребенка:
>>> soup.select_one('li.test > a')
<a>link1</a>