Python Webscraping Beautifulsoup избежать повторения в find_all () - PullRequest
0 голосов
/ 28 апреля 2020

Я работаю над очисткой веб-страниц в Python с помощью Beautifulsoup. Я пытаюсь извлечь текст жирным шрифтом или курсивом или и тем, и другим. Рассмотрим следующий HTML фрагмент.

<div>
  <b> 
    <i>
      HelloWorld
   </i>
  </b>
</div>

Если я использую команду sp.find_all(['i', 'b']), понятно, что я получу два результата, один из которых будет выделен жирным шрифтом, а другой - курсивом. то есть

[' HelloWorld ', ' HelloWorld ']

Мой вопрос, есть ли способ однозначно извлечь его и получить теги? Мой желаемый вывод - что-то вроде -

tag: text - HelloWorld, tagnames: [b, i]

Обратите внимание, что сравнение текста и отсеивание не уникально вхождение текста не является выполнимым вариантом, так как я мог бы много раз повторять текст HelloWorld, который я хотел бы извлечь.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Я бы сказал, что это неясно определено. Что если у вас есть <b>foo<i>bar</i><b> (это может быть еще сложнее)?

В любом случае, я бы сказал, что вы должны реализовать рекурсию.

Вот пример:

import bs4

html = """
<div>
  <b> 
    <i>
      HelloWorld
   </i>
  </b>
</div>
"""

def recursive_find(soup):
    for child in soup.children:
        result = child.find_all(['i', 'b'], recursive=False)
        if result:
            if len(result) == 1:
                result_s_result = result[0].find_all(['i', 'b'], recursive=False)
                if len(result_s_result) == 1:
                    print(result_s_result[0].contents)
            else:
                print(result)
        else:
            recursive_find(child)

oneline_html = "".join(line.strip() for line in html.split("\n"))

soup = bs4.BeautifulSoup(oneline_html, 'html.parser')

recursive_find(soup)
0 голосов
/ 28 апреля 2020

Наиболее естественным способом поиска узлов, у которых среди предков есть <b> и <i>, будет XPath:

//node()[ancestor::i or ancestor::b]

Вместо node() вы можете использовать text() для поиска текста узлы или * для поиска элементов в зависимости от ситуации. Это не приведет к выбору дубликатов и не имеет значения, в каком порядке вложены <i> и <b>.

Проблема этой идеи заключается в том, что BeautifulSoup не поддерживает XPath. По этой причине я использовал бы l xml вместо BeautifulSoup для просмотра веб-страниц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...