Как разложить и сгладить теги из объекта BeautifulSoup? - PullRequest
1 голос
/ 18 июня 2020

Как разложить и сгладить теги из объекта BeautifulSoup?

Не из строки.

Из soup, в суп, не переходя к строке.

В docs предлагается использовать метод smooth() для устранения нежелательных пробелов. Можешь ли ты показать мне?

from bs4 import BeautifulSoup
dml = '''<html>
<head>
    <title>TITLE</title>
</head>
<body>LOOSE TEXT
    <div></div>
    <p></p>
    <div>MORE TEXT</div>
    <b></b>
    <i></i> # COMMENT
</body>
</html>'''

soup = BeautifulSoup(dml, features='lxml')
def strip_empty_tags(soup:BeautifulSoup):
    for item in soup.find_all():
        if not item.get_text(strip=True):
            item.decompose()
            soup.smooth()  # How to .smooth()?
    return soup

strip_empty_tags(soup)
<html>
<head>
<title>TITLE</title>
</head>
<body>LOOSE TEXT


<div>MORE TEXT</div>

 # COMMENT
</body>
</html>

Методы decompose() и extract() заставляют появляться нежелательные пробелы / пустые строки. Я хочу избавиться от них. Но нет, я не хочу ''.join([string for string in string_list]).

Существуют прецеденты этого вопроса, в частности: [1] , [2] . Но все предложения включают преобразование объекта BeautifulSoup в строку. Я могу это сделать, я уже делаю это, но я не хочу этого делать.

На этом сайте есть много других ссылок на BeautifulSoup и «удаление пустых пространств», но большинство из них касается ситуаций, когда текстовое содержимое имеет пустые места , начинающиеся с . В моей ситуации пустые пространства являются побочным продуктом методов декомпозиции / извлечения BeautifulSoup. Я бы хотел удалить их сразу после того, как они будут созданы в l oop.

Я использую синтаксический анализатор 'lxml' и не планирую менять его без крайней необходимости.

1 Ответ

1 голос
/ 18 июня 2020

Вы можете извлечь пустые теги с помощью tag.replace_with(''), затем выполнить parent.smooth() и заменить все пустые символы в конце строки на re.sub.

Например:

import re
from bs4 import BeautifulSoup

dml = '''<html>
<head>
    <title>TITLE</title>
</head>
<body>LOOSE TEXT
    <div></div>
    <p></p>
    <div>MORE TEXT</div>
    <b></b>
    <i></i> # COMMENT
</body>
</html>'''

soup = BeautifulSoup(dml, features='lxml')
def strip_empty_tags(soup:BeautifulSoup):
    for item in soup.find_all():
        if not item.get_text(strip=True):
            p = item.parent
            item.replace_with('')
            p.smooth()
            for c in p.find_all(text=True):
                c.replace_with(re.sub(r'\s{2,}$', '\n', c))
    return soup


print( strip_empty_tags(soup) )

Печать:

<html>
<head>
<title>TITLE</title>
</head>
<body>LOOSE TEXT
<div>MORE TEXT</div>
 # COMMENT
</body>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...