테이블에 10개의 열이 표시됩니다. 내보내기를 합니다. CSV에도 10개의 열이 있습니다.
그런데 페이지에는 15개의 열 데이터가 있습니다. 나머지 5개는 어디로 갔을까요?
HTML 테이블에는 보이는 것보다 더 많은 데이터가 포함되어 있는 경우가 많습니다. 숨겨진 열, data 속성, 축소된 행—모두 기본적인 추출 방법으로는 보이지 않습니다.
보이지 않는 데이터를 찾고 추출하는 방법을 알아보겠습니다.
숨겨진 데이터의 유형
1. CSS로 숨겨진 열
가장 단순한 경우입니다. 열이 DOM에 존재하지만 CSS로 숨겨져 있습니다.
<th style="display: none;">내부 ID</th>
<td style="display: none;">12345</td>
또는 클래스를 통해:
.hidden-column { display: none; }
사이트가 이렇게 하는 이유: 모바일 반응형(작은 화면에서 열 숨기기), JavaScript용 내부 데이터, 점진적 공개.
감지 방법: DevTools를 열고 테이블을 검사하여 display: none 또는 visibility: hidden이 있는 셀을 찾습니다.
2. Data 속성
HTML5는 모든 요소에 사용자 정의 data-* 속성을 허용합니다. 테이블은 이 속성을 사용하여 JavaScript가 접근하지만 사용자에게는 보이지 않는 메타데이터를 저장합니다.
<tr data-id="12345" data-category="electronics" data-stock="47">
<td>노트북</td>
<td>₩999,000</td>
</tr>
보이는 테이블에는 "노트북"과 "₩999,000"만 표시됩니다. 하지만 행에는 세 가지 추가 데이터 포인트가 있습니다.
일반적인 data 속성:
-
data-id— 내부 식별자 -
data-sort-value— 정렬용 숫자 값 (표시는 "2024년 1월"이지만 정렬에는 202401이 필요할 때) -
data-raw— 서식 없는 값 (표시는 "₩12억"이지만 데이터는 1200000000) -
data-href— 링크 URL
3. Title 및 툴팁 속성
title 속성은 마우스를 올렸을 때 추가 정보를 포함하는 호버 텍스트를 제공합니다.
<td title="업데이트: 2024-01-15 14:32:00 UTC">1월 15일</td>
셀에는 "1월 15일"이 표시됩니다. 전체 타임스탬프는 툴팁에 있습니다.
4. 축소/확장 가능한 행
드릴다운 기능이 있는 테이블은 클릭할 때까지 세부 행을 숨깁니다.
<tr class="parent-row">
<td>카테고리 A</td>
<td>₩50,000,000</td>
</tr>
<tr class="child-row" style="display: none;">
<td>— 하위 카테고리 A1</td>
<td>₩30,000,000</td>
</tr>
<tr class="child-row" style="display: none;">
<td>— 하위 카테고리 A2</td>
<td>₩20,000,000</td>
</tr>
데이터는 존재합니다. 단지 펼쳐지지 않았을 뿐입니다.
5. 지연 로드 콘텐츠
일부 테이블은 일부만 표시하고 스크롤하거나 "더 보기"를 클릭하면 JavaScript를 통해 더 많은 데이터를 로드합니다.
<table id="results">
<!-- 처음 20행만 렌더링 -->
</table>
<button onclick="loadMore()">더 많은 결과 보기</button>
나머지 데이터는 로딩을 트리거할 때까지 DOM에 없습니다.
숨겨진 데이터 추출
CSS로 숨겨진 열 추출
JavaScript (브라우저 콘솔에서):
// 모든 셀에서 display:none 제거
document.querySelectorAll('td, th').forEach(el => {
el.style.display = '';
});
이제 정상적으로 내보내면 열이 보입니다.
Python + BeautifulSoup:
BeautifulSoup은 CSS를 무시합니다. 가시성에 관계없이 모든 요소를 추출합니다.
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
table = soup.find('table')
for row in table.find_all('tr'):
cells = [td.get_text(strip=True) for td in row.find_all(['td', 'th'])]
print(cells) # 숨겨진 열 포함
Data 속성 추출
JavaScript 방식:
const rows = document.querySelectorAll('table tr');
const data = [];
rows.forEach(row => {
const rowData = {
// 보이는 텍스트
cells: Array.from(row.querySelectorAll('td')).map(td => td.textContent),
// Data 속성
id: row.dataset.id,
category: row.dataset.category,
stock: row.dataset.stock
};
data.push(rowData);
});
console.log(JSON.stringify(data, null, 2));
Python 방식:
for row in table.find_all('tr'):
# data 속성 가져오기
attrs = {k: v for k, v in row.attrs.items() if k.startswith('data-')}
# 셀 텍스트 가져오기
cells = [td.get_text(strip=True) for td in row.find_all('td')]
print(f"Data: {attrs}, Cells: {cells}")
Title 속성 추출
const cells = document.querySelectorAll('table td');
cells.forEach(cell => {
if (cell.title) {
console.log(`표시: ${cell.textContent}, 전체: ${cell.title}`);
}
});
축소된 행 확장
방법 1: 모든 확장 버튼 클릭
// 모든 확장 버튼 찾아서 클릭
document.querySelectorAll('.expand-btn, .toggle-row').forEach(btn => {
btn.click();
});
// DOM 업데이트 대기 후 내보내기
setTimeout(() => {
// 내보내기 로직
}, 1000);
방법 2: 숨김 클래스 제거
document.querySelectorAll('.child-row, .detail-row').forEach(row => {
row.style.display = '';
row.classList.remove('hidden', 'collapsed');
});
지연 로드 트리거
이것은 좀 더 까다롭습니다. 로딩을 트리거하는 동작을 시뮬레이션해야 합니다.
// 무한 스크롤 트리거를 위해 하단으로 스크롤
window.scrollTo(0, document.body.scrollHeight);
// 또는 "더 보기" 반복 클릭
const loadMore = document.querySelector('.load-more-btn');
while (loadMore && !loadMore.disabled) {
loadMore.click();
await new Promise(r => setTimeout(r, 500)); // 로드 대기
}
실제 사례: 정렬 값
스포츠 통계 테이블은 종종 서식이 지정된 숫자를 표시하지만 원시 값으로 정렬합니다.
<td data-sort="1234567">123.4만</td>
<td data-sort="20240115">2024년 1월 15일</td>
<td data-sort="0.347">34.7%</td>
보이는 텍스트만 추출하면 정렬이나 계산이 올바르게 되지 않는 서식 문자열을 얻게 됩니다.
두 값을 모두 추출:
const cells = document.querySelectorAll('table td');
const data = Array.from(cells).map(cell => ({
display: cell.textContent.trim(),
sortValue: cell.dataset.sort || cell.textContent.trim()
}));
브라우저 확장 프로그램이 도움이 되는 경우
좋은 테이블 내보내기 도구는 이 중 일부를 자동으로 처리합니다:
- CSS로 숨겨진 열을 옵션으로 포함 가능
- Data 속성을 추가 열로 추출 가능
- 숫자 정규화로 "₩12.3억"을 1230000000으로 파싱 가능
HTML Table Exporter는 병합된 셀과 서식을 적절히 처리하면서 보이는 콘텐츠를 추출합니다. 코드 없이 더 복잡한 추출이 필요한 경우, 코드 없이 웹사이트에서 테이블 스크래핑하기 가이드를 참조하세요.
Data 속성과 깊이 숨겨진 콘텐츠의 경우 위의 JavaScript 접근 방식이 필요할 수 있습니다.
검사 워크플로
테이블을 추출하기 전에:
- DevTools 열기 (F12)
- 테이블 요소 검사
-
확인 사항:
- 열에
display: none이 있는지 - 행/셀에
data-*속성이 있는지 - 추가 정보가 있는
title속성이 있는지 - 숨겨진 자식 행이 있는지
- "더 보기" 버튼이 있는지
- 열에
- 결정: 보이는 데이터로 충분한지, 숨겨진 데이터가 필요한지?
대부분의 경우 보이는 데이터로 충분합니다. 그러나 그렇지 않을 때, 숨겨진 데이터를 찾고 추출하는 방법을 아는 것이 차이를 만듭니다.
요약
HTML 테이블에는 여러 계층의 데이터가 포함될 수 있습니다:
| 계층 | 접근 방법 |
|---|---|
| 보이는 텍스트 | 표준 내보내기 |
| CSS 숨김 열 | display:none 제거 또는 BeautifulSoup 사용 |
| Data 속성 | JavaScript dataset 또는 Python attrs |
| Title/툴팁 | title 속성 추출 |
| 축소된 행 | 확장 또는 숨김 클래스 제거 |
| 지연 로드 | 먼저 로딩 트리거 |
데이터는 보통 거기에 있습니다. 어디를 봐야 하는지만 알면 됩니다.
보이는 데이터를 내보내야 하나요? gauchogrid.com/ko/html-table-exporter에서 자세히 알아보거나 Chrome 웹 스토어에서 HTML Table Exporter를 무료로 사용해 보세요.
Top comments (0)