AI Agents · บทเรียน

การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก

ติดตามลิงก์หน้าถัดไปและใช้ Playwright กับหน้าที่แสดงผลด้วย JavaScript

บทเรียน 3 จาก 413 ขั้นตอน

การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

ปัญหาการแบ่งหน้า

เว็บไซต์จริงส่วนใหญ่ไม่ได้แสดงข้อมูลทั้งหมดในหน้าเดียว ผลลัพธ์จะถูกแบ่งออกเป็นหลายหน้าเพื่อลดภาระของระบบ เอเจนต์ต้องตรวจจับและทำตามการแบ่งหน้าเพื่อรวบรวมชุดข้อมูลให้ครบถ้วน

รูปแบบการแบ่งหน้าที่พบได้ทั่วไปมีสองแบบ ได้แก่ ลิงก์ไปหน้าถัดไป และ รูปแบบ URL ตามหมายเลขหน้า

การตรวจจับลิงก์ไปหน้าถัดไป

หลายเว็บไซต์มีปุ่ม 'ถัดไป' หรือลิงก์รูปลูกศร ให้ค้นหาแท็กจุดยึดที่มี rel='next' หรือมีข้อความเช่น 'ถัดไป' จากนั้นดึงค่า href แล้วติดตามลิงก์ในลูปจนกว่าจะไม่มีลิงก์ดังกล่าว

from bs4 import BeautifulSoup
import httpx

def scrape_all_pages(start_url: str) -> list:
    results = []
    url = start_url

    while url:
        response = httpx.get(url, timeout=10.0)
        soup = BeautifulSoup(response.text, 'html.parser')

        # Collect data from this page
        for item in soup.select('.result-item'):
            results.append(item.text.strip())

        # Find the next page link
        next_link = soup.find('a', rel='next') or soup.find('a', string='Next')
        url = next_link.get('href') if next_link else None

    return results

รูปแบบ URL ตามหมายเลขหน้า

เอพีไอและเว็บไซต์จำนวนมากใช้รูปแบบ URL ที่คาดเดาได้ เช่น /results?page=1, /results?page=2 เป็นต้น เอเจนต์สามารถวนซ้ำตามรูปแบบเหล่านี้ได้โดยตรง โดยไม่ต้องแยกวิเคราะห์ DOM เพื่อหาลิงก์ไปหน้าถัดไป

import httpx

def scrape_paginated_api(base_url: str, max_pages: int = 10) -> list:
    all_items = []

    for page in range(1, max_pages + 1):
        response = httpx.get(
            base_url,
            params={'page': page, 'per_page': 50},
            timeout=10.0
        )
        response.raise_for_status()
        data = response.json()

        items = data.get('results', [])
        if not items:
            break  # No more data

        all_items.extend(items)
        print(f'Page {page}: fetched {len(items)} items')

    return all_items

การแบ่งหน้าโดยใช้เคอร์เซอร์

เอพีไอสมัยใหม่ เช่น GitHub, สแล็ก และทวิตเตอร์ ใช้การแบ่งหน้าโดยอาศัยเคอร์เซอร์ การตอบกลับแต่ละครั้งจะมีโทเค็นเคอร์เซอร์สำหรับหน้าถัดไป ให้ส่งเคอร์เซอร์นั้นไปกับคำขอถัดไปจนกว่าจะไม่มีค่าหรือมีค่าเป็น null

import httpx

def fetch_with_cursor(url: str, headers: dict) -> list:
    all_data = []
    cursor = None

    while True:
        params = {'cursor': cursor} if cursor else {}
        response = httpx.get(url, headers=headers, params=params, timeout=10.0)
        response.raise_for_status()
        data = response.json()

        all_data.extend(data.get('items', []))

        cursor = data.get('next_cursor')  # None when done
        if not cursor:
            break

    return all_data

เนื้อหาแบบคงที่เทียบกับแบบไดนามิก

บางหน้าจะโหลดเนื้อหาด้วย JavaScript หลังจากส่ง HTML เริ่มต้นแล้ว ไคลเอ็นต์เอชทีทีพีทั่วไปจะได้รับเพียงโครงเปล่า ๆ เท่านั้น ส่วนข้อมูลจริงจะถูกแทรกโดย JS ในเบราว์เซอร์

สำหรับหน้าเหล่านี้ เครื่องมืออย่างเพลย์ไรต์จะเรียกใช้กลไกเบราว์เซอร์จริงและรอให้ JavaScript ทำงานเสร็จก่อนดึงเนื้อหา

การติดตั้งและนำเข้าเพลย์ไรต์

ติดตั้งเพลย์ไรต์ด้วย pip install playwright จากนั้นเรียกใช้ playwright install chromium เพื่อดาวน์โหลดเบราว์เซอร์ ใช้ async_playwright() สำหรับกระบวนการทำงานของเอเจนต์แบบอะซิงโครนัส

# Installation (run in terminal):
# pip install playwright
# playwright install chromium

from playwright.async_api import async_playwright
import asyncio

async def fetch_dynamic(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)
        html = await page.content()  # Full rendered HTML
        await browser.close()
    return html

# html = asyncio.run(fetch_dynamic('https://example.com'))

การรอให้เนื้อหาแบบไดนามิกโหลด

หน้า JavaScript มักโหลดข้อมูลแบบอะซิงโครนัส ให้เพลย์ไรต์รอจนกว่าองค์ประกอบที่ระบุจะปรากฏก่อนดึงเนื้อหา เพื่อให้แน่ใจว่าข้อมูลที่ต้องการมีอยู่ใน DOM แล้ว

from playwright.async_api import async_playwright

async def scrape_dynamic_table(url: str) -> list:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)

        # Wait for the table to appear in the DOM
        await page.wait_for_selector('table.results', timeout=10000)

        html = await page.content()
        await browser.close()

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'html.parser')
    return [td.text for td in soup.select('table.results td')]

การคลิกและโต้ตอบกับหน้าเว็บ

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

from playwright.async_api import async_playwright

async def click_load_more(url: str) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)

        # Click the 'Load More' button
        load_more = page.locator('button:text("Load More")')
        if await load_more.count() > 0:
            await load_more.click()
            await page.wait_for_timeout(2000)  # wait 2s for content

        html = await page.content()
        await browser.close()
    return html

การจัดการหน้าเว็บที่เลื่อนโหลดข้อมูลอย่างไม่สิ้นสุด

บางเว็บไซต์จะโหลดเนื้อหาเพิ่มเติมเมื่อคุณเลื่อนลง เพลย์ไรต์สามารถจำลองการเลื่อนเพื่อเรียกการโหลดเหล่านี้ได้ ให้เลื่อนซ้ำ ๆ และตรวจสอบทุกครั้งว่ามีเนื้อหาใหม่ปรากฏขึ้นหรือไม่

from playwright.async_api import async_playwright

async def scrape_infinite_scroll(url: str, scroll_count: int = 5) -> str:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)

        for _ in range(scroll_count):
            await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
            await page.wait_for_timeout(1500)  # wait for new content

        html = await page.content()
        await browser.close()
    return html

การใช้เพลย์ไรต์ร่วมกับ BeautifulSoup

หลังจากเพลย์ไรต์แสดงผลหน้าเว็บและส่งคืน HTML ทั้งหมดแล้ว ให้นำ HTML นั้นป้อนเข้าสู่ BeautifulSoup เพื่อดึงข้อมูลได้อย่างสะดวก วิธีนี้รวมจุดแข็งของไลบรารีทั้งสองเข้าด้วยกัน

from playwright.async_api import async_playwright
from bs4 import BeautifulSoup

async def extract_js_rendered_data(url: str) -> list:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        page = await browser.new_page()
        await page.goto(url)
        await page.wait_for_selector('.product-card')
        html = await page.content()
        await browser.close()

    soup = BeautifulSoup(html, 'html.parser')
    products = []
    for card in soup.select('.product-card'):
        products.append({
            'name': card.select_one('.name').text.strip(),
            'price': card.select_one('.price').text.strip()
        })
    return products

การเลือกเครื่องมือที่เหมาะสม

ไม่ใช่ทุกหน้าที่จำเป็นต้องใช้เพลย์ไรต์ ให้ใช้วิธีที่ง่ายที่สุดและใช้งานได้:

  • HTML แบบคงที่: เอชทีทีพีเอ็กซ์ + BeautifulSoup (รวดเร็วและไม่ต้องมีภาระจากเบราว์เซอร์)
  • เอพีไอเจสันที่มีการแบ่งหน้า: เอชทีทีพีเอ็กซ์พร้อมพารามิเตอร์หน้า/เคอร์เซอร์
  • เนื้อหาที่แสดงผลด้วย JS: การทำงานแบบอะซิงก์ของเพลย์ไรต์ (ช้ากว่าแต่ทรงพลังกว่า)

ให้เริ่มด้วยวิธีแบบคงที่เสมอ และเลือกใช้เพลย์ไรต์เมื่อจำเป็นเท่านั้น

ตรวจสอบความเข้าใจ: การแบ่งหน้าและเนื้อหาแบบไดนามิก

ทดสอบความเข้าใจเกี่ยวกับการแบ่งหน้าและการจัดการเนื้อหาแบบไดนามิก

ทบทวน: การแบ่งหน้าและเนื้อหาแบบไดนามิก

ขณะนี้เอเจนต์ของคุณสามารถจัดการเนื้อหาเว็บได้ครบทุกลักษณะแล้ว:

  • ติดตามลิงก์ไปหน้าถัดไปหรือวนซ้ำตามพารามิเตอร์หน้าของ URL
  • ใช้โทเค็นเคอร์เซอร์สำหรับการแบ่งหน้าของเอพีไอสมัยใหม่
  • ใช้ async_playwright() สำหรับหน้าที่แสดงผลด้วย JavaScript
  • รอองค์ประกอบด้วย page.wait_for_selector()
  • ใช้เพลย์ไรต์ร่วมกับ BeautifulSoup เพื่อดึงข้อมูลได้อย่างสะดวก

ให้เริ่มด้วยวิธีที่ง่ายที่สุดเสมอ และเปลี่ยนไปใช้เพลย์ไรต์เมื่อวิธีแบบคงที่ไม่เพียงพอเท่านั้น

เริ่มต้นได้ฟรี

เรียนรู้ AI Agents ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
60
บทเรียน
239

คำถามที่พบบ่อย

บทเรียน “การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก”

ติดตามลิงก์หน้าถัดไปและใช้ Playwright กับหน้าที่แสดงผลด้วย JavaScript คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม

ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ไคลเอ็นต์ HTTP สำหรับตัวแทน: httpx และ requests
  2. การแยกวิเคราะห์ HTML ด้วย BeautifulSoup
  3. การจัดการการแบ่งหน้าและเนื้อหาแบบไดนามิก
  4. แนวปฏิบัติการดึงข้อมูลอย่างรับผิดชอบ
← กลับไปที่ AI Agents