파이썬 크롤링으로 자식 태그를 제외한 HTML 태그 text 가져오기
다음과 같은 경우, BeautifulSoup을 이용하여 파싱한 후 텍스트만 추출하면 다음과 같이 나온다.
1
2
3
4
5
6
| <div id="target">
<div id="except">
이 내용은 가져오지마
</div>
이 내용을 가져와
</div>
|
코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| from bs4 import BeautifulSoup
from bs4.element import NavigableString
html = """
<div id="target">
<div id="except">
이 내용은 가져오지마
</div>
이 내용을 가져와
</div>
"""
soup = BeautifulSoup(html, 'html.parser')
target_tag = soup.select_one("#target")
print(target_tag.text)
|
출력
1
2
3
4
5
6
|
이 내용은 가져오지마
이 내용을 가져와
|
하지만 우리는 자식 태그를 제외한 태그의 내용만 가져오고 싶다면 어떻게 해야할까?
이 경우, BeautifulSoup 공식문서를 읽어보면 총 4가지의 objects로 존재함을 알 수 있다.
- Tag
- NavigableString
- BeautifulSoup
- Comment
따라서 해당 태그를 for문으로 순회하면서 1. 어떤 object에 2. 어떤 내용이 있는지 출력해본다.
코드
1
2
3
4
5
6
7
| soup = BeautifulSoup(html, 'html.parser')
target_tag = soup.select_one("#target")
for bs_object in target_tag:
print("[object]", type(bs_object))
print("[repr]")
print(bs_object)
print("-----")
|
출력
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| [object]
<class 'bs4.element.NavigableString'>
-----
[repr]
-----
[object]
<class 'bs4.element.Tag'>
-----
[repr]
<div id="except">
이 내용은 가져오지마
</div>
-----
[object]
<class 'bs4.element.NavigableString'>
-----
[repr]
이 내용을 가져와
-----
|
해당 태그는 다음과 같이 구성되어 있었다.
- [열린 태그 ~ 자식 태그]
NavigableString
- 자식 태그는
Tag
- [자식 태그 ~ 닫힌 태그]
NavigableString
따라서 for문을 순회하면서 NavgableString 태그인 경우를 가져오면 내부 태그는 없앨 수 있다.
완성 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| from bs4 import BeautifulSoup
from bs4.element import NavigableString
html = '''
<div id="target">
<div id="except">
이 내용은 가져오지마
</div>
이 내용을 가져와
</div>
'''
soup = BeautifulSoup(html, 'html.parser')
target_tag = soup.select_one("#target")
target_text_without_child_tags = [
bs_object
for bs_object
in target_tag
if isinstance(bs_object, NavigableString)
]
text = "".join(target_text_without_child_tags)
print(text)
|
실행 결과
참고
BeautifulSoup 공식문서
stackoverflow