CodeGym /자바 코스 /Python SELF KO /복잡한 HTML 구조에서 데이터 추출하기

복잡한 HTML 구조에서 데이터 추출하기

Python SELF KO
레벨 34 , 레슨 0
사용 가능

1. 복잡한 HTML 구조 작업의 기본

복잡한 HTML 마크업을 분석하기 전에 HTML이 왜 그렇게 혼란스러울 수 있는지 이해하는 것이 중요해! 웹 개발자들은 종종 콘텐츠 구성을 위해 복잡한 중첩된 요소를 사용하는데, 이런 작업은 데이터를 추출하려고 할 때 진짜 골칫거리가 될 수 있어. 하지만 걱정 마—좋은 계획과 도구가 있다면 쉽게 해결할 수 있어!

HTML 트리 분석

HTML 문서를 트리라고 상상해봐: 각 요소는 텍스트 또는 다른 노드를 포함할 수 있는 노드야. 이 트리의 최상위에는 html이 있고, 그다음은 headbody가 있어. 그리고 그 아래에는 다양한 자식 요소들이 놓여 있어. 중첩된 요소들은 이 트리에서 더 깊은 곳에 위치해.

단순한 HTML 구조 예제:

HTML

<html>
  <head>
    <title>예제</title>
  </head>
  <body>
    <div class="content">
      <h1>제목</h1>
      <p>문단 1</p>
      <p>문단 2</p>
      <div class="nested">
        <ul>
          <li>항목 1</li>
          <li>항목 2</li>
          <li><span>항목 3</span></li>
        </ul>
      </div>
    </div>
  </body>
</html>

여기에서 div 요소는 nested 클래스와 함께 있고, 그 안에 ul이 들어있어. 그리고 이 ulli로 채워져 있어. 이런 식으로 요소들이 중첩될 수 있다는 예제야.

2. BeautifulSoup를 사용한 데이터 추출

중첩된 요소에서 데이터 추출하기

BeautifulSoup이 어떻게 작동하는지 기억나? 이제 BeautifulSoup으로 li 리스트에서 텍스트를 추출해 보자. 진짜 데이터 탐정이 되어 중첩 구조에서 데이터를 모아보자!

Python

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, 'html.parser')
nested_items = soup.select('.nested ul li')

for item in nested_items:
    print(item.get_text())

결과:


항목 1
항목 2
항목 3

여기에서 우리는 select 메서드를 사용하여 nested 클래스의 요소 내부에 있는 모든 li를 찾았어. get_text() 메서드는 발견된 요소에서 텍스트를 직접 추출할 수 있게 해줘.

3. 다단계 요소 작업

가끔 데이터가 구조의 깊숙한 곳뿐만 아니라 다양한 레벨에 분산되어 있어서 데이터를 추출하는 작업이 더 어려워질 수 있어. 이제 더 복잡한 HTML 트리에서 데이터를 추출하는 방법을 살펴보자.

복잡한 구조의 예제:

HTML

<html>
  <body>
    <div class="wrapper">
      <div class="header">
        <h1>이것은 제목입니다</h1>
      </div>
      <div class="content">
        <div class="article">
          <h2>기사 1</h2>
          <p>기사 1의 내용</p>
        </div>
        <div class="article">
          <h2>기사 2</h2>
          <p>기사 2의 내용</p>
        </div>
      </div>
      <div class="footer">
        <p>연락처 정보</p>
      </div>
    </div>
  </body>
</html>

레벨별 데이터 추출

이제 모든 기사 제목과 내용을 추출해 보자.

Python

articles = soup.select('.content .article')

for article in articles:
    title = article.find('h2').get_text()
    content = article.find('p').get_text()
    print(f'제목: {title}')
    print(f'내용: {content}\n')

기대 출력:


제목: 기사 1
내용: 기사 1의 내용

제목: 기사 2
내용: 기사 2의 내용

우리는 select 메서드와 find 메서드를 결합하여 목표를 달성했어. select는 부모 요소를 찾는 데 도움을 주고, find는 자식 요소에서 정보를 추출해.

4. 중첩된 요소 작업의 특징

웹 페이지를 살펴보면 동일한 클래스나 태그를 가진 여러 중첩 요소를 만나게 될 수도 있어. 이런 경우 컨텍스트 검색과 명확한 요소 식별을 사용하면 오류를 피할 수 있어.

복잡한 중첩 예제:

HTML

<html>
  <body>
    <div class="container">
      <div class="item">
        <h2>번호 1</h2>
        <div class="details">세부정보 1</div>
      </div>
      <div class="item">
        <h2>번호 2</h2>
        <div class="details">세부정보 2</div>
        <div class="additional">
          <div class="info">추가 정보</div>
        </div>
      </div>
    </div>
  </body>
</html>

중첩을 고려한 데이터 추출

혼란을 피하기 위해 더 구체적인 요소를 찾아야 해:

Python

items = soup.select('.container .item')

for item in items:
    number = item.find('h2').get_text()
    details = item.select_one('.details').get_text()
    additional_info = item.select_one('.additional .info')
    
    print(f'번호: {number}')
    print(f'세부정보: {details}')
    
    if additional_info:
        print(f'추가 정보: {additional_info.get_text()}')
    print()

여기에서 우리는 select_one 메서드를 사용했어. 이 메서드는 첫 번째 검색된 요소만 반환해서 추가 블록의 데이터 중복을 피할 수 있어.

5. 실무적인 측면과 일반적인 실수

복잡한 HTML 구조를 다룰 때 쉽게 혼란에 빠지거나 오류를 만날 수 있어. 일반적인 오류 중 하나는 존재하지 않는 요소에 접근하려는 시도로 인한 AttributeError야. 이를 피하려면 항상 요소가 존재하는지 확인한 다음 작업을 수행해야 해.

또 한 가지 중요한 점은 데이터를 "즉시" 추출하려고 하지 않는 거야. 경우에 따라 구조를 먼저 분석하고 디버그 출력을 사용하며 중간 결과를 확인하는 것이 유용할 수 있어.

실제 프로젝트에서 중첩된 HTML 구조를 다루는 기술은 매우 중요할 수 있어. 이는 웹 스크래핑뿐만 아니라 웹 인터페이스 테스트, 자동화 테스트 및 복잡한 API 데이터 분석(포맷화되고 중첩된 응답 제공)에서도 적용될 수 있어.

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