หลังจากที่ได้เรียน Web Scraping 💻 ในคลาสเรียน R มาแล้ว วันนี้หนุ่มจะพาไปเก็บข้อมูล Pokémon จากหน้าเว็บ Static website ด้วยภาษา R กัน ต่อเนื่องจากบทความ ทำรายงานสถิติประจำเดือนง่ายๆ ด้วยภาษา R ก่อนหน้านี้

โดยหนุ่มจะใช้หน้าเว็บ List of Pokémon | Pokémon Wiki | Fandom นี้ ในการดึงข้อมูลออกมา ดาวน์โหลดรูปเก็บไว้ในเครื่อง และโหลดข้อมูลลง Google sheet ดูน้า พร้อมแล้วไปกันเลย

List of contents

  1. Load library
  2. Extract text from <table> tag
  3. Extract image URL from <table> tag
  4. Combine 2 Data frames
  5. Download images
  6. Load data to GG sheets

Load library

เบื้องต้นหนุ่มจะเรียกใช้ library พื้นฐาน 3 ตัวนะครับ

  • tidyverse เป็น Library ครอบจักรวาลตั้งแต่การ Import หรือนำเข้าข้อมูล, ดัดแปลงรูปแบบข้อมูล, เลือกเฉพาะบางข้อมูลหรือกรุ๊ปข้อมูล ไปจนถึงการ Visualization (dplpyr เพื่อนยากก็อยู่ในนี้)
  • rvest ใช้สำหรับดึงข้อมูลออกมาจากหน้าเว็บ (scraping)
  • googlesheets4 ใช้นำข้อมูลเข้า Google sheets
# Load library
library(rvest)
library(tidyverse)
library(googlesheets4)

Extract text from <table> tag

จากที่บอกไปข้างต้นว่าหนุ่มจะใช้เว็บของ Fandom ในการดึงนะครับ ซึ่งใน page นี้มีข้อมูลตั้งแต่ Generation I จนถึง Generation IX (9 ตารางเลย) ในที่นี้ขอ sample แค่ตารางเดียงก่อนนะครับ (ถ้าต้องเขียน Loop ดึงทั้งหมด เดี๋ยว Post ยาวเกินไป)

จากหัวข้อที่เป็น <table> tag นั่นก็เพราะ หากเราลองคลิกขวาแล้วเลือก inspect ดูจะพบ html code ที่เก็บข้อมูล Pokémon วางอยู่ใน tag <table> ซึ่งจะทำให้ได้โค้ดเป็นแบบนี้

# Extracting text from table tag
pokemon_data <- url %>%
  read_html() %>%
  html_elements("table.wikitable") %>%   # Select <table> tag & .class wikitable
  .[[1]] %>%                             # only 1st table
  html_table()                           # Convert table to df
  
pokemon_data <- pokemon_data %>% mutate(generation = 'I') # add col generation
pokemon_data

หนุ่มใช้ %>% pipe operator ในการจัดการดึงข้อมูลออกมานะครับ โดยมี html_elements() ในการปักหมุดบอกโค้ดว่าต้องการข้อมูลจาก tag: table โดยมี class: wikitable เอาเฉพาะตารางแรกของเว็บนี้ [[1]]

และขอแวะนิดนึงโดยหนุ่มอยากเพิ่มคอลัมน์ generation ให้เท่ากับ I เผื่ออนาคตจะมาเขียนลูปเก็บข้อมูล Generation II, III, IV, V, VI, VII, VIII และ IX ด้วย 🤣 อิอิ เสร็จแล้วก็เรียก df: pokemon_data ออกมาดูหน่อย

Extract image URL from <table> tag

จาก df: pokemon_data ที่คอลัมน์ Sprite เป็นค่า NA เราจะตามเก็บที่หัวข้อนี้นะครับ ซึ่งข้อมูลที่เก็บไว้นั้นอยู่ใน tag <a> เป็นลิงก์ไปหาไฟล์รูปภาพนั้นเอง หนุ่มจะเก็บ URL ของ Pokémon ทุกตัวมา เพื่อดาวน์โหลดรูป และใช้รวม data frame เข้าด้วยกัน

# Extracting image URLs from table tag
image_urls <- url %>%
  read_html() %>%
  html_elements("table.wikitable") %>%  # Select <table> tag & .class wikitable
  .[[1]] %>%                            # only 1st table
  html_elements("a.image") %>%          # Select <a> tag & .class image
  html_attr("href")                     # Extract the "href" attribute (image URL)

image_urls

โค้ดที่ได้นอกจากจะปักหมุดไปที่ tag: table + class: wikitable + ตารางแรก แล้ว ยังเพิ่มเจาะไปที่ tag: a โดยมี class: image จากนั้นใช้ html_attr() เพื่อเลือกเอา href ที่เป็นลิงก์ตรงไปหารูปภาพ จะได้ข้อมูลหน้าตาแบบนี้ออกมา

Combine 2 Data frames

# Combine the image URLs with the Pokemon data
pokemon_data$Image_URL <- image_urls[1:nrow(pokemon_data)]
pokemon_data

ได้ data frame มาแล้ว 2 ตารางคือ pokemon_data และ image_urls จับมันรวมเข้าด้วยกัน จะได้แบบนี้

Download images

เพราะว่าตัว Pokémon น่ารักมาก อยากโหลดมาเก็บไว้ในเครื่องตัวเอง ก็เลยเขียนโค้ดนี้เพื่อวนลูปโหลดแต่ละรูป ได้โค้ดมาแบบนี้ครับ และผลที่ได้ตามคลิปเลยครับ (อย่าลืมไปสร้างโฟลเดอร์รอรับรูปด้วยน้า)

# Optional: Download images
for (i in 1:nrow(pokemon_data)) {
   download.file(pokemon_data$Image_URL[i], paste0("pokemon_images/", pokemon_data$Name[i], ".png"), mode = "wb")
}

สวยงาม~สบายใจที่ได้รูปมาละมาต่อกันเลย

Load data to GG sheets

เราจะต้องใช้ library googlesheets4 และกด Authenticate ร่วมด้วยนิดหน่อย (ในการใช้งานครั้งแรกอาจจะมีติดตั้ง package เพิ่มเติม และกด permission ของ tidyverse นิดนึงนะครับ)

โดยที่สิ่งที่เราจะต้องเตรียมคือต้องไปสร้าง google sheet ก่อน จากนั้นตั้งค่า permission เป็น Anyone with link เป็น Editor แบบนี้ครับ จากนั้นคัดลอก URL เอกสารนี้มาใช้

# Google Sheet URL
sheet_url <- "https://docs.google.com/spreadsheets/d/1mGXpI44CT6tXsFdz9vYA3dDHzqgjVaWdn0Dw1F_fhfA" # Replace with your sheet's URL

# Authenticate
gs4_auth()

write_sheet(pokemon_data, ss = sheet_url, sheet = "PokeList")

หากมีถาม permission ก็กดอนุญาตให้สามารถใช้งานได้นะครับ เสร็จแล้ว sheets ของเราก็มีข้อมูลขึ้นมาแบบนี้เลย

ทีนี้หนุ่มจะเพิ่มให้แต่ละ row แสดงรูป Pokemon ขึ้นมาด้วย ซึ่งจะใช้สูตร =IMAGE(I2,3) เพิ่มเข้าไปในคอลัมน์ “Sprite” และพอขยายความกว้าง x ยาวของเซลล์แล้วจะได้ผลลัพธ์แบบนี้เลยครับ

Conclusion

เย้ๆ ได้มาแล้ว Pokédex ด้วยวิธีการ Web scraping ซึ่งเว็บที่ใช้เป็น Static web เราได้โหลดลงมาเป็น Data frame จากนั้นเอา URL ของรูปภาพ มาโหลดรูปลงเครื่องคอมฯ ของเรา สุดท้ายนำข้อมูลที่ได้โหลดเก็บไว้ใน Google Sheets เพื่อใช้งานต่อ และการต่อยอดอาจจะนำไปประมวลผลทำสถิติ หรือแอพพลิเคชั่นอื่นๆ ได้อีกมากมายเลยครับ

.

ขอบคุณท่านผู้อ่านที่เข้ามาอ่านบทควาามนะครับ ผิดพลาดหรือพิมพ์ผิด ชอบหรือไม่ชอบยังไง อยากให้เขียนบทความไหนเพิ่ม คอมเมนต์บอกกันได้เลยน้า 🙏



Leave a Reply

Your email address will not be published. Required fields are marked *

Search

About

Feasible เว็บไซต์ที่นำเสนออาชีพปัจจุบันที่เรา (เจ้าของเว็บ) กำลังทำ ไม่ว่าจะเป็น นักวิเคราะห์ข้อมูล นักเรียน นักอ่าน นักฟาร์ม และอีกหลากหลายมุมมอง เรียกได้ว่าเป็น ‘แกงโฮะ’ เลยล่ะ ฮ่าๆๆ ติดตาม Content ที่จะทำออกมาได้เรื่อยๆ นะครับ ขอบคุณที่เข้ามาเยี่ยมกัน 😁✌️

Social Icons