Scrape Daily Daylight (R)
R Script สำหรับดึงข้อมูลเวลาดวงอาทิตย์ขึ้น-ตก และคำนวณช่วงแสงในแต่ละวันจากสมาคมดาราศาสตร์ไทย
นี่คือโค้ด R ที่ใช้สำหรับดึงข้อมูลเวลาพระอาทิตย์ขึ้นและพระอาทิตย์ตกจากเว็บไซต์สมาคมดาราศาสตร์ไทย (thaiastro.nectec.or.th) จากนั้นนำข้อมูลมาคำนวณหาความยาวนานของแสงแดด (Daylight Hours) ในแต่ละวันสำหรับจังหวัดที่กำหนด
การดึงข้อมูลชุดนี้มีประโยชน์มากสำหรับการวิจัยที่เกี่ยวข้องกับผลกระทบของสภาพแวดล้อมโดยเฉพาะเรื่องแสง ที่มีต่อการเจริญเติบโตของพืช หรือการศึกษาพฤติกรรมสัตว์
📦 ไลบรารีที่จำเป็นต้องใช้
ก่อนใช้งานโค้ดนี้ ให้ทำการติดตั้งและโหลดไลบรารีเหล่านี้ให้เรียบร้อย:
library(rvest) # สำหรับทำ Web Scraping อ่านโครงสร้าง HTML และดึงข้อมูล
library(dplyr) # สำหรับจัดการและทำความสะอาด dataframe
library(stringr) # สำหรับจัดการรูปแบบข้อความ (String manipulation)
library(lubridate) # สำหรับจัดการและคำนวณวัน-เวลา
library(purrr) # สำหรับการวนลูปอ่านตารางแต่ละเดือน (Functional programming)
💻 ฟังก์ชัน get_daily_daylight
โค้ดเต็มสำหรับฟังก์ชันที่ใช้ดึงข้อมูล
get_daily_daylight <- function(year, province_name) {
# 1. จัดการตัวเลขปี
year_ce <- ifelse(year > 2500, year - 543, year)
index_url <- paste0("https://thaiastro.nectec.or.th/skyevnt/sunmoon/", year_ce, "/")
# 2. ค้นหาลิงก์ของจังหวัดเป้าหมาย
index_page <- tryCatch(
read_html(index_url, encoding = "UTF-8"),
error = function(e) { stop(paste("ไม่สามารถเข้าถึงข้อมูลสารบัญของปี", year_ce)) }
)
links <- index_page %>% html_nodes("a")
prov_df <- data.frame(
province = html_text(links) %>% str_trim(),
href = html_attr(links, "href"),
stringsAsFactors = FALSE
)
matched_row <- prov_df %>% filter(str_detect(province, province_name))
if (nrow(matched_row) == 0) stop(paste("ไม่พบข้อมูลของจังหวัด:", province_name))
# 3. ดึงข้อมูลจากหน้าของจังหวัดนั้นๆ
target_url <- paste0("https://thaiastro.nectec.or.th/skyevnt/sunmoon/", year_ce, "/", matched_row$href[1])
target_page <- read_html(target_url, encoding = "UTF-8")
# ดึงตาราง "ทั้งหมด" ในหน้านั้น (เว็บนี้แยก 1 ตารางต่อ 1 เดือน)
tables <- target_page %>% html_table(fill = TRUE)
# กรองเอาเฉพาะตารางที่มี 11 คอลัมน์ (ตามโครงสร้างมาตรฐานของตารางเวลาเว็บนี้)
valid_tables <- keep(tables, ~ ncol(.x) == 11)
if (length(valid_tables) == 0) stop("ไม่พบตารางที่มีโครงสร้างถูกต้อง (11 คอลัมน์) ในหน้านี้")
# 4. นำตารางทั้ง 12 เดือนมาต่อกัน (Bind rows)
raw_df <- map_df(valid_tables, function(tbl) {
# เปลี่ยนชื่อคอลัมน์ชั่วคราวเพื่อให้ต่อกันได้
colnames(tbl) <- paste0("V", 1:11)
# แปลงทุกคอลัมน์เป็นตัวอักษรเพื่อป้องกัน Error ชนิดข้อมูลชนกัน
mutate_all(tbl, as.character)
})
# ตั้งชื่อคอลัมน์ใหม่ตามโครงสร้างจริง
colnames(raw_df) <- c("DateStr", "Weekday",
"Sunrise", "Sunrise_Azimuth",
"Sunset", "Sunset_Azimuth",
"Moon_Illum",
"Moonrise", "Moonrise_Azimuth",
"Moonset", "Moonset_Azimuth")
# 5. ทำความสะอาดและคำนวณช่วงแสง
final_data <- raw_df %>%
# กรองเอาเฉพาะบรรทัดที่เป็นข้อมูลเวลาจริงๆ (สังเกตจากเครื่องหมาย :)
filter(str_detect(Sunrise, ":") & str_detect(Sunset, ":")) %>%
mutate(
Year = year_ce,
Province = province_name,
# แยกวันที่และเดือนออกจากกัน (เช่น "1 ม.ค." -> Day=1, Month_Th="ม.ค.")
Day = as.integer(str_extract(DateStr, "^\\d+")),
Month_Th = str_replace(DateStr, "^\\d+\\s*", ""),
# แปลงข้อความ "HH:MM" เป็นระยะเวลา (Period)
rise_time = hm(Sunrise),
set_time = hm(Sunset),
# คำนวณช่วงแสงเป็นชั่วโมง (ทศนิยม)
Daylight_Hours = round(time_length(set_time - rise_time, unit = "hour"), 2)
) %>%
# จัดเรียงคอลัมน์ที่จำเป็นสำหรับนำไปใช้งานต่อ
select(Year, Province, Month_Th, Day, Weekday, Sunrise, Sunset, Daylight_Hours)
return(final_data)
}
💡 ตัวอย่างการใช้งานจริง
ดูตัวอย่างฟังก์ชันการดึงข้อมูลความยาวแสงแต่ละวันในปี 2024 ในพื้นที่ต่างๆ
# ดึงข้อมูลของจังหวัดพัทลุง ในปี ค.ศ. 2024
phatthalung_daylight <- get_daily_daylight(2024, "พัทลุง")
# ตรวจสอบ 5 บรรทัดแรกของตารางข้อมูล
head(phatthalung_daylight)
# ดึงข้อมูลของกรุงเทพมหานคร ในปี ค.ศ. 2025
bkk_daylight <- get_daily_daylight(2025, "กรุงเทพมหานคร")
head(bkk_daylight)