ส่องเว็บด้วย Python: มาลอง Scrape ข้อมูลกัน! (พร้อมวิธีแก้เซ็ง)
การทำ Web Scraping เนี่ย เป็นอะไรที่เจ๋งมากนะ ถ้าเว็บปลายทางเขาไม่มี API ให้เราเรียกใช้ เราก็ต้องใช้วิธีนี้แหละ แต่บอกเลยว่ามันก็มีมุมที่โคตรปวดหัวเหมือนกันแหละ โดยเฉพาะตอนที่เว็บเขาไม่อยากให้เราไปยุ่ง!
มาเริ่มกันแบบง่ายๆ ก่อนนะ เราจะใช้ไลบรารี requests สำหรับดึงหน้าเว็บ กับ BeautifulSoup (bs4) สำหรับ parse HTML
เตรียมตัวก่อนลุย
ก่อนอื่นก็ลงไลบรารีที่เราต้องใช้ก่อนเลย:
pip install requests beautifulsoup4
เริ่มต้น Scrape ง่ายๆ
สมมติว่าเราจะลองดึงข้อมูลจากเว็บทดสอบ scraping ทั่วไปอย่าง quotes.toscrape.com นะ:
import requests
from bs4 import BeautifulSoup
url = 'http://quotes.toscrape.com/'
try:
response = requests.get(url)
response.raise_for_status() # อันนี้สำคัญ! ถ้าสถานะไม่ใช่ 200 มันจะพ่น error ให้เลย
soup = BeautifulSoup(response.text, 'html.parser')
# ลองหาหัวข้อใหญ่ๆ บนหน้าเว็บก่อน
title = soup.find('h1')
if title:
print(f"เจอหัวข้อแล้ว: {title.text.strip()}")
else:
print("หา h1 ไม่เจอว่ะ...")
# ทีนี้ลองดึงพวกคำคมมาดูดีกว่า
quotes = soup.find_all('div', class_='quote')
print("\n--- คำคมที่เจอ ---")
for quote in quotes:
text = quote.find('span', class_='text')
author = quote.find('small', class_='author')
if text and author:
print(f"\" {text.text.strip()} \" - {author.text.strip()}")
else:
print("มีคำคมบางอันที่ดึงข้อมูลไม่ครบนะ")
except requests.exceptions.HTTPError as err:
print(f"เออเร่อ HTTP ว่ะ: {err}")
except requests.exceptions.RequestException as err:
print(f"เกิดปัญหาตอนเชื่อมต่อ: {err}")
โค้ดข้างบนเนี่ย ถ้าเว็บที่เราจะไปดึงไม่ได้มีอะไรซับซ้อน มันก็ทำงานได้ดีเลยแหละ
ปัญหาโลกแตก: โดนบล็อกเพราะ User-Agent
มีบ่อยมากนะที่รันโค้ดข้างบนแล้วมันได้ 403 Forbidden หรือ 401 Unauthorized กลับมา แทนที่จะเป็น 200 OK
แรกๆ ก็คิดว่าโดนบล็อกไอพีรึเปล่า? แต่ส่วนใหญ่ไม่ใช่หรอก! เว็บส่วนมากเขาจะเช็ค User-Agent ของเรา ว่าเรามาจาก Browser จริงๆ หรือเป็น bot
ถ้าเราไม่ส่ง User-Agent ไปเลย หรือส่งแบบที่มันดูแปลกๆ เช่น python-requests/X.Y.Z เว็บเขาก็จะรู้ทันทีว่านี่มันบอตนี่หว่า แล้วก็บล็อกเราซะเลย!
วิธีแก้ก็ง่ายมาก แค่เพิ่ม headers เข้าไปใน requests.get() แล้วใส่ User-Agent ที่ดูเป็น Browser ทั่วไปซะหน่อย:
import requests
from bs4 import BeautifulSoup
url = 'http://quotes.toscrape.com/' # หรือเว็บไหนก็ได้ที่เคยเจอ 403
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36'
# หรือจะลองหา User-Agent ตัวอื่นที่อัปเดตกว่านี้ก็ได้นะ ลองค้นหา 'my user agent' ใน Google
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # ย้ำอีกทีว่าอันนี้ช่วยเยอะ
print(f"สถานะ: {response.status_code} - เยี่ยมเลย!")
# ที่เหลือก็ parse HTML เหมือนเดิม
soup = BeautifulSoup(response.text, 'html.parser')
# ...ทำอะไรต่อก็ทำไป
except requests.exceptions.HTTPError as err:
print(f"เออเร่อ HTTP ว่ะ: {err}. ลองเช็ค User-Agent ดีๆ นะ!")
except requests.exceptions.RequestException as err:
print(f"เกิดปัญหาตอนเชื่อมต่อ (กับ User-Agent แล้วก็ยัง): {err}")
ประสบการณ์ส่วนตัว: เคยเจอเว็บข่าวไทยบางเว็บนะ ไม่ใส่ User-Agent ก็ 403 ตลอด ลองใส่ไปปุ๊บ ใช้ได้เลย! โคตรเซ็งอ่ะตอนแรกที่เจอ ไม่นึกว่าแค่นี้ก็โดนบล็อกแล้ว
อีกเรื่องที่โคตรเซ็ง: HTML เปลี่ยนไปมา
อันนี้ก็ปวดหัวไม่แพ้กันเลย คือเราเขียน selector ใน BeautifulSoup อย่างดีเลยนะ เช่น soup.find('div', class_='product-name') เพื่อดึงชื่อสินค้า
แต่พอวันนึง เจ้าของเว็บเขาเปลี่ยน HTML ไง! เปลี่ยน div เป็น h2 บ้าง หรือเปลี่ยนชื่อ class จาก product-name เป็น item-title บ้าง โค้ดเราที่เขียนไว้ก็ พังดิครับรออะไร!
คือมันไม่มีวิธีแก้ตายตัวนะกับเรื่องนี้ สิ่งเดียวที่ทำได้คือทำใจ แล้วก็เข้าไปดูโครงสร้าง HTML ของเว็บนั้นใหม่ แล้วก็แก้โค้ดเราให้มันตรงกับโครงสร้างใหม่ แค่นั้นแหละ! (แต่ถ้าเว็บใหญ่ๆ เปลี่ยนบ่อยนี่ปวดหัวจริง)
ทริคเล็กๆ: * พยายามใช้ Selector ที่มันกว้างๆ หน่อย แต่อย่ากว้างไปจนได้ข้อมูลมั่ว * ถ้าเป็นไปได้ ลองหา Tag หรือ Attribute ที่มันไม่น่าจะเปลี่ยนบ่อย เช่น id (ถ้ามี) * ใช้ try-except ดีๆ เวลาดึงข้อมูลแต่ละส่วน เพื่อไม่ให้โปรแกรมพังทั้งแถบ ถ้าเจอข้อมูลบางส่วนหาไม่เจอ
สรุป
Web Scraping มันเป็นเครื่องมือที่มีประโยชน์มาก แต่ก็ไม่ใช่เรื่องง่ายที่จะทำให้ออกมาสมบูรณ์แบบได้ตลอดเวลา มันเหมือนเกมแมวจับหนูที่ต้องคอยปรับตัวตามเว็บที่เราจะไปดึงข้อมูลเลยแหละ แต่ถ้าเข้าใจปัญหาหลักๆ อย่าง User-Agent หรือการเปลี่ยนแปลง HTML Structure มันก็จะช่วยให้เราปวดหัวน้อยลงไปเยอะเลยนะ!
ลองเอาไปปรับใช้ดูนะ!