Programming
น้องๆ เคยอยากได้ข้อมูลจากเว็บ แต่ขี้เกียจ copy-paste เองมั้ย? Web Scraping นี่แหละคือตัวช่วย! มันคือการดึงข้อมูลจากเว็บแบบอัตโนมัติ ด้วยโปรแกรมที่เราเขียนขึ้นมาเอง
สมัยผมทำร้านเน็ต SiamCafe (ตั้งแต่ปี 2540 กว่าๆ แน่ะ) ก็เคยใช้ Scraping ดึงข้อมูลเกมมา update ในร้านนะ ประหยัดเวลาไปเยอะเลย (แอบกระซิบว่าตอนนั้นไม่ได้ใช้ Python นะ ใช้ Perl ซะมากกว่า 555)
ทำไมมันถึงสำคัญ? ลองคิดดูสิ เราสามารถดึงข้อมูลสินค้าจากเว็บ e-commerce มาเปรียบเทียบราคา, ดึงข้อมูลข่าวจากหลายๆ สำนักข่าวมาวิเคราะห์ sentiment, หรือแม้แต่ดึงข้อมูลสถิติจากเว็บต่างๆ มาทำ dashboard ได้หมดเลย
เว็บส่วนใหญ่สร้างด้วย HTML น้องๆ ต้องเข้าใจโครงสร้าง HTML ก่อนนะ ถึงจะดึงข้อมูลได้ถูกที่ ลองนึกภาพ HTML เป็นบ้าน แต่ละส่วนก็มีป้ายชื่อแปะไว้ เช่น <h1> คือหัวข้อใหญ่ <p> คือย่อหน้า <a> คือลิงก์
CSS Selectors เหมือนเป็น GPS ที่จะนำทางเราไปหาข้อมูลที่เราต้องการใน HTML อีกทีนึง เช่น #id คือเลือก element ที่มี id ชื่อนั้น .class คือเลือก element ที่มี class ชื่อนั้น div > p คือเลือก paragraph ที่เป็นลูกของ div
เวลาเราเปิดเว็บ Browser จะส่ง HTTP Request ไปขอข้อมูลจาก Server แล้ว Server ก็จะส่ง HTML กลับมาให้เรา การ Scraping ก็ต้องส่ง Request แบบเดียวกัน เพื่อเอา HTML มา parse
Python มี Library เด็ดๆ ที่ช่วยเรื่อง Web Scraping เยอะมาก ที่ฮิตๆ ก็มี BeautifulSoup กับ Scrapy
BeautifulSoup ใช้งานง่าย เหมาะสำหรับโปรเจคเล็กๆ หรือมือใหม่ Scrapy จะซับซ้อนกว่า แต่ powerful กว่า เหมาะสำหรับโปรเจคใหญ่ๆ ที่ต้องการ scalability
วันนี้ผมจะสอนใช้ BeautifulSoup นะ ง่ายดี เริ่มต้นได้ไว
ก่อนอื่นต้อง install library ก่อนนะ เปิด Command Prompt หรือ Terminal แล้วพิมพ์
pip install beautifulsoup4 requests
ต่อไปเราจะดึง HTML จากเว็บที่เราต้องการ
import requests
from bs4 import BeautifulSoup
url = "https://siamcafe.net/blog/" # หรือเว็บอะไรก็ได้ที่น้องๆ อยากลอง
response = requests.get(url)
html_content = response.content
จากนั้นเราจะใช้ BeautifulSoup มา parse HTML
soup = BeautifulSoup(html_content, "html.parser")
ทีนี้ก็ถึงเวลาดึงข้อมูลที่เราต้องการแล้ว สมมติเราอยากดึงหัวข้อข่าวจาก SiamCafe Blog
headlines = soup.find_all("h2", class_="entry-title") # ดึง h2 ที่มี class เป็น entry-title
for headline in headlines:
print(headline.text)
แค่นี้เอง! ลองรัน code ดู น้องๆ ก็จะได้หัวข้อข่าวจาก SiamCafe Blog แล้ว
นอกจาก Python แล้ว ก็ยังมีภาษาอื่นๆ ที่ใช้ทำ Web Scraping ได้ เช่น JavaScript (Node.js), PHP, Ruby แต่ Python มันได้เปรียบตรงที่มี Library ให้เลือกใช้เยอะ แถม Syntax ก็อ่านง่าย
แต่ถ้าเว็บที่เราต้องการดึงข้อมูลมี API ให้ใช้ (Application Programming Interface) อันนั้นจะง่ายกว่า Scraping เยอะเลย API จะให้ข้อมูลที่เป็น structured data มาเลย ไม่ต้องมานั่ง parse HTML เอง
| Feature | Web Scraping | API |
|---|---|---|
| ความซับซ้อน | สูง ต้อง parse HTML | ต่ำ ได้ structured data เลย |
| ความยืดหยุ่น | สูง ดึงข้อมูลอะไรก็ได้ | ต่ำ ดึงได้เฉพาะข้อมูลที่ API อนุญาต |
| ความเสถียร | ต่ำ ถ้าเว็บเปลี่ยน layout code เราก็ต้องแก้ | สูง API มักจะไม่ค่อยเปลี่ยน |
| ข้อจำกัด | อาจโดนเว็บ block ได้ | มี rate limiting (จำกัดจำนวน request) |
สรุปคือ ถ้ามี API ให้ใช้ เลือก API ก่อนเลย แต่ถ้าไม่มี Web Scraping ก็เป็นทางเลือกที่ดี
เอาล่ะน้องๆ มาถึงส่วนสำคัญแล้ว นี่คือเคล็ดลับที่พี่บอม SiamCafe สั่งสมมาจากการคลุกคลีกับ Web Scraping มานานโข บอกเลยว่าถ้าทำตามนี้ชีวิตง่ายขึ้นเยอะ สมัยผมทำร้านเน็ตนี่ ข้อมูลสำคัญมากนะ ช่วยให้เราตัดสินใจหลายๆ อย่างได้ดีขึ้น
จำไว้ว่า Web Scraping ไม่ใช่แค่การดึงข้อมูล แต่มันคือการดึงข้อมูลอย่างมีมารยาท และมีประสิทธิภาพด้วยนะจ๊ะ
เว็บไซต์ส่วนใหญ่จะตรวจสอบ User-Agent ของเราเพื่อดูว่าเราเป็นใคร ถ้าเราใช้ User-Agent default ของ Python บ่อยๆ เว็บไซต์อาจจะบล็อกเราได้
วิธีแก้คือ กำหนด User-Agent ของเราให้เหมือนกับ Browser ทั่วไปซะ จะได้เนียนๆ หน่อย
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
response = requests.get('https://www.example.com', headers=headers)
print(response.status_code)
robots.txt คือไฟล์ที่บอกว่า Bot หรือ Crawler ตัวไหนสามารถเข้าถึงส่วนไหนของเว็บไซต์ได้บ้าง ก่อน Scraping เว็บไซต์ไหน อย่าลืมเข้าไปอ่าน robots.txt ก่อนนะ
เหมือนสมัยก่อนที่เราต้องดูป้าย "ห้ามเข้า" ก่อนเข้าไปในบ้านคนอื่นนั่นแหละ
การส่ง Request ถี่ๆ รัวๆ ไปที่เว็บไซต์ อาจทำให้ Server ของเขาทำงานหนักเกินไป จนอาจจะโดนบล็อกได้
วิธีแก้คือ หน่วงเวลาในการส่ง Request แต่ละครั้งซะหน่อย จะได้ไม่เป็นการรบกวน Server เขามากเกินไป
import requests
import time
for i in range(5):
response = requests.get('https://www.example.com')
print(f"Request {i+1}: {response.status_code}")
time.sleep(2) # หน่วงเวลา 2 วินาที
ระหว่าง Scraping อาจจะเกิด Error ได้ตลอดเวลา เช่น Network Error, Timeout Error หรือ HTML Structure เปลี่ยนแปลง
ดังนั้นควรใช้ try-except blocks เพื่อจัดการกับ Error เหล่านี้ และทำให้โปรแกรมของเราทำงานต่อไปได้
import requests
from bs4 import BeautifulSoup
try:
response = requests.get('https://www.example.com')
response.raise_for_status() # Check for HTTP errors
soup = BeautifulSoup(response.content, 'html.parser')
# Your scraping code here
except requests.exceptions.RequestException as e:
print(f"Error during request: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
บางเว็บไซต์ใช้เทคนิค Anti-Scraping เช่น Load ข้อมูลด้วย JavaScript, ใช้ CAPTCHA หรือเปลี่ยนแปลง HTML Structure บ่อยๆ ทำให้ Scraping ยากขึ้น
สำหรับ Python ที่พี่ใช้บ่อยๆ ก็มี requests, BeautifulSoup และ Scrapy แต่ละตัวก็มีข้อดีข้อเสียต่างกัน เลือกใช้ตามความเหมาะสมของงานนะ
Web Scraping ไม่ผิดกฎหมายเสมอไป แต่ต้องระวังเรื่องลิขสิทธิ์, Terms of Service ของเว็บไซต์ และข้อมูลส่วนตัวของผู้ใช้งาน ถ้าไม่แน่ใจควรปรึกษาผู้เชี่ยวชาญด้านกฎหมายก่อน
ลองเปลี่ยน User-Agent, ใช้ Proxy หรือ VPN, ลดความถี่ในการส่ง Request หรือติดต่อเจ้าของเว็บไซต์เพื่อขออนุญาต Scraping ข้อมูล
Web Scraping เป็นเครื่องมือที่มีประโยชน์มากในการดึงข้อมูลจากเว็บไซต์ แต่ต้องใช้อย่างระมัดระวังและมีมารยาทเสมอ จำไว้ว่าเราไม่ได้เป็นเจ้าของข้อมูลบนเว็บไซต์เหล่านั้น
ถ้าอยากรู้เรื่อง Forex เพิ่มเติม ลองแวะไปดูที่ iCafeForex ได้นะ
หวังว่าบทความนี้จะเป็นประโยชน์กับน้องๆ นะครับ ถ้ามีคำถามเพิ่มเติม ถามมาได้เลย หรือลองเข้าไปอ่านบทความอื่นๆ ใน SiamCafe Blog ก็ได้นะจ๊ะ