CodeGym /자바 코스 /Python SELF KO /HTML 태그와 속성으로 데이터 추출하기

HTML 태그와 속성으로 데이터 추출하기

Python SELF KO
레벨 31 , 레슨 3
사용 가능

1. HTML 트리 탐색

오늘은 HTML 트리의 신비한 세계로 들어가서 진짜 프로그래머 닌자처럼 웹 페이지 정보 추출하는 방법을 배울 거야. 우리는 마법 같은 BeautifulSoup 라이브러리를 계속 사용할 거야. 그래서 필요한 데이터를 얻고 멋진 스크립트의 기능을 더 멋지게 만들 거야. 그러니 키보드를 잘 준비하고, 시작하자!

먼저, 데이터를 추출하기 전에 HTML 트리가 뭔지 다시 알아보자. 이거 엄청 큰 가족 트리 같아. 모든 태그가 각기 다른 친척이 되는 거야. 부모, 자식, 형제자매. 우리의 목표는 특정 "친척"을 찾아서 그 안에서 중요한 가족 유물을 (즉, 데이터를) 깔끔하게 추출하는 거야.

여기 HTML 조각이 어떻게 생겼는지 봐봐:

HTML

<div class="article">
    <h2 id="title">제목</h2>
    <p class="content">이건 기사 내용입니다...</p>
    <a href="https://example.com" class="link">더 읽기</a>
</div>

여기 div가 있어. 이건 h2, p, 그리고 a의 부모 요소야. 각자는 저마다 속성과 내용을 가지고 있어.

2. 태그로 데이터 추출

BeautifulSoup은 트리를 탐색하고 데이터를 추출할 수 있는 편리한 메서드를 제공해. 먼저 find() 메서드를 사용해서 특정 태그를 가진 첫 번째 요소를 찾아볼 거야. 그리고 find_all()은 모든 요소를 찾는 파워풀한 방법이야.

python
                      
                        from bs4 import BeautifulSoup
                
                        html_doc = """<div class="article">
                                        <h2 id="title">제목</h2>
                                        <p class="content">이건 기사 내용입니다...</p>
                                        <a href="https://example.com" class="link">더 읽기</a>
                                     </div>"""
                        
                        soup = BeautifulSoup(html_doc, 'html.parser')
                        
                        # 첫 번째 단락 찾기
                        first_paragraph = soup.find('p')
                        print(first_paragraph.text)  # 출력: 이건 기사 내용입니다...
                        
                        # 모든 링크 찾기
                        all_links = soup.find_all('a')
                        for link in all_links:
                            print(link['href'])  # 출력: https://example.com
                      
                    

3. 속성으로 요소 필터링

이제 태그 검색을 마스터했으니, 다음은 idclass 같은 속성을 사용해 요소 필터링하기를 배워보자. 이 속성들은 페이지의 북마크 같은 역할을 해서, 어디가 무엇인지 즉시 알려준다구.

HTML

<div class="article">
    <h2 id="title">제목</h2>
    <p class="content">이건 기사 내용입니다...</p>
    <a href="https://example.com" class="link">더 읽기</a>
</div>
Python

# 특정 id를 가진 요소 찾기
title = soup.find(id="title")
print(title.text)  # 출력: 제목

# 클래스 "content"를 가진 모든 요소 찾기
content_paragraphs = soup.find_all(class_="content")
for p in content_paragraphs:
    print(p.text)  # 출력: 이건 기사 내용입니다...

중요! 우리는 class 대신 class_를 사용해. Python의 예약어와 충돌을 피하기 위해서야.

4. 조건에 따라 데이터 추출 연습하기

이제 실습 들어간다! 예를 들어 대규모 반복 HTML 기사를 대상으로 제목과 링크를 추출하는 방법을 배워보자:

HTML

<div class="articles">
    <div class="article">
        <h2 class="title">첫 번째 기사</h2>
        <a href="https://example.com/1" class="read-more">더 읽기</a>
    </div>
    <div class="article">
        <h2 class="title">두 번째 기사</h2>
        <a href="https://example.com/2" class="read-more">더 읽기</a>
    </div>
</div>
        

이 데이터를 추출하는 방법은 이렇게:

Python

html_doc = """<div class="articles">
                <div class="article">
                    <h2 class="title">첫 번째 기사</h2>
                    <a href="https://example.com/1" class="read-more">더 읽기</a>
                </div>
                <div class="article">
                    <h2 class="title">두 번째 기사</h2>
                    <a href="https://example.com/2" class="read-more">더 읽기</a>
                </div>
              </div>"""

soup = BeautifulSoup(html_doc, 'html.parser')

articles = soup.find_all('div', class_='article')
for article in articles:
    title = article.find('h2', class_='title').text
    link = article.find('a', class_='read-more')['href']
    print(f"제목: {title}, 링크: {link}")
    
# 출력:
# 제목: 첫 번째 기사, 링크: https://example.com/1
# 제목: 두 번째 기사, 링크: https://example.com/2

5. 흔히 겪는 함정들

이제 지식으로 무장했으니 몇 가지 흔한 실수를 살펴보자. 가장 흔한 문제는 존재하지 않는 속성에 접근하려는 시도야. Python은 친절하지만 그래도 불편한 KeyError로 답할 거야. 이걸 피하려면 속성을 가져올 때 .get() 메서드를 사용해서 기본값을 설정하도록 해.

또한 HTML 요소가 중첩되고 복잡한 구조를 가질 수 있다는 걸 잊지 마. 브라우저에서 코드 구조를 확인하고 BeautifulSoup을 사용하기 전에 정확히 이해했는지 확인해.

이후에는 CSS 선택자를 사용해서 더 정밀하고 구체적인 데이터를 추출하는 방법을 다룰 거야. 그러니 계속 함께하자! BeautifulSoup의 신비한 세계는 이제 시작이야!

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION