html_element()とhtml_text()の基礎
スクレイピングしたページからテキスト、属性、テーブルデータを抽出します。
「html_element()とhtml_text()の基礎」はCoddyKit上の無料R Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応の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()は一致するノードの最初の1つを返します(見つからない場合はNA)。html_elements()は一致するすべてのノードをリストとして返します。結果が1つだけの想定なら単数形を、リストをスクレイピングするなら複数形を使用します。
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()を呼び出すと、ノードごとに1つの属性値を持つベクトルが返されます。属性が存在しない場合は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を使ったWebスクレイピングで一般的に目指す結果です。
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時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。
「html_element()とhtml_text()の基礎」で何を学びますか?
スクレイピングしたページからテキスト、属性、テーブルデータを抽出します。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
R Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「html_element()とhtml_text()の基礎」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このR Academyレッスンでコードを書いて実行できますか?
はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- HTML構造とCSSセレクター
- html_element()とhtml_text()の基礎
- テーブルとリンクのスクレイピング
- ページネーションと複数ページの処理