Python BeautifulSoup: Как найти все div самого низкого уровня (div, которые не содержат вложенных div)? - PullRequest
0 голосов
/ 28 августа 2018

У меня сложный HTML-документ с вложенными тегами <div>, например:

<html>
    <body>
        <div id="one">
            <p>1. Get this div!</p>
        </div>
        <div id="two">
            <div>
                <div id="three">
                    <p>2. Get this div!</p>
                </div>
            </div>
            <div id="four">
                <p>3. Get this div!</p>
            </div>
        </div>
    </body>
</html>

И я пытаюсь использовать следующий код:

soup = BeautifulSoup(html, 'html.parser')
div_list = soup.find_all('div')

Однако приведенный выше код получает только самые верхние уровни div, что означает, что он вернет только div с идентификаторами "one" и "two". Тем не менее, я хотел бы использовать BeautifulSoup, чтобы вернуть список div с идентификаторами «one», «three» и «four». Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Вы можете напрямую проверить, имеет ли какое-либо из найденных подразделений больше подразделений внутри:

[d for d in soup.findAll('div') if not d.find('div')]
#[<div id="one"><p>1. Get this div!</p></div>, 
# <div id="three"><p>2. Get this div!</p></div>, 
# <div id="four"><p>3. Get this div!</p></div>]
0 голосов
/ 28 августа 2018

Самый простой способ - создать список с нужными идентификаторами, а затем использовать re.compile:

from bs4 import BeautifulSoup as soup
import re
ids = ['one', 'three', 'four']
results = soup(content, 'html.parser').find_all('div', {'id':re.compile('|'.join(ids))})
for i in results:
 print(i)
 print('-'*20)

Выход:

<div id="one">
<p>1. Get this div!</p>
</div>
--------------------
<div id="three">
<p>2. Get this div!</p>
</div>
--------------------
<div id="four">
<p>3. Get this div!</p>
</div>
--------------------

Однако без использования списка для поиска можно использовать рекурсию:

def get_ids(_d):
  if not any(getattr(i, '__dict__', {}).get('name') == 'div' for i in _d.__dict__['contents']):
     return _d 
  _r = [get_ids(i) for i in _d.__dict__['contents'] if getattr(i, '__dict__', {}).get('name') == 'div']
  return None if not _r else _r[0]

final_results = []
for i in [get_ids(i) for i in soup(content, 'html.parser').find_all('div')]:
  if i not in s:
     s.append(i)

print(final_results)

Выход:

[<div id="one"><p>1. Get this div!</p></div>, <div id="three"><p>2. Get this div!</p></div>, <div id="four"><p>3. Get this div!</p></div>]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...