#beautifulsoup
#beautifulsoup
Вопрос:
Я пытаюсь создать html-файл, структурированный следующим образом, используя beautifulsoup. По сути, каждый блок состоит из:
-
один
<h2></h2>
-
один
<h3></h3>
-
более одного
<p></p>
Что-то вроде follow:
<h2>January, 2020</h2>
<h3>facility</h3>
<p>text1-1</p>
<p>text1-2</p>
<h2>April, 2020</h2>
<h3>scientists</h3>
<p>text2-1</p>
<p>text2-2</p>
<h2>June, 2020</h2>
<h3>lawyers</h3>
<p>text3-1</p>
<h2>.....
Я хочу получить текст, включающий <p>
теги между </h3>
и следующим <h2>
. Результат должен быть:
для строки #1:
<p>text1-1</p>
<p>text1-2</p>
для строки #2:
<p>text2-1</p>
<p>text2-2</p>
для строки #3:
<p>text3-1</p>
Вот что я пробовал до сих пор:
num_h2 = len(soup.find_all('h2'))
for i in range(0,num_h2):
print('---------')
print(i)
p_string = ''
sibling = soup.find_all('h3')[i].find_next_sibling('p').getText()
if sibling:
p_string = sibling
else:
break
print(p_string)
Проблема с этим решением заключается в том, что оно показывает только содержимое первого <p>
под каждым блоком. Я не знаю, как определить, сколько <p>
их существует для создания цикла for . Кроме того, есть ли лучший способ сделать это, чем использовать find_next_silibing()
?
Комментарии:
1. Уверен, что есть способ. Какие-либо попытки с вашей стороны?
2. @baduker спасибо. Я обновил свою попытку.
Ответ №1:
Возможно, селекторы css могут помочь:
for s in soup.select('h3'):
for ns in (s.fetchNextSiblings()):
if ns.name == "h2":
break
else:
if ns.name == "p":
print(ns)
Вывод:
<p>text1-1</p>
<p>text1-2</p>
<p>text2-1</p>
<p>text2-2</p>
<p>text3-1</p>