프로그래밍 & IT 정보/Python

파이썬 BeautifulSoup 파싱(Parsing) 다양한 방법

아미넴 2020. 9. 2.
반응형

파이썬을 공부하면서

html 문서에서 특정 태그를 가져오는 다양한 방법에 대해 정리를 해 보았습니다.

 

다음과 같은 HTML 문서가 있다고 가정을 하고

BeautifulSoup 모듈을 이용해서 특정 태그를 파싱해 오는 방법을 하나씩 보도록 할게요.

from bs4 import BeautifulSoup

html = """
<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <span class='test1'>Content1</span>
        <div class='test1'>Content2</div>
        <div class='test1' id='target' name='sangminem'>Goal</div>
        <div class='test2'>Content3</div>
    </body>
</html>
"""

soup = BeautifulSoup(html, "html.parser")

 

목표는 아래 태그입니다.

<div class='test1' id='target' name='sangminem'>Goal</div>

 

1. find() 메서드 활용

print(soup.find('div',id='target')) #tag, id
print(soup.find('div',attrs={'id':'target'})) #tag, 속성으로서의 id
print(soup.find('div',attrs={'name':'sangminem'})) #tag, 속성으로서의 name
print(soup.find(attrs={'name':'sangminem'})) #속성으로서의 name
print(soup.find(attrs={'id':'target'})) #속성으로서의 id

# 출력 결과
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>

 

2. find_all() 메서드 활용

print(soup.find_all('div')[1]) #tag
print(soup.find_all('div',class_=['test1'])[1]) #tag, class
print(soup.find_all('div',id='target')[0]) #tag, id
print(soup.find_all('div',attrs={'class':'test1'})[1]) #tag, 속성으로서의 class
print(soup.find_all('div',attrs={'id':'target'})[0]) #tag, 속성으로서의 id
print(soup.find_all('div',attrs={'name':'sangminem'})[0]) #속성으로서의 name
print(soup.find_all(class_=['test1'])[2]) #class
print(soup.find_all(id='target')[0]) #id
print(soup.find_all(attrs={'class':'test1'})[2]) #속성으로서의 class
print(soup.find_all(attrs={'id':'target'})[0]) #속성으로서의 id
print(soup.find_all(attrs={'name':'sangminem'})[0]) #속성으로서의 name

# 출력 결과
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>

 

 

3. select_one() 메서드 활용

print(soup.select_one('div.test1#target')) #tag, class, id
print(soup.select_one('div#target')) #tag, id
print(soup.select_one('.test1#target')) #class, id
print(soup.select_one('#target')) #id

# 출력 결과
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>

 

4. select() 메서드 활용

print(soup.select('.test1')[2]) #class
print(soup.select('div.test1')[1]) #tag, class
print(soup.select('div.test1#target')[0]) #tag, class, id
print(soup.select('div#target')[0]) #tag, id
print(soup.select('.test1#target')[0]) #class, id
print(soup.select('#target')[0]) #id

# 출력 결과
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>
# <div class="test1" id="target" name="sangminem">Goal</div>

 

find() 메서드와 select_one() 메서드는 단일 결과를 가져옵니다.

만약 조건에 만족하는 결과가 여러 건이 있다면 맨 처음 값만을 가져옵니다.

 

find_all()과 select() 메서드는 조건에 만족하는 모든 결과를 배열 형태로 가져옵니다.

따라서 최종적으로 원하는 값을 가져오기 위해서는 배열 인덱스를 빠뜨려서는 안 됩니다.

 

 

방법이 다양하여 어떤걸 써야할지 결정이 어려우시다면

select() 메서드를 활용하는 것을 추천 드립니다.

사용이 간편하고 실제로 파싱하는 속도도 더 빠르다고 하네요.

반응형
그리드형(광고전용)

댓글5

  • ssung85 2020.11.23 16:38 신고

    크롤링 공부하면서 알게 된 bs4 ㅎㅎ 이름처럼 아름답네요 ㅋㅋ
    답글

    • 아미넴 2020.11.23 21:58 신고

      bs4 이용해서 파싱할 때 select 메서드 문법이 jQuery와 비슷해서 더 익숙하고 간편한 것 같아요 ㅎㅎ

  • metamong 2021.09.25 15:09 신고

    안녕하세요. 목차 만들려고 블로그 와서 많이 도움 받았습니다! 정말 감사해요 ㅠㅠ
    다름이 아니라 어떤 코드블록 사용하신건지 궁금해요!
    그리고 코드 블록 가장자리 님께서 하신 것처럼 약간 원으로 둥글게 어떻게 하신 건지 궁금합니다!
    티스토리를 꾸미다 보니 무궁무진하게 꾸밀 수 있네요! 너무 좋아요 :)
    답글

    • 아미넴 2021.09.25 15:25 신고

      네 안녕하세요~ 도움이 되셨다니 기분이 좋네요 :)
      코드블록은 기본 코드블록에 코드 문법 강조 플러그인을 사용했고 css에서 pre > code 부분에 border-radius를 10px 정도 준 정도 밖에 없습니다 ㅎㅎ

    • metamong 2021.09.25 17:07 신고

      감사합니다! :)

💲 추천 글