R Academy · บทเรียน

การขูดตารางและลิงก์

แยกวิเคราะห์ตาราง HTML เป็นดาต้าเฟรมและรวบรวมไฮเปอร์ลิงก์ทั้งหมดในหน้า

บทเรียน 3 จาก 413 ขั้นตอน

การขูดตารางและลิงก์ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตาราง HTML ในหน้าเว็บ

ตาราง HTML (<table>) เป็นเป้าหมายที่สะดวกที่สุดสำหรับการดึงข้อมูล เนื่องจากมีโครงสร้างอยู่แล้ว html_table() ของ rvest จะแปลงตารางเหล่านี้เป็นกรอบข้อมูลของ 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)

ดึงลิงก์ทั้งหมดในหน้าเว็บ

ลิงก์คือแท็กแองเคอร์ (<a>) ที่มีแอตทริบิวต์ href ใช้ html_elements(page, 'a') เพื่อดึงแองเคอร์ทั้งหมด จากนั้นใช้ html_attr('href') เพื่อดึง URL และใช้ 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)

พารามิเตอร์ fill ของ html_table()

ตาราง HTML บางครั้งมีเซลล์ที่หายไปหรือแถวที่มีโครงสร้างไม่สม่ำเสมอ พารามิเตอร์ fill=TRUE ใน html_table() จะเติมค่าที่หายไปด้วย 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')

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับการดึงตาราง HTML และลิงก์ด้วย rvest

ทบทวน: ตารางและลิงก์

ประเด็นสำคัญ: html_table() แปลงตาราง HTML เป็นกรอบข้อมูลโดยอัตโนมัติ ใช้ fill=TRUE กับตารางที่มีโครงสร้างไม่สม่ำเสมอ สำหรับลิงก์ ให้ดึงแองเคอร์ทั้งหมดด้วย html_elements('a') ดึงข้อความด้วย html_text2() และดึง URL ด้วย html_attr('href') แปลง URL สัมพัทธ์เป็น URL สัมบูรณ์ด้วย xml2::url_absolute() กรองลิงก์ที่ไม่ต้องการตามรูปแบบ และรวมข้อความในตารางกับ 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')
เริ่มต้นได้ฟรี

เรียนรู้ R ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
43
บทเรียน
159

คำถามที่พบบ่อย

บทเรียน “การขูดตารางและลิงก์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การขูดตารางและลิงก์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การขูดตารางและลิงก์”

แยกวิเคราะห์ตาราง HTML เป็นดาต้าเฟรมและรวบรวมไฮเปอร์ลิงก์ทั้งหมดในหน้า คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การขูดตารางและลิงก์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม

ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้าง HTML และตัวเลือก CSS
  2. พื้นฐาน html_element() และ html_text()
  3. การขูดตารางและลิงก์
  4. การจัดการการแบ่งหน้าและหลายหน้า
← กลับไปที่ R Academy