Получить элементы между 2 элементами с супом - PullRequest
1 голос
/ 10 октября 2019

У меня есть следующий HTML-код:

<div class="info">
    <div class="left-wrap"><span class="date">DATE-1</span></div>
</div>

<div class="clients-list">
        <div>
            <span class="client" >client1</span>
            <span class="client" >client2</span>
            <span class="client" >client3</span>
        </div>
    </div>

<div class="info">
    <div class="left-wrap"><span class="date" >DATE-2</span></div>
</div>
<div class="clients-list">
        <div>
            <span class="client" >client4</span>
            <span class="client" >client5</span>
        </div>
</div>

Я хочу получить данные, относящиеся к каждой дате, я сделал следующее:

date = []
clients = []
for item in soup.find_all(class_='date'):
    date.append(item.get_text().strip())
for item in soup.find_all(class_='client'): 
    clients.append(item.get_text().strip())
print date
print clients

Я получаю список дат, содержащий "date1" и "date2", а также список клиентов, содержащих клиентов1 к клиентам5.

Моя проблема заключается в том, что я не могу сопоставить клиентов с датой, например client1, client2 и client3 и связанных с date1, но яне нашел, чтобы узнать, сколько клиентов будет под каждой датой.

Ответы [ 2 ]

2 голосов
/ 10 октября 2019

Попробуйте это. Используйте find_next (), чтобы найти следующий тег div, а затем найдите тег span_all ().

from bs4 import BeautifulSoup
html='''<div class="info">
    <div class="left-wrap"><span class="date">DATE-1</span></div>
</div>

<div class="clients-list">
        <div>
            <span class="client" >client1</span>
            <span class="client" >client2</span>
            <span class="client" >client3</span>
        </div>
    </div>

<div class="info">
    <div class="left-wrap"><span class="date" >DATE-2</span></div>
</div>
<div class="clients-list">
        <div>
            <span class="client" >client4</span>
            <span class="client" >client5</span>
        </div>
</div>'''

soup=BeautifulSoup(html,'html.parser')
dates=soup.find_all(class_='date')
for date in dates:
  print(date.text)
  for item in date.find_next(class_='clients-list').find_all(class_='client'):
       print(item.text)

Вывод :

DATE-1
client1
client2
client3
DATE-2
client4
client5
2 голосов
/ 10 октября 2019

Вы можете использовать itertools.groupby:

from bs4 import BeautifulSoup as soup
import itertools as it, re
data = soup(html, 'html.parser').find_all('span', {'class':re.compile('client|date')})
r = [[i.text for i in b] for _, b in it.groupby(data, key=lambda x:x['class'][0] == 'client')]
result = {r[i][0]:r[i+1] for i in range(0, len(r), 2)}

Выход:

{'DATE-1': ['client1', 'client2', 'client3'], 'DATE-2': ['client4', 'client5']}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...