BeautifulSoup을 사용하여 노드의 자식을 찾는 방법


115

나는 <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>

답변:


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 2011 년

3
그러나 와드 이후에만 <a> 태그를 얻는 방법. 같은find(li).find(a).firstChild()
tej.tan

"재귀"kwarg에 감사드립니다 :)
Swift

121

DOC에는 직계 자식 을 찾고 / 찾는 방법을 보여주는 매우 작은 섹션이 있습니다.

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

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>사이 테 차이를 보여 selectselect_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>

이것은 내가 찾고 있던 것입니다. 나는 그것을 잘못된 방법으로 공급하고 있었다. Forgot>은 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.