我正在将BeautifulSoup 4与Python 3.7一起使用。我有以下HTML ...
<tr>
<td class="info"><div class="title">...</div></td>
</tr>
<tr class="ls">
<td colspan="3">Less similar results</td>
</tr>
<tr>
<td class="info"><div class="title">...</div></td>
</tr>
我想提取带有class =“ title”的DIV,但是,我只想查找表中TD文本=“缺少相似结果”的元素之前的DIV。现在我有这个
elts = soup.find("td", class_="info").find_all("div", class_="title")
但是这将返回该类的所有DIV,即使是在我要筛选的元素之后发生的DIV。如何优化搜索以仅包含特定TD之前的结果?
答案 0 :(得分:5)
您可以使用CSS选择器tr:not(tr:has(td:contains("Less similar results")) ~ *) div.title
:
data = '''<tr>
<td class="info"><div class="title">THIS YOU WANT ...</div></td>
</tr>
<tr class="ls">
<td colspan="3">Less similar results</td>
</tr>
<tr>
<td class="info"><div class="title">THIS YOU DON'T WANT ...</div></td>
</tr>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'lxml')
print(soup.select('tr:not(tr:has(td:contains("Less similar results")) ~ *) div.title'))
打印:
[<div class="title">THIS YOU WANT ...</div>]
这是什么意思?
tr:not(tr:has(td:contains("Less similar results")) ~ *) div.title
选择类别为<div>
的{{1}},该类别位于title
之前的<tr>
之下,其中<tr>
包含<td>
和"Less similar results"
。
进一步阅读:
答案 1 :(得分:2)
我们可以反过来,首先关注<tr class="ls">
:
from bs4.element import Tag
ls = soup.find('tr', class_='ls')
elts = [td for tr in ls.previous_siblings
if isinstance(tr, Tag)
for td in tr.find_all('td', class_='info')]
这给我们:
>>> elts
[<td class="info"><div class="title">...</div></td>]
因此,我们首先使用tr
来定位class="ls"
,然后迭代其先前的同级并寻找<td class="info">
。
答案 2 :(得分:0)
尝试-
o = []
for td in soup.find("td", class_="info"):
if td.get_text() == 'Less similar results':
break
for div in td.findChildren("div", class_='title'):
o.append(div.get_text())
print(o)