Предположим, есть следующий фрагмент html, из которого я хотел бы извлечь значения, соответствующие меткам «цена» и «отправка»:
<div class = "divName">
<div>
<label>Price</label>
<div>22.99</div>
</div>
<div>
<label>Ships from</label>
<span>EU</span>
</div>
</div>
Который является частью большего html-файла. Предположим, что в некоторых файлах присутствует метка «Отправка из», а иногда нет. Я хотел бы использовать BeautifulSoup с аналогичным подходом, чтобы справиться с этим из-за изменчивости содержимого html. Присутствует несколько div
и span
, что затрудняет выбор без идентификатора или имени класса.
Мои мысли, примерно такие:
t = open('snippet.html', 'rb').read().decode('iso-8859-1')
s = BeautifulSoup(t, 'lxml')
s.find('div.divName[label*=Price]')
s.find('div.divName[label*=Ships from]')
Однако это возвращает пустой список.
Используйте select
, чтобы найти label
, а затем используйте find_next_sibling().text
Бывший:
from bs4 import BeautifulSoup
html = """<div class = "divName">
<div>
<label>Price</label>
<div>22.99</div>
</div>
<div>
<label>Ships from</label>
<span>EU</span>
</div>
</div>"""
soup = BeautifulSoup(html, "html.parser")
for lab in soup.select("label"):
print(lab.find_next_sibling().text)
Выход:
22.99
EU
Попробуй это :
from bs4 import BeautifulSoup
from bs4.element import Tag
html = """ <div class = "divName">
<div>
<label>Price</label>
<div>22.99</div>
</div>
<div>
<label>Ships from</label>
<span>EU</span>
</div>
</div>"""
s = BeautifulSoup(html, 'lxml')
row = s.find(class_='divName')
Решение-1:
for tag in row.findChildren():
if len(tag) > 1:
continue
if tag.name in 'span' and isinstance(tag, Tag):
print(tag.text)
elif tag.name in 'div' and isinstance(tag, Tag):
print(tag.text)
Решение-2:
for lab in row.select("label"):
print(lab.find_next_sibling().text)
О/П:
22.99
EU
Вы можете использовать :contains
(с bs 4.7.1 и next_sibling
import requests
from bs4 import BeautifulSoup as bs
html = '''
<div class = "divName">
<div>
<label>Price</label>
<div>22.99</div>
</div>
<div>
<label>Ships from</label>
<span>EU</span>
</div>
</div>
'''
soup = bs(html, 'lxml')
items = soup.select('label:contains(Price), label:contains("Ships from")')
for item in items:
print(item.text, item.next_sibling.next_sibling.text)