โครงสร้าง HTML และตัวเลือก CSS
ทำความเข้าใจทรี DOM และเขียนตัวเลือก CSS เพื่อกำหนดเป้าหมายองค์ประกอบ
โครงสร้าง HTML และตัวเลือก CSS เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
ต้นไม้ DOM ของ HTML
หน้าเว็บทุกหน้ามีโครงสร้างเป็นต้นไม้ Document Object Model (DOM) องค์ประกอบ HTML จะซ้อนอยู่ภายในกันและกัน ก่อให้เกิดลำดับชั้นระหว่างองค์ประกอบแม่กับองค์ประกอบลูก การดึงข้อมูลจากเว็บจะนำทางไปตามต้นไม้นี้เพื่อแยกข้อมูลออกมา
# HTML structure conceptually:
# <html>
# <body>
# <div class='container'>
# <h1 id='title'>Hello</h1>
# <p class='text'>World</p>
# </div>
# </body>
# </html>
# rvest lets us query this tree with CSS selectors
library(rvest)
html <- read_html('<div><h1>Title</h1><p class="info">Text</p></div>')
html_text(html_element(html, 'h1'))ตัวเลือก CSS: ตัวเลือกแท็ก
ตัวเลือก CSS ที่ง่ายที่สุดคือการเลือกองค์ประกอบตามชื่อแท็ก การเขียน p จะเลือกองค์ประกอบย่อหน้าทั้งหมด ส่วนการเขียน h1 จะเลือกหัวข้อระดับ 1 ทั้งหมด
library(rvest)
html <- read_html('
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
<h2>A heading</h2>
</div>
')
# Tag selector: selects all <p> elements
nodes <- html_elements(html, 'p')
html_text2(nodes)
# Returns: c('First paragraph', 'Second paragraph')ตัวเลือก CSS: คลาสและ ID
ใช้ .classname เพื่อเลือกองค์ประกอบตามคลาส และใช้ #idname เพื่อเลือกองค์ประกอบที่มี ID เฉพาะ คลาสสามารถปรากฏซ้ำได้หลายครั้ง แต่ ID ควรมีค่าไม่ซ้ำกันภายในหน้าเว็บ
library(rvest)
html <- read_html('
<div>
<p class="highlight">Important text</p>
<p class="normal">Regular text</p>
<span id="price">$9.99</span>
</div>
')
# Class selector (prefix with .)
html_text2(html_element(html, '.highlight'))
# ID selector (prefix with #)
html_text2(html_element(html, '#price'))ตัวเลือกองค์ประกอบสืบทอดและองค์ประกอบลูก
div p จะเลือก p ใด ๆ ที่อยู่ภายใน div ไม่ว่าจะซ้อนลึกเพียงใด ส่วน div > p จะเลือกเฉพาะองค์ประกอบลูกโดยตรง และ h1 + p จะเลือก p ที่อยู่ถัดจาก h1 ทันที ซึ่งเรียกว่าองค์ประกอบพี่น้องที่อยู่ติดกัน
library(rvest)
html <- read_html('
<div class="outer">
<p>Direct child</p>
<section>
<p>Nested deeper</p>
</section>
</div>
')
# Descendant: both paragraphs
all_p <- html_elements(html, 'div p')
length(all_p) # 2
# Direct child only
direct_p <- html_elements(html, 'div.outer > p')
length(direct_p) # 1ตัวเลือกแอตทริบิวต์
ตัวเลือกแอตทริบิวต์ของ CSS ช่วยให้คุณกรองตามแอตทริบิวต์ HTML ได้: [attr] ตรวจสอบว่ามีแอตทริบิวต์อยู่หรือไม่ [attr='val'] ตรวจสอบค่าที่ตรงกันทุกประการ และ [attr*='val'] ตรวจสอบว่าค่ามีสตริงย่อยนี้อยู่หรือไม่
library(rvest)
html <- read_html('
<div>
<a href="https://example.com">External</a>
<a href="/about">Internal</a>
<a>No href</a>
</div>
')
# Select only anchors that have an href attribute
with_href <- html_elements(html, 'a[href]')
length(with_href) # 2
# Select anchors with href starting with https
external <- html_elements(html, 'a[href^="https"]')
html_text2(external) # 'External'พื้นฐาน XPath
XPath เป็นทางเลือกนอกเหนือจากตัวเลือก CSS และมีความสามารถมากกว่าสำหรับคำสั่งที่ซับซ้อน ใน rvest ให้ใช้ html_element(html, xpath='//tag') //p หมายถึง p ที่อยู่ ณ ตำแหน่งใด ๆ และ /html/body/p คือเส้นทางแบบสัมบูรณ์
library(rvest)
html <- read_html('
<html><body>
<table>
<tr><td class="price">10.99</td></tr>
<tr><td class="price">5.50</td></tr>
</table>
</body></html>
')
# XPath: select all td with class price
nodes <- html_elements(html, xpath = '//td[@class="price"]')
html_text2(nodes)
# c('10.99', '5.50')
# XPath text() function
nodes2 <- html_elements(html, xpath = '//td[contains(@class,"price")]')
html_text2(nodes2)การรวมตัวเลือก
คุณสามารถรวมตัวเลือกเพื่อเพิ่มความแม่นยำได้ div.card h2 จะเลือก h2 ที่อยู่ภายใน div ซึ่งมีคลาส card เครื่องหมายจุลภาคใช้คั่นตัวเลือกอิสระหลายรายการ: h1, h2, h3 จะเลือกหัวข้อทั้งสามระดับ
library(rvest)
html <- read_html('
<div class="card">
<h2>Card Title</h2>
<p class="desc">Description here</p>
<span class="price">$19</span>
</div>
<div class="footer">
<h2>Footer Heading</h2>
</div>
')
# Only h2 inside .card
card_h2 <- html_element(html, 'div.card h2')
html_text2(card_h2) # 'Card Title'
# Multiple selectors with comma
price_desc <- html_elements(html, '.price, .desc')
html_text2(price_desc)เครื่องมือ SelectorGadget
SelectorGadget เป็นบุ๊กมาร์กเล็ตของเบราว์เซอร์ที่ช่วยค้นหาตัวเลือก CSS แบบโต้ตอบ คลิกองค์ประกอบที่ต้องการ ซึ่งจะถูกเน้นเป็นสีเขียว และองค์ประกอบที่ไม่ต้องการ ซึ่งจะถูกเน้นเป็นสีแดง จากนั้นเครื่องมือจะสร้างตัวเลือก CSS ที่สั้นที่สุดให้อัตโนมัติ
# SelectorGadget workflow:
# 1. Open target page in Chrome/Firefox
# 2. Activate SelectorGadget bookmarklet
# 3. Click element you want -> turns green, selector appears
# 4. Click elements you DON'T want -> turns red, selector narrows
# 5. Copy the selector shown at the bottom
# 6. Use in rvest:
library(rvest)
# Example: SelectorGadget found '.product-title' for us
# page <- read_html('https://books.toscrape.com')
# titles <- html_elements(page, '.product_pod h3 a')
# html_text2(titles)
cat('SelectorGadget is available at selectorgadget.com')ตรวจสอบหน้าเว็บใน DevTools
DevTools ของเบราว์เซอร์ (F12) ช่วยให้คุณตรวจสอบ DOM ได้โดยตรง คลิกขวาที่องค์ประกอบใด ๆ เลือก ตรวจสอบ แล้วแผง Elements จะแสดง HTML การเลื่อนเมาส์ไปบนองค์ประกอบจะเน้นองค์ประกอบนั้นบนหน้าเว็บ ช่วยให้คุณระบุแท็ก คลาส และ ID ที่ต้องการเลือกได้อย่างถูกต้อง
# DevTools workflow for finding selectors:
# 1. F12 -> Elements tab
# 2. Click the cursor icon (Inspector)
# 3. Click the element on the page
# 4. Right-click highlighted HTML -> Copy -> Copy selector
# 5. Paste selector into rvest
# The copied selector might look like:
# '#main > div.results > article:nth-child(1) > h3'
# Simplify it: usually '.results h3' works just as well
# Validate your selector in the Console with:
# document.querySelectorAll('.results h3')
library(rvest)
cat('Always verify selectors return the elements you expect')คลาสเทียมและ nth-child
คลาสเทียมของ CSS เช่น :first-child, :last-child และ :nth-child(n) ช่วยให้คุณเลือกองค์ประกอบตามตำแหน่งภายในองค์ประกอบแม่ได้ ซึ่งมีประโยชน์เมื่อองค์ประกอบไม่มีคลาสที่ใช้แยกความแตกต่าง
library(rvest)
html <- read_html('
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
')
# First item
first <- html_element(html, 'li:first-child')
html_text2(first) # 'First'
# Third item
third <- html_element(html, 'li:nth-child(3)')
html_text2(third) # 'Third'
# Even items
evens <- html_elements(html, 'li:nth-child(even)')
html_text2(evens) # c('Second', 'Fourth')กฎความจำเพาะของตัวเลือก
เมื่อมีตัวเลือกหลายรายการที่อาจตรงกัน ความจำเพาะจะเป็นตัวกำหนดว่ารายการใดมีผลเหนือกว่า ID มีความสำคัญเหนือคลาส และคลาสมีความสำคัญเหนือแท็ก ในการดึงข้อมูลจากเว็บ เรื่องนี้มีความสำคัญน้อยกว่า แต่การเข้าใจความจำเพาะจะช่วยให้คุณเขียนตัวเลือกที่แม่นยำและหลีกเลี่ยงการตรงกันผิดรายการได้
library(rvest)
html <- read_html('
<div id="header" class="top">
<p class="title">Main Title</p>
</div>
<div class="content">
<p class="title">Content Title</p>
</div>
')
# Overly broad: gets BOTH titles
broad <- html_elements(html, 'p.title')
html_text2(broad)
# Specific: only header title
specific <- html_element(html, '#header p.title')
html_text2(specific) # 'Main Title'
# Be as specific as needed but not more
content_title <- html_element(html, '.content .title')
html_text2(content_title)ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับตัวเลือก CSS ที่ใช้ในการดึงข้อมูลจากเว็บไซต์ด้วย rvest
ทบทวน: ตัวเลือก HTML และ CSS
ประเด็นสำคัญ: DOM มีโครงสร้างเป็นต้นไม้ และตัวเลือก CSS ใช้สำหรับนำทางในโครงสร้างนั้น ใช้ tag เพื่อระบุชนิดองค์ประกอบ ใช้ .class สำหรับคลาส ใช้ #id สำหรับองค์ประกอบที่ไม่ซ้ำ ใช้ > สำหรับองค์ประกอบลูกโดยตรง และใช้ [attr] สำหรับแอตทริบิวต์ SelectorGadget และ DevTools ช่วยค้นหาตัวเลือกแบบโต้ตอบได้ ส่วน XPath (//tag[@attr]) ใช้จัดการกรณีที่ CSS ไม่สามารถตอบโจทย์ได้
# Summary of key CSS selectors for web scraping:
# 'p' -> all <p> elements
# '.price' -> elements with class='price'
# '#main' -> element with id='main'
# 'div > p' -> direct child p of div
# 'a[href]' -> a elements that have href attr
# 'a[href*=http] -> a elements where href contains 'http'
# 'li:nth-child(2)' -> second li in its parent
# 'h1, h2' -> both h1 and h2 elements
# xpath='//td[@class="price"]' -> XPath alternative
library(rvest)
cat('Selectors are the foundation of reliable web scraping')คำถามที่พบบ่อย
บทเรียน “โครงสร้าง HTML และตัวเลือก CSS” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “โครงสร้าง HTML และตัวเลือก CSS” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “โครงสร้าง HTML และตัวเลือก CSS”
ทำความเข้าใจทรี DOM และเขียนตัวเลือก CSS เพื่อกำหนดเป้าหมายองค์ประกอบ คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “โครงสร้าง HTML และตัวเลือก CSS” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม
ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- โครงสร้าง HTML และตัวเลือก CSS
- พื้นฐาน html_element() และ html_text()
- การขูดตารางและลิงก์
- การจัดการการแบ่งหน้าและหลายหน้า