1. 테이블 데이터 추출
테이블과 양파의 공통점은 뭘까? 그래, 바로 층층이!
HTML 테이블은 층층이 쌓인 파이와 같은 구조로 볼 수 있어. 요소들은 <table>, <tr> (행), <th> (헤더 셀), 그리고 <td> (일반 셀)로 구성돼. 각각의 요소는 데이터를 표현하는 데 중요한 역할을 하고, 데이터를 추출하려면 각 층을 하나씩 차례로 접근해야 해.
실습, 실습 그리고 또 실습!
다음의 간단한 HTML 테이블로 시작해보자:
<table>
<tr>
<th>이름</th>
<th>나이</th>
<th>도시</th>
</tr>
<tr>
<td>알리사</td>
<td>29</td>
<td>모스크바</td>
</tr>
<tr>
<td>밥</td>
<td>34</td>
<td>상트페테르부르크</td>
</tr>
</table>
첫 번째 단계: 페이지에서 테이블 찾기
웹 페이지의 테이블은 HTML 태그 <table>로 정의되고, 데이터는 <tr> (테이블 행)과 <td> (데이터 셀) 태그 안에 포함돼. BeautifulSoup에서 find 메서드를 사용하면 페이지에서 첫 번째 테이블을 찾을 수 있고, find_all을 사용하면 여러 개의 테이블을 가져올 수 있어.
# 페이지에서 첫 번째 테이블 찾기
table = soup.find("table")
특정 테이블을 추출하려면, 테이블의 id나 class와 같은 속성을 지정해 검색을 세부적으로 조정할 수 있어.
# 클래스에 따라 테이블 검색
table = soup.find("table", {"class": "table-class"})
두 번째 단계: 테이블에서 데이터 추출하기
로드된 후 데이터를 추출할 수 있어. 테이블 데이터는 보통 행에 따라 정렬되므로, 테이블 행을 순회하면서 각각의 셀 데이터를 추출하면 돼.
헤더 추출
테이블 헤더는 보통 첫 번째 행에 위치하며 <th> 태그 안에 있어. find_all을 이용해서 모든 헤더를 리스트로 모을 수 있어.
# 테이블의 첫 번째 행에서 헤더 추출
headers = []
header_row = table.find("tr")
for th in header_row.find_all("th"):
headers.append(th.text.strip())
print("테이블 헤더:", headers)
데이터 행 추출
데이터 행을 추출하려면, 보통 <tr> 태그로 정의된 모든 행을 찾고, 각각의 셀 <td>를 탐색해야 해.
# 모든 데이터 행 추출
data = []
rows = table.find_all("tr")[1:] # 첫 번째 헤더 행 건너뛰기
for row in rows:
row_data = []
for cell in row.find_all("td"):
row_data.append(cell.text.strip())
data.append(row_data)
print("테이블 데이터:", data)
이 코드는 테이블의 행을 하나씩 순회하면서 각각의 셀에서 텍스트를 추출해. 와! 반복문의 마력이 놀랍지 않니?
2. 리스트 작업
리스트 — 테이블의 형님
세상에는 두 가지 끝없는 객체가 있어: 테이블과 리스트. 리스트는 <ul> (순서 없는 리스트)와 <ol> (순서 있는 리스트)로 표현돼, 그 안의 요소는 <li>야. 테이블과는 달리, 리스트는 간단하고 간소화된 구조를 가지고 있어. 이 점이 데이터를 빠르고 효과적으로 처리하는 데 딱이야!
리스트에서 데이터 추출
HTML 리스트의 예를 보자:
<ul>
<li>사과</li>
<li>바나나</li>
<li>포도</li>
</ul>
이제 우리에게 익숙한 BeautifulSoup을 사용해서 데이터를 추출해보자:
html = """
<ul>
<li>사과</li>
<li>바나나</li>
<li>포도</li>
</ul>
"""
soup = BeautifulSoup(html, 'html.parser')
ul = soup.find('ul')
items = ul.find_all('li')
for item in items:
print(item.get_text())
끝! 간단하지만 강력한 접근 방식으로 더 복잡한 구조에도 적용할 수 있어.
3. 테이블 데이터 추출 및 처리 예제
학습한 내용을 기반으로 조금 더 복잡한 구조에서 데이터를 빼내보자:
<table id="courses">
<tr>
<th>코스</th>
<th>강사</th>
</tr>
<tr>
<td>모두를 위한 Python</td>
<td>귀도 반 로썸</td>
</tr>
<tr>
<td>Python으로 자동화하기</td>
<td>에릭 매티스</td>
</tr>
</table>
<ul class="technologies">
<li>Python</li>
<li>JavaScript</li>
<li>HTML & CSS</li>
</ul>
테이블과 리스트의 데이터를 추출하려면 다음과 같이 설정을 조정할 수 있어:
html = """
<table id="courses">
<tr>
<th>코스</th>
<th>강사</th>
</tr>
<tr>
<td>모두를 위한 Python</td>
<td>귀도 반 로썸</td>
</tr>
<tr>
<td>Python으로 자동화하기</td>
<td>에릭 매티스</td>
</tr>
</table>
<ul class="technologies">
<li>Python</li>
<li>JavaScript</li>
<li>HTML & CSS</li>
</ul>
"""
soup = BeautifulSoup(html, 'html.parser')
# 테이블에서 데이터 추출
course_table = soup.find('table', id='courses')
course_rows = course_table.find_all('tr')
for row in course_rows:
cells = row.find_all(['th', 'td'])
for cell in cells:
print(cell.get_text())
print("---")
# 리스트에서 데이터 추출
tech_list = soup.find('ul', class_='technologies')
tech_items = tech_list.find_all('li')
for item in tech_items:
print(item.get_text())
이 스크립트는 두 데이터 유형을 다룰 수 있어. ID와 클래스를 사용해 필요한 요소를 정밀하게 찾는 방법도 보여줬지. 실전에서는 더 복잡한 HTML 구조를 만날 수 있지만, 기본 원칙은 변함없어: 상위 레벨부터 시작해서 요소를 세세히 분석한 다음, 데이터를 추출하면 돼!
4. 부분 요약과 흔한 오류
웹 페이지의 테이블과 리스트를 다루는 건 마치 미로를 탐험하는 것 같아. 때로는 비어 있는 셀이나 누락된 요소 같은 불완전한 데이터를 만날 수 있어. 이럴 땐 데이터가 정확하고 완전한지 확인하는 게 중요해. 흔한 오류로는 없는 요소에 접근하려 하거나, 선택자를 잘못 사용하는 경우가 있어. HTML이 항상 우리가 원하는 대로 깨끗하고 구조화되지 않았다는 걸 기억하고, 예외 처리와 데이터 유효성 검사를 항상 고려해야 해.
이 기술이 어디에 유용할까?
이번 강의에서 배운 내용은 수많은 온라인 소스에서 데이터를 자동으로 추출하고 처리하는 데 도움을 줄 거야. 예를 들어, 주식 거래소의 테이블 데이터를 자동으로 수집하거나, 인터넷 쇼핑몰의 가격 모니터링을 설정하거나, 심지어 블로그와 뉴스 웹사이트에서 정기적으로 데이터 분석을 할 수도 있어. 테이블과 리스트에서 데이터를 추출하는 기술을 익히면, 자동화와 데이터 분석의 세계가 넓어질 거야!
GO TO FULL VERSION