如何使用BeautifulSoup查找节点的子节点


114

我想获取所有<a>属于以下子项的标签<li>

<div>
<li class="test">
    <a>link1</a>
    <ul> 
       <li>  
          <a>link2</a> 
       </li>
    </ul>
</li>
</div>

我知道如何找到像这样的特定类的元素:

soup.find("li", { "class" : "test" }) 

但是我不知道如何找到所有<a>的孩子的孩子,<li class=test>而不是其他孩子的孩子。

就像我想选择:

<a>link1</a>

Answers:


124

试试这个

li = soup.find('li', {'class': 'text'})
children = li.findChildren("a" , recursive=False)
for child in children:
    print child

3
或者,仅提取描述我们想要的表达式:soup.find('li', {'class': 'text'}).findChildren()
Karl Knechtel

3
但是如何仅在病房之后才能获取第一号<a>标签。像find(li).find(a).firstChild()
tej.tan 2011年

感谢您的“递归” kwarg :)
迅速,

121

DOC中有一个超小部分,显示了如何查找/ find_all 直接子级。

https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-recursive-argument

在您需要的情况下,link1是第一个直接子级:

# for only first direct child
soup.find("li", { "class" : "test" }).find("a", recursive=False)

如果您想要所有直系子女:

# for all direct children
soup.find("li", { "class" : "test" }).findAll("a", recursive=False)

12

也许你想做

soup.find("li", { "class" : "test" }).find('a')

1
我认为它也会找到<a> link2 </a>,但我不想要
tej.tan 2011年

1
这个答案如何选择<a>link1</a>在这个问题给出的HTML,但是这将失败的时候第一个<li class="test">不包含任何<a>元素,并有其他li元素与test含有类<a>
radzak

11

试试这个:

li = soup.find("li", { "class" : "test" })
children = li.find_all("a") # returns a list of all <a> children of li

其他提醒:

find方法仅获取第一个出现的子元素。find_all方法获取所有后代元素,并存储在列表中。


2
发问者希望以上两个选项都不是。他希望所有的链接都是直子。
Ahsan Roy

8

“如何找到所有人a的孩子,<li class=test>而不是其他孩子?”

给定下面的HTML(我添加了另一个<a>以显示select和之间的区别select_one):

<div>
  <li class="test">
    <a>link1</a>
    <ul>
      <li>
        <a>link2</a>
      </li>
    </ul>
    <a>link3</a>
  </li>
</div>

解决方案是使用放在两个CSS选择器之间的子组合器>):

>>> soup.select('li.test > a')
[<a>link1</a>, <a>link3</a>]

如果您只想找到第一个孩子:

>>> soup.select_one('li.test > a')
<a>link1</a>

这是我一直在寻找的那个。我将其提供给错误的方法。忘记了>是CSS选择器。谢谢!
LFMekz

7

另一种方法-创建一个过滤器函数,该函数返回True所有所需标签:

def my_filter(tag):
    return (tag.name == 'a' and
        tag.parent.name == 'li' and
        'test' in tag.parent['class'])

然后只需调用find_all参数:

for a in soup(my_filter): # or soup.find_all(my_filter)
    print a
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.