html_element()와 html_text() 기초
스크랩한 페이지에서 텍스트, 속성, 테이블 데이터를 추출합니다.
html_element()와 html_text() 기초은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
read_html(): 페이지 불러오기
read_html()은 rvest의 시작점입니다. URL 또는 원시 HTML 문자열을 전달하면 됩니다. 구문 분석된 DOM 트리를 나타내는 xml_document 객체를 반환하며, 바로 조회할 수 있습니다.
library(rvest)
# From a URL (requires internet connection)
# page <- read_html('https://books.toscrape.com')
# From a raw HTML string (great for testing)
page <- read_html('
<html><body>
<h1>Book Store</h1>
<p class="desc">Over 1000 books!</p>
</body></html>
')
class(page) # 'xml_document' 'xml_node'html_element()와 html_elements() 비교
html_element()는 일치하는 첫 번째 노드를 반환하고, 일치하는 노드가 없으면 NA를 반환합니다. html_elements()는 일치하는 모든 노드를 목록으로 반환합니다. 결과가 정확히 하나일 것으로 예상되면 단수형을 사용하고, 목록을 스크래핑할 때는 복수형을 사용합니다.
library(rvest)
page <- read_html('
<ul>
<li class="item">Apple</li>
<li class="item">Banana</li>
<li class="item">Cherry</li>
</ul>
')
# Singular: gets first match
first_item <- html_element(page, '.item')
html_text2(first_item) # 'Apple'
# Plural: gets all matches
all_items <- html_elements(page, '.item')
html_text2(all_items) # c('Apple', 'Banana', 'Cherry')
length(all_items) # 3html_text2()로 깔끔한 텍스트 추출
html_text2()는 노드에서 텍스트 콘텐츠를 추출하고, HTML 태그를 제거하며, 공백을 깔끔하게 정리합니다. <br>을 줄 바꿈으로 처리합니다. 이전 함수인 html_text()는 공백 처리 기능이 더 제한적입니다.
library(rvest)
page <- read_html('
<div class="product">
<h2> Laptop </h2>
<p>Price: <strong>$999</strong></p>
<p> Free shipping </p>
</div>
')
# html_text2 trims whitespace intelligently
title <- html_element(page, 'h2')
html_text2(title) # 'Laptop' (no extra spaces)
# From the whole div - collapses nested text
div <- html_element(page, '.product')
html_text2(div) # 'Laptop\nPrice: $999\nFree shipping'html_attr(): 속성 추출
html_attr(node, 'attr_name')은 HTML 속성의 값을 추출합니다. 링크에서 href를 가져오거나 이미지에서 src, data-* 속성 등을 가져올 때 필수적입니다.
library(rvest)
page <- read_html('
<div>
<a href="https://example.com" title="Example site">Visit</a>
<img src="/images/photo.jpg" alt="A photo">
<div data-price="29.99">Product</div>
</div>
')
# Extract href from link
link <- html_element(page, 'a')
html_attr(link, 'href') # 'https://example.com'
html_attr(link, 'title') # 'Example site'
# Extract src from image
img <- html_element(page, 'img')
html_attr(img, 'src') # '/images/photo.jpg'
# Extract data attributes
div <- html_element(page, 'div[data-price]')
html_attr(div, 'data-price') # '29.99'html_attrs(): 모든 속성
html_attrs(node)는 노드의 모든 속성을 이름이 지정된 문자 벡터로 반환합니다. 속성 이름을 미리 알 수 없거나 요소에서 어떤 속성을 사용할 수 있는지 확인하려는 경우에 유용합니다.
library(rvest)
page <- read_html('
<a href="/page" class="nav-link" id="home" data-section="main">Home</a>
')
link <- html_element(page, 'a')
# Get all attributes at once
attrs <- html_attrs(link)
attrs
# href class id data-section
# '/page' 'nav-link' 'home' 'main'
# Access by name
attrs['href'] # '/page'
attrs['class'] # 'nav-link'
names(attrs) # all attribute nameshtml_children(): 자식 노드
html_children(node)은 요소의 바로 아래 자식 노드를 반환합니다. html_name()과 함께 사용해 태그 이름을 가져오면 페이지 구조를 프로그래밍 방식으로 파악하는 데 유용합니다.
library(rvest)
page <- read_html('
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<span>|</span>
<a href="/contact">Contact</a>
</nav>
')
nav <- html_element(page, 'nav')
# Get all direct children
kids <- html_children(nav)
length(kids) # 4
# Get tag names of children
html_name(kids) # c('a', 'a', 'span', 'a')
# Filter to only anchor children
links <- kids[html_name(kids) == 'a']
html_text2(links) # c('Home', 'About', 'Contact')html_name(): 태그 이름
html_name(node)은 노드의 태그 이름을 소문자 문자열로 반환합니다(예: 'div', 'p', 'a'). 노드를 가져온 후 요소 유형별로 노드 목록을 필터링할 때 유용합니다.
library(rvest)
page <- read_html('
<article>
<h2>Title</h2>
<p>First paragraph.</p>
<img src="img.jpg">
<p>Second paragraph.</p>
</article>
')
article <- html_element(page, 'article')
all_children <- html_children(article)
# Check tag name of each child
html_name(all_children)
# c('h2', 'p', 'img', 'p')
# Get only paragraph children
paras <- all_children[html_name(all_children) == 'p']
html_text2(paras)
# c('First paragraph.', 'Second paragraph.')선택 결과 연결하기
문서뿐 아니라 노드도 html_element()의 첫 번째 인수로 전달할 수 있습니다. 그러면 해당 노드 내부로 검색 범위가 제한됩니다. 이는 상품 카드나 표의 행처럼 반복되는 구조를 스크래핑할 때 매우 중요합니다.
library(rvest)
page <- read_html('
<div class="card">
<h3>Laptop</h3>
<span class="price">$999</span>
</div>
<div class="card">
<h3>Phone</h3>
<span class="price">$499</span>
</div>
')
# Get all cards, then extract fields from each
cards <- html_elements(page, '.card')
names_list <- html_text2(html_elements(page, '.card h3'))
prices_list <- html_text2(html_elements(page, '.card .price'))
data.frame(name = names_list, price = prices_list)NodeSet에서 html_attr 사용하기
nodeset(html_elements()의 결과)에 html_attr()을 호출하면 노드마다 하나씩 속성 값이 포함된 벡터를 반환합니다. 없는 속성은 NA로 반환됩니다.
library(rvest)
page <- read_html('
<ul>
<li><a href="/page1">Page 1</a></li>
<li><a href="/page2">Page 2</a></li>
<li><span>No link</span></li>
<li><a href="/page3">Page 3</a></li>
</ul>
')
# Get all a elements
links <- html_elements(page, 'a')
# html_attr on a nodeset returns a vector
hrefs <- html_attr(links, 'href')
hrefs # c('/page1', '/page2', '/page3')
# Link text alongside hrefs
texts <- html_text2(links)
data.frame(text = texts, href = hrefs)없는 요소 처리하기
일치하는 항목이 없으면 html_element()은 NULL이 아닌 NA 노드를 반환합니다. NA 노드에 html_text2()를 적용하면 NA_character_를 반환합니다. 요소가 선택 사항일 수 있다면 결과에서 항상 NA를 확인하세요.
library(rvest)
page <- read_html('
<div class="product">
<h3>Widget</h3>
<!-- No price tag here -->
</div>
')
# Element exists
title <- html_element(page, 'h3')
html_text2(title) # 'Widget'
# Element does NOT exist -> NA node
price <- html_element(page, '.price')
html_text2(price) # NA
is.na(html_text2(price)) # TRUE
# Safe extraction with default
price_text <- html_text2(price)
if (is.na(price_text)) price_text <- 'N/A'
price_text # 'N/A'종합하여 사용하기
html_elements(), html_text2(), html_attr()을 조합하면 구조화된 데이터를 데이터 프레임으로 스크래핑할 수 있습니다. 이는 rvest를 사용한 웹 스크래핑의 일반적인 최종 목표입니다.
library(rvest)
page <- read_html('
<div class="book">
<a href="/book/1" class="title">R Programming</a>
<span class="author">Hadley Wickham</span>
<span class="rating" data-stars="5">*****</span>
</div>
<div class="book">
<a href="/book/2" class="title">Advanced R</a>
<span class="author">Hadley Wickham</span>
<span class="rating" data-stars="5">*****</span>
</div>
')
titles <- html_text2(html_elements(page, '.title'))
authors <- html_text2(html_elements(page, '.author'))
links <- html_attr(html_elements(page, 'a.title'), 'href')
ratings <- html_attr(html_elements(page, '.rating'), 'data-stars')
data.frame(title=titles, author=authors, link=links, stars=ratings)빠른 확인
HTML 문서를 탐색하는 rvest의 핵심 함수에 대한 지식을 확인해 보세요.
복습: rvest 핵심 함수
핵심 요점: read_html()은 페이지를 불러오고, html_element()는 첫 번째 일치 항목을 가져오며, html_elements()는 모든 일치 항목을 가져옵니다. html_text2()로 텍스트를, html_attr()로 속성을, html_children()로 자식 노드를, html_name()으로 태그 이름을 추출합니다. 없는 요소는 NA 노드로 반환되므로 실제 스크래핑 코드에서는 항상 NA를 처리해야 합니다.
library(rvest)
# Core rvest workflow:
# 1. Load page
# page <- read_html(url)
# 2. Find elements
# node <- html_element(page, 'css-selector')
# nodes <- html_elements(page, 'css-selector')
# 3. Extract content
# html_text2(node) -> text content
# html_attr(node, 'href') -> attribute value
# html_attrs(node) -> all attributes
# html_name(node) -> tag name
# html_children(node) -> child nodes
# 4. Build data frame
# data.frame(title = html_text2(...), link = html_attr(...))
cat('rvest follows the tidy data philosophy')자주 묻는 질문
“html_element()와 html_text() 기초” 강의는 무료인가요?
네 — “html_element()와 html_text() 기초” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“html_element()와 html_text() 기초”에서 뭘 배우나요?
스크랩한 페이지에서 텍스트, 속성, 테이블 데이터를 추출합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
R Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“html_element()와 html_text() 기초” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- HTML 구조와 CSS 선택자
- html_element()와 html_text() 기초
- 테이블과 링크 스크래핑
- 페이지 매김과 여러 페이지 처리