Playwright: สกิมเว็บแบบไม่ปวดหัวเรื่องไดรเวอร์!

สวัสดีคร้าบ! วันนี้จะมาแนะนำเครื่องมือสำหรับทำเว็บสแครปปิ้ง (Web Scraping) ที่ส่วนตัวผมรู้สึกว่ามันสะดวกกว่า Selenium เยอะเลย โดยเฉพาะเรื่องการจัดการ browser driver เนี่ยะ คือมันจบในตัวเลย ไม่ต้องมานั่งหาเวอร์ชั่นให้ตรงกัน ไม่ต้องลง WebDriver Manager ให้วุ่นวาย

เครื่องมือนั้นก็คือ Playwright นั่นเองครับ!

เอาจริง ๆ Playwright มันถูกสร้างมาเพื่อทำ End-to-End Testing แหละ แต่มันทำงานกับเบราว์เซอร์จริง ๆ ได้ดีมาก ทำให้เอามาประยุกต์ใช้กับงานสแครปปิ้งได้โคตรจะเทพ เพราะมันรองรับ Chrome, Firefox, Safari ได้หมดเลยในโค้ดชุดเดียว

เริ่มต้นใช้งาน

ก่อนอื่นก็ติดตั้งก่อนเลยครับ:

pip install playwright
playwright install

ขั้นตอน playwright install นี่สำคัญมากนะ! ย้ำว่าสำคัญมาก! เพราะถ้าไม่รันตัวนี้ คุณจะเจอ error แบบว่า playwright.sync_api._generated.PlaywrightException: BrowserType.launch: Executable doesn't exist at ... คือมันจะฟ้องว่าหาไฟล์ browser ไม่เจอไง

ตอนแรกผมก็งงๆ ว่าทำไมรันไม่ได้ หาใน Stack Overflow อ๋อออออ... ลืมรันตัวนี้แหละครับ ง่ายๆ เลยแต่พลาดประจำ 😅

มาลองเขียนโค้ดสแครปกัน

ผมจะลองสแครปเว็บ http://quotes.toscrape.com/js/ ซึ่งเป็นเว็บตัวอย่างที่โหลด quote มาแบบ JavaScript นะครับ ถ้าใช้แค่ requests ปกติจะไม่ได้ข้อมูลตรงนี้มา

เปิดไฟล์ .py ขึ้นมาแล้วแปะโค้ดนี้เลย

from playwright.sync_api import sync_playwright

def scrape_quotes():
    print("-- เริ่มสแครปเว็บ quotes.toscrape.com/js/ ---")
    with sync_playwright() as p:
        # เปิด browser (chromium, firefox, webkit)
        # headless=True คือไม่เปิดหน้าต่าง browser ให้เห็น ถ้าอยากดูให้เปลี่ยนเป็น False
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()

        # ไปที่ URL เป้าหมาย
        page.goto("http://quotes.toscrape.com/js/")
        print(f"เปิดหน้าเว็บ: {page.url}")

        # รอให้เนื้อหาโหลดเสร็จ (รอ selector ของ quote class โหลด)
        # อันนี้สำคัญมากสำหรับเว็บที่โหลด content ด้วย JS
        page.wait_for_selector(".quote") 

        quotes_data = []

        # วนลูปหา quote ทั้งหมดในหน้านั้น
        quotes = page.locator(".quote").all()

        for quote in quotes:
            text = quote.locator(".text").inner_text()
            author = quote.locator(".author").inner_text()

            # tags นี่อาจจะยากหน่อย เพราะมันมีหลายอัน เราต้องใช้ .all_inner_texts()
            tags_elements = quote.locator(".tag")
            tags = tags_elements.all_inner_texts() # ได้เป็น list ของ tag strings

            quotes_data.append({
                "text": text.strip(),
                "author": author.strip(),
                "tags": tags
            })

        browser.close()

        print("-- สแครปเสร็จแล้ว! --- ")
        return quotes_data

if __name__ == "__main__":
    data = scrape_quotes()
    for q in data:
        print(f"\nQuote: {q['text']}")
        print(f"Author: {q['author']}")
        print(f"Tags: {', '.join(q['tags'])}")

    # print(f"ข้อมูลที่ได้ทั้งหมด: {data}")

อธิบายโค้ดนิดหน่อย

  • with sync_playwright() as p:: นี่คือจุดเริ่มต้นของการใช้งาน Playwright ครับ. ตัว p นี่แหละที่เราจะใช้ไปเปิด browser.
  • p.chromium.launch(headless=True): เราสั่งให้มันเปิด browser Chromium ขึ้นมาครับ ถ้า headless=True ก็คือมันจะทำงานเบื้องหลัง ไม่เปิดหน้าต่าง browser ให้เราเห็น (ซึ่งเหมาะกับงานสแครปปิ้งมาก).
  • page.goto("URL"): ให้ browser ไปที่ URL ที่เราต้องการ
  • page.wait_for_selector(".quote"): อันนี้คือพระเอกเลย สำหรับเว็บที่โหลดข้อมูลด้วย JavaScript! เราสั่งให้ Playwright รอจนกว่า element ที่มี class .quote จะปรากฏบนหน้าจอ ถ้าไม่ใส่ตรงนี้ บางทีข้อมูลอาจจะยังไม่โหลดมาครบ เราก็จะสแครปพลาดได้นะ
  • page.locator(".quote").all(): อันนี้คล้ายๆ กับ find_elements_by_class_name ใน Selenium แหละ แต่ Playwright ใช้ locator ซึ่งผมว่ามันอ่านง่ายดีกว่า
  • inner_text() / all_inner_texts(): ใช้ดึงข้อความจาก element ครับ

ความรู้สึกส่วนตัวนะ

ตั้งแต่ผมลองใช้ Playwright มาเนี่ยะ ผมรู้สึกว่ามันค่อนข้างเสถียรมาก และที่สำคัญคือมันเร็ว! แถมยังมีฟังก์ชัน wait_for_selector ที่ทำให้จัดการเว็บที่โหลดข้อมูลด้วย AJAX หรือ JavaScript ได้ง่ายขึ้นเยอะ

ส่วนตัวผมชอบกว่า Selenium (สำหรับงานสแครปปิ้งนะ) เพราะเรื่อง driver มันจบจริงๆ ไม่ต้องมานั่งลุ้นว่าวันนี้ไดรเวอร์จะหมดอายุไหม หรือเวอร์ชั่นเบราว์เซอร์อัปเดตแล้วต้องมาหาไดรเวอร์ใหม่มั้ย

ลองเอาไปใช้กันดูนะครับ หวังว่าจะช่วยให้ชีวิตการสแครปของคุณง่ายขึ้น!

Read more

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

ไอลีน กู: ตำนานนักสกีฟรีสไตล์ผู้พลิกโฉมวงการและความหมายของชัยชนะ

เจาะลึกเรื่องราวของ Eileen Gu นักสกีฟรีสไตล์ผู้สร้างประวัติศาสตร์ในโอลิมปิก 2026 สถิติที่ไม่เคยมีมาก่อน ประเด็นถกเถียง และความแข็งแกร่งส่วนตัวที่ทำให้เธอก้าวสู่ระดับโลก

By ทีมงาน devdog
วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

วันพระ: คู่มือฉบับสมบูรณ์สำหรับพุทธศาสนิกชนและผู้สนใจยุคใหม่

เจาะลึกวันพระและความสำคัญของวันมาฆบูชา 2569 ทั้งวันหยุดราชการ ธนาคาร กิจกรรมเวียนเทียนต้นไม้ และผลกระทบต่อบริการขนส่ง เตรียมตัววางแผนทำบุญและพักผ่อน

By ทีมงาน devdog
ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

ถอดรหัสรักแท้: "บังมัดคลองตันต้นข้าว" เรื่องราวที่สะท้อนการให้อภัยและการเริ่มต้นใหม่

เจาะลึกงานวิวาห์ "บังมัดคลองตัน" กับ "ต้นข้าว มิสแกรนด์" พร้อมเหตุผลจากใจเจ้าสาวที่เลือกความรักเหนือกาลเวลาและคำวิจารณ์ สู่การเริ่มต้นชีวิตคู่ที่สะท้อนการให้อภัย

By ทีมงาน devdog
ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

ไฮไลท์บอลไทยลีก 2: มหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรงสู่เส้นทางเพลย์ออฟ

เจาะลึกไฮไลท์บอลไทยลีก 2 ของมหาสารคาม เอสบีที เอฟซี กับฟอร์มร้อนแรง ชัยชนะสำคัญจาก ชิตชนก และบทบาทโค้ชดุสิต สู่เส้นทางเพลย์ออฟที่น่าจับตา!

By ทีมงาน devdog