Извлеките все ссылки после определенного тега с помощью beautifulsoup

#html #python-3.x #beautifulsoup

Вопрос:

Я не смог найти ответа на свой конкретный вопрос, так что вот оно. Предположим, у меня есть HTML, который выглядит примерно так (извините, если это выглядит немного глупо, я просто хотел сделать очень минимальный пример, который отражает мою проблему).:

 html1 = """<html>
<head></head>
<body>
<p>Hello World!</p>
<a href='whatevs.com'>whatevs</a>
<p>Howdy!</p>
<a href='well.com'>well</a>
<div><span>haha</span><a href='haha.com'>haha</a></div>
<a href='goodbye.com'>Goodbye!</a>
</body>
</html>"""
 

Я хочу извлечь все ссылки здесь, которые появятся после <p>Howdy!</p> .

Поэтому я попытался,

 howdy = BeautifulSoup(html1).find('p', text='Howdy!')
 

но и howdy.find_next_siblings('a') то и другое и howdy.find_next('a') возвращает что-то немного отличное от того, что я хочу.

Желаемый результат:

 [<a href="well.com">well</a>,
 <a href="haha.com">haha</a>,
 <a href="goodbye.com">Goodbye!</a>]
 

(Ну, на самом деле, это ['well','haha','Goodbye!'] так, но я думаю, что смогу получить это сверху.)

В идеале я хочу что-то вроде howdy.find_all('a') .

Извините, если это слишком простой вопрос, но я был бы очень признателен, если бы кто-нибудь мог направить вас в правильном направлении. Спасибо!

Ответ №1:

Попробуй:

 from bs4 import BeautifulSoup

html1 = """<html>
<head></head>
<body>
<p>Hello World!</p>
<a href='whatevs.com'>whatevs</a>
<p>Howdy!</p>
<a href='well.com'>well</a>
<div><span>haha</span><a href='haha.com'>haha</a></div>
<a href='goodbye.com'>Goodbye!</a>
</body>
</html>"""

soup = BeautifulSoup(html1, "html.parser")

out, tag = [], soup.find("p", text="Howdy!")
while True:
    tag = tag.find_next("a")
    if not tag:
        break
    out.append(tag.text)

print(out)
 

С принтами:

 ['well', 'haha', 'Goodbye!']
 

Ответ №2:

.find_next_siblings() это то, что вы ищете:

 from bs4 import BeautifulSoup

html1 = """<html>
<head></head>
<body>
<p>Hello World!</p>
<a href='whatevs.com'>whatevs</a>
<p>Howdy!</p>
<a href='well.com'>well</a>
<div><span>haha</span><a href='haha.com'>haha</a></div>
<a href='goodbye.com'>Goodbye!</a>
</body>
</html>"""

soup = BeautifulSoup(html1, 'lxml')
siblings = soup.find('p', text="Howdy!").find_next_siblings()
a_tags = [sib.find('a').text if sib.name != 'a' else sib.text for sib in siblings]
# -> ['well', 'haha', 'Goodbye!']
 

Примечание: Использование .find_next_siblings('a') не даст желаемого результата, так как оно не ищет внутренние теги.