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

PPV คืออะไร? เจาะลึกปรากฏการณ์ Pay-Per-View กับอีเวนต์สุดพิเศษแห่งยุค

PPV คืออะไร? เจาะลึกปรากฏการณ์ Pay-Per-View กับอีเวนต์สุดพิเศษแห่งยุค

ทำความเข้าใจ Pay-Per-View (PPV) กับเทรนด์การรับชมอีเวนต์สุดพิเศษ ทั้งศึก ONE Championship, คอนเสิร์ต Project Sekai และความบันเทิงหลากหลายผ่าน ABEMA PPV.

By ทีมงาน devdog
Xiaomi 17T เผยโฉมภาพจริงจาก Anatel ลุ้นเปิดตัว พ.ค. นี้ พร้อมดีไซน์ใหม่และชาร์จไว 67W!

Xiaomi 17T เผยโฉมภาพจริงจาก Anatel ลุ้นเปิดตัว พ.ค. นี้ พร้อมดีไซน์ใหม่และชาร์จไว 67W!

พบภาพจริง Xiaomi 17T จาก Anatel เผยดีไซน์ใหม่ กล้อง Leica ชิป Dimensity 8500 แบต 6500mAh และชาร์จไว 67W ลุ้นเปิดตัวเดือนพฤษภาคมนี้!

By ทีมงาน devdog
เอลนีโญกลับมาแล้ว! WMO เตือนรุนแรงทั่วโลก ไทยต้องเตรียมรับมือวิกฤตความร้อน

เอลนีโญกลับมาแล้ว! WMO เตือนรุนแรงทั่วโลก ไทยต้องเตรียมรับมือวิกฤตความร้อน

องค์การอุตุนิยมวิทยาโลกเตือนปรากฏการณ์เอลนีโญรุนแรงในปี 2026 อาจทำโลกเผชิญปีที่ร้อนที่สุด. เรียนรู้ผลกระทบและการเตรียมพร้อมของไทย.

By ทีมงาน devdog