0Pricing
R Academy · 강의

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)  # 3

html_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 names

html_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 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. HTML 구조와 CSS 선택자
  2. html_element()와 html_text() 기초
  3. 테이블과 링크 스크래핑
  4. 페이지 매김과 여러 페이지 처리
← R Academy(으)로 돌아가기