我是beautifulsoup的新手,我正试图在某个p标签下找到一些表格,里面有文字“子类”
这是HTML示例
<p><b>subclass</b></p>
<table>...<table>
<p><b>frnekr</b></p>
<table>...<table>
我只想抓住p标签下的表格 - &gt;子类。遗憾的是,那些p标签没有类。
答案 0 :(得分:1)
一种方法是在一个过滤器中完成。
请参阅文档中搜索的Kinds of filters部分。
如果您可以编写一个函数来检查标记是否为文本中带有p
的{{1}}标记,则可以使用它来查找subclass
标记。例如:
p
当然你不需要这个功能。 (它与>>> soup.find_all(lambda tag: tag.name=='p' and tag.text=='subclass')
[<p><b>subclass</b></p>]
相同。)但它说明了这个想法。
现在,您要查找遵循此类soup.find_all('p', text='subclass')
标记的table
代码。这会变得有点复杂,所以让我们把它写出来。
首先,快速而肮脏的解决方案:
p
但这并不是非常强大。你不想浏览所有以前的兄弟姐妹,只需检查一下。此外,如果找不到def is_table_after_subclass(tag):
return (tag.name == 'table' and
tag.find_previous_sibling('p').text == 'subclass')
标记,您将获得异常而不是false。所以:
p
现在,你可以这样做:
# This is necessary because the table's previous_sibling is the
# '\n' string between the `p` and the `table`, not the `p`.
def previous_tag(tag):
tag = tag.previous_sibling
while not isinstance(tag, bs4.Tag):
tag = tag.previous_sibling
return tag
def is_table_after_subclass(tag):
if tag.name != 'table': return False
prev = previous_tag(tag)
return prev.name == 'p' and prev.text == 'subclass'
另一种方法是首先迭代所有表,然后跳过前一个兄弟错误的表。或者首先迭代所有子类段落,然后跳过那些错误的下一个兄弟段落。例如:
soup.find_all(is_table_after_subclass)
答案 1 :(得分:0)
Soupy是我尝试使这样的查询更自然(Soupy包装BeautifulSoup,使查询链更容易)。这是一个解决方案:
from soupy import Soupy, Q
text = """
<p><b>subclass</b></p>
<table>...</table>
<p><b>frnekr</b></p>
<table>...</table>
<p><b>subclass</b></p>
<p> No table here </p>
"""
from soupy import Soupy, Q
(dom.find_all('p', text="subclass") # find relevant p tags
.each(Q.find_next_sibling('table')) # look for sibling tables
.filter(Q) # drop failed searches
.val()) # dump out of Soupy
哪个产生
[<table>...</table>]
这大致相当于@ abarnert的最后一个代码示例