BeautifulSoup — очистить текст от начального ключевого слова до конечного ключевого слова

#python #web-scraping #beautifulsoup

#python #веб-очистка #beautifulsoup

Вопрос:

У меня есть приведенный ниже исходный код HTML, который необходимо очистить. Данные включают таблицу, которая не настроена с <table> тегом. Я не могу использовать теги для идентификации элемента, поскольку один и тот же тег используется во всем HTML-коде. Как мне очистить данные для получения приведенного ниже вывода? Строка заголовка всегда остается неизменной, данные в таблице меняются.

Код

 <p>
    <div class="my-test-class" style="white-space: pre-wrap; font-size: small; font-family: amp;quot;Courier Newamp;quot;">
        <div class="my-test-class">Random text goes on.........</div>
        <div class="my-test-class"><br></div>
        <div class="my-test-class">Header1 Header2 Header3 Header4 Header5
        </div>
        <div class="my-test-class">--------------------------------------
        </div>
        <div class="my-test-class">A1 B1 C1 D1 E1</div>
        <div class="my-test-class">A2 B2 C2 D2 E2</div>
        <div class="my-test-class">A3 B3 C3 D3 E3</div>
        <div class="my-test-class">--------------------------------------
        </div>
    </div>
</p>
  

Вывод:

 Header1 Header2 Header3 Header4 Header5
--------------------------------------
A1 B1 C1 D1 E1
A2 B2 C2 D2 E2
A3 B3 C3 D3 E3
--------------------------------------
  

Очистка кода до сих пор:

 from bs4 import BeautifulSoup
import re
soup = BeautifulSoup('''
<p>
    <div class="my-test-class" style="white-space: pre-wrap; font-size: small; font-family: amp;quot;Courier Newamp;quot;">
        <div class="my-test-class">Random text goes on.........</div>
        <div class="my-test-class"><br></div>
        <div class="my-test-class">Header1 Header2 Header3 Header4 Header5
        </div>
        <div class="my-test-class">--------------------------------------
        </div>
        <div class="my-test-class">A1 B1 C1 D1 E1</div>
        <div class="my-test-class">A2 B2 C2 D2 E2</div>
        <div class="my-test-class">A3 B3 C3 D3 E3</div>
        <div class="my-test-class">--------------------------------------
        </div>
    </div>
</p>
''')

h = soup.find_all(text=re.compile('Header1*'))
print(h)
  

Комментарии:

1. Какие значения находятся внутри таблицы? Просто числа или строки с пробелами?

Ответ №1:

Вы можете найти заголовок, а затем .find_next_siblings() вашу таблицу:

 from bs4 import BeautifulSoup

txt = '''<p>
    <div class="my-test-class" style="white-space: pre-wrap; font-size: small; font-family: amp;quot;Courier Newamp;quot;">
        <div class="my-test-class">Random text goes on.........</div>
        <div class="my-test-class"><br></div>
        <div class="my-test-class">Header1 Header2 Header3 Header4 Header5
        </div>
        <div class="my-test-class">--------------------------------------
        </div>
        <div class="my-test-class">A1 B1 C1 D1 E1</div>
        <div class="my-test-class">A2 B2 C2 D2 E2</div>
        <div class="my-test-class">A3 B3 C3 D3 E3</div>
        <div class="my-test-class">--------------------------------------
        </div>
    </div>
</p>'''

soup = BeautifulSoup(txt, 'html.parser')

header = soup.find(text=lambda t: '----' in t).parent.find_previous()

print(header.text)
print(*[tag.get_text(strip=True) for tag in header.find_next_siblings()], sep='n')
  

С принтами:

 Header1 Header2 Header3 Header4 Header5
        
--------------------------------------
A1 B1 C1 D1 E1
A2 B2 C2 D2 E2
A3 B3 C3 D3 E3
--------------------------------------
  

Ответ №2:

Это должно помочь вам:

 from bs4 import BeautifulSoup
import re
soup = BeautifulSoup('''
<p>
    <div class="my-test-class" style="white-space: pre-wrap; font-size: small; font-family: amp;quot;Courier Newamp;quot;">
        <div class="my-test-class">Random text goes on.........</div>
        <div class="my-test-class"><br></div>
        <div class="my-test-class">Header1 Header2 Header3 Header4 Header5
        </div>
        <div class="my-test-class">--------------------------------------
        </div>
        <div class="my-test-class">A1 B1 C1 D1 E1</div>
        <div class="my-test-class">A2 B2 C2 D2 E2</div>
        <div class="my-test-class">A3 B3 C3 D3 E3</div>
        <div class="my-test-class">--------------------------------------
        </div>
    </div>
</p>
''', 'html5lib')

txt = soup.find_all('div', class_ = "my-test-class", text=True)
txt = [elem.text.strip() for elem in txt]
pattern = re.compile('[A-Z][0-9]')

[print(elem) for elem in txt if 'Header' in elem or '-' in elem or pattern.match(elem)]
  

Вывод:

 Header1 Header2 Header3 Header4 Header5
--------------------------------------     
A1 B1 C1 D1 E1
A2 B2 C2 D2 E2
A3 B3 C3 D3 E3
--------------------------------------