테이블과 링크 스크래핑
HTML 테이블을 데이터 프레임으로 구문 분석하고 페이지의 모든 하이퍼링크를 수집합니다.
테이블과 링크 스크래핑은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
웹 페이지의 HTML 표
HTML 표(<table>)는 이미 구조를 갖추고 있으므로 스크래핑하기에 가장 편리한 대상입니다. rvest의 html_table()은 표를 R 데이터 프레임으로 직접 변환하며, 헤더도 자동으로 처리합니다.
library(rvest)
html <- read_html('
<table>
<thead><tr><th>Country</th><th>GDP</th><th>Pop</th></tr></thead>
<tbody>
<tr><td>USA</td><td>25T</td><td>330M</td></tr>
<tr><td>China</td><td>18T</td><td>1400M</td></tr>
</tbody>
</table>
')
# html_table converts to data frame
tbl <- html_table(html_element(html, 'table'))
class(tbl) # 'data.frame'
names(tbl) # c('Country', 'GDP', 'Pop')
nrow(tbl) # 2
print(tbl)전체 페이지에서 html_table() 사용하기
페이지에 표가 여러 개 있으면 html_elements()(복수형)로 모든 표를 가져온 다음, 결과 노드 집합에 html_table()을 적용하여 데이터 프레임 목록을 반환받습니다. 인덱스로 필요한 표를 선택하세요.
library(rvest)
html <- read_html('
<table id="t1"><tr><th>A</th></tr><tr><td>1</td></tr></table>
<table id="t2"><tr><th>X</th><th>Y</th></tr>
<tr><td>10</td><td>20</td></tr></table>
')
# Get ALL tables as a list of data frames
tables <- html_table(html_elements(html, 'table'))
length(tables) # 2
# First table
tables[[1]]
# Second table
tables[[2]]
# Select a specific table by its id
table2 <- html_table(html_element(html, '#t2'))
print(table2)표 데이터 정리하기
웹사이트에서 스크래핑한 표에는 헤더가 정리되지 않았거나 셀이 병합되어 있거나 불필요한 공백이 포함된 경우가 많습니다. 헤더에는 janitor::clean_names()를 사용하고, 셀 값은 일반적인 dplyr/stringr 연산으로 정리하세요.
library(rvest)
html <- read_html('
<table>
<tr><th>Product Name</th><th>Price (USD)</th><th>In Stock?</th></tr>
<tr><td> Widget A </td><td>$12.50</td><td>Yes</td></tr>
<tr><td>Gadget B</td><td>$7.99</td><td>No</td></tr>
</table>
')
df <- html_table(html_element(html, 'table'))
# Clean column names
names(df) <- c('product', 'price', 'in_stock')
# Strip whitespace and dollar signs
df$product <- trimws(df$product)
df$price <- as.numeric(gsub('[$]', '', df$price))
df$in_stock <- df$in_stock == 'Yes'
print(df)페이지의 모든 링크 스크래핑하기
링크는 href 속성을 가진 앵커(<a>) 태그입니다. html_elements(page, 'a')로 모든 앵커를 가져온 다음, URL에는 html_attr('href')를, 링크 텍스트에는 html_text2()를 사용하세요.
library(rvest)
html <- read_html('
<div>
<a href="/about">About Us</a>
<a href="/products">Products</a>
<a href="https://partner.com" rel="external">Partner</a>
<a>No href link</a>
</div>
')
# Get all anchor elements
anchors <- html_elements(html, 'a')
# Extract text and href
link_text <- html_text2(anchors)
link_href <- html_attr(anchors, 'href')
data.frame(text = link_text, href = link_href)
# Note: last row has NA href의미 있는 링크 필터링하기
실제 페이지에는 원하는 링크뿐 아니라 탐색 링크, 푸터 링크, 내부 앵커가 함께 섞여 있습니다. NA, 앵커(#), javascript: 링크를 제거하고 패턴 매칭을 적용하여 관련 URL만 남기세요.
library(rvest)
html <- read_html('
<div>
<a href="/article/1">Article One</a>
<a href="/article/2">Article Two</a>
<a href="#top">Back to top</a>
<a href="javascript:void(0)">JS link</a>
<a href="/article/3">Article Three</a>
</div>
')
anchors <- html_elements(html, 'a')
hrefs <- html_attr(anchors, 'href')
texts <- html_text2(anchors)
# Keep only article links
article_idx <- grepl('^/article/', hrefs) & !is.na(hrefs)
article_links <- data.frame(
text = texts[article_idx],
href = hrefs[article_idx]
)
print(article_links)상대 URL을 절대 URL로 변환하기
스크래핑한 href 값은 /page와 같은 상대 경로인 경우가 많습니다. 기본 URL을 앞에 붙여 절대 URL로 변환하세요. xml2::url_absolute() 함수가 이 작업을 올바르게 처리합니다.
library(rvest)
base_url <- 'https://books.toscrape.com'
html <- read_html('
<ul>
<li><a href="/catalogue/book1">Book One</a></li>
<li><a href="/catalogue/book2">Book Two</a></li>
<li><a href="https://external.com/book">External</a></li>
</ul>
')
hrefs <- html_attr(html_elements(html, 'a'), 'href')
# xml2::url_absolute resolves relative + keeps absolute
abs_urls <- xml2::url_absolute(hrefs, base = base_url)
abs_urls
# 'https://books.toscrape.com/catalogue/book1'
# 'https://books.toscrape.com/catalogue/book2'
# 'https://external.com/book' <- kept as-is대상 지정 링크 스크래핑
모든 링크를 스크래핑한 후 필터링하는 대신, 필요한 링크만 대상으로 삼는 구체적인 CSS 선택자를 사용하세요. 정확도를 높이려면 요소의 맥락과 속성 선택자를 함께 사용하세요.
library(rvest)
html <- read_html('
<nav class="breadcrumb">
<a href="/">Home</a> > <a href="/books">Books</a>
</nav>
<ul class="products">
<li><a href="/books/1" class="prod-link">Clean Code</a></li>
<li><a href="/books/2" class="prod-link">Refactoring</a></li>
</ul>
<footer>
<a href="/privacy">Privacy</a>
</footer>
')
# Target ONLY product links (not nav or footer)
prod_links <- html_elements(html, 'ul.products a.prod-link')
data.frame(
title = html_text2(prod_links),
url = html_attr(prod_links, 'href')
)표 데이터와 링크 데이터 병합하기
표의 셀에 링크가 포함된 경우가 많습니다. 텍스트 값에는 html_table()을 사용하고, 포함된 링크에는 대상이 지정된 html_attr()을 사용하여 더 풍부한 데이터 프레임을 만드세요.
library(rvest)
html <- read_html('
<table class="results">
<tr><th>Book</th><th>Author</th></tr>
<tr>
<td><a href="/b/1">Clean Code</a></td>
<td>Robert Martin</td>
</tr>
<tr>
<td><a href="/b/2">Refactoring</a></td>
<td>Martin Fowler</td>
</tr>
</table>
')
# Get text from table
df <- html_table(html_element(html, 'table'))
# Get links embedded in first column
links <- html_attr(html_elements(html, 'table td a'), 'href')
df$url <- links
print(df)html_table()의 fill 매개변수
HTML 표에는 때때로 없는 셀이 있거나 행 구조가 일정하지 않습니다. html_table()의 fill=TRUE 매개변수는 오류를 발생시키는 대신 없는 값을 NA로 채웁니다.
library(rvest)
html <- read_html('
<table>
<tr><th>Name</th><th>Score</th><th>Grade</th></tr>
<tr><td>Alice</td><td>95</td><td>A</td></tr>
<tr><td>Bob</td><td>80</td></tr>
</table>
')
# Without fill=TRUE this may error on uneven rows
df <- html_table(html_element(html, 'table'), fill = TRUE)
print(df)
# Name Score Grade
# Alice 95 A
# Bob 80 <NA>
# fill=TRUE is safe even when rows are uniform
is.na(df[2, 'Grade']) # TRUE이미지 소스 추출하기
이미지는 src 속성을 사용하며, 지연 로딩을 위해 data-src를 사용하는 경우도 있습니다. 동일한 html_attr() 방식을 사용하여 다운로드하거나 목록으로 정리할 이미지 URL을 추출할 수 있습니다.
library(rvest)
html <- read_html('
<div class="gallery">
<img src="/img/photo1.jpg" alt="Sunset">
<img src="/img/photo2.jpg" alt="Mountains">
<img data-src="/img/lazy.jpg" class="lazy" alt="Lake">
</div>
')
# Regular images
images <- html_elements(html, 'img')
srcs <- html_attr(images, 'src')
alts <- html_attr(images, 'alt')
data.frame(alt = alts, src = srcs)
# For lazy-loaded images check data-src
lazy_src <- html_attr(html_element(html, '.lazy'), 'data-src')
lazy_src # '/img/lazy.jpg'스크래핑한 데이터 저장하기
표와 링크를 데이터 프레임으로 스크래핑한 후 write.csv() 또는 readr::write_csv()로 결과를 저장하세요. 데이터 출처를 추적할 수 있도록 항상 타임스탬프나 원본 URL을 포함하세요.
library(rvest)
html <- read_html('
<table>
<tr><th>Product</th><th>Price</th></tr>
<tr><td>Widget</td><td>9.99</td></tr>
<tr><td>Gadget</td><td>14.50</td></tr>
</table>
')
df <- html_table(html_element(html, 'table'))
# Add metadata
df$scraped_at <- Sys.time()
df$source_url <- 'https://example.com/products'
# Save to CSV
# write.csv(df, 'products.csv', row.names = FALSE)
print(df)
cat('Data ready for analysis or storage')빠른 확인
rvest를 사용한 HTML 표와 링크 스크래핑에 대한 이해도를 확인해 보세요.
복습: 표와 링크
핵심 요점: html_table()은 HTML 표를 데이터 프레임으로 자동 변환하며, 구조가 일정하지 않은 표에는 fill=TRUE를 사용합니다. 링크의 경우 html_elements('a')로 모든 앵커를 가져오고, html_text2()로 텍스트를, html_attr('href')로 URL을 가져옵니다. 상대 URL은 xml2::url_absolute()로 절대 URL로 변환하세요. 패턴을 사용하여 원치 않는 링크를 필터링하세요. 표의 텍스트와 포함된 링크 URL을 병합하면 더 풍부한 데이터 세트를 만들 수 있습니다.
library(rvest)
# Table scraping pattern:
# tables <- html_table(html_elements(page, 'table'))
# df <- tables[[1]]
# Link scraping pattern:
# links <- html_elements(page, 'a[href]')
# data.frame(
# text = html_text2(links),
# url = xml2::url_absolute(
# html_attr(links, 'href'),
# base = base_url
# )
# )
# Combine: scrape table text AND embedded link URLs
cat('Tables + links = most of what the web offers')자주 묻는 질문
“테이블과 링크 스크래핑” 강의는 무료인가요?
네 — “테이블과 링크 스크래핑” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“테이블과 링크 스크래핑”에서 뭘 배우나요?
HTML 테이블을 데이터 프레임으로 구문 분석하고 페이지의 모든 하이퍼링크를 수집합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
R Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“테이블과 링크 스크래핑” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.