Panduan untuk melakukan scraping situs web dinamis dengan Python

Komentar: 0

Kemampuan penting untuk mendapatkan data dari halaman web adalah web scraping. Pinterest dan Instagram, yang memuat konten secara dinamis melalui interaksi pengguna dengan mereka adalah contoh dari jenis situs web ini. Metode scraping biasa tidak cukup ketika menangani materi berbasis JavaScript. Pada artikel ini, kami akan menguraikan Playwright sebagai alat otomatisasi sementara lxml akan digunakan untuk ekstraksi data dari situs dinamis seperti itu yang membutuhkan Javascript untuk bekerja dengan baik. Pada catatan ini, kita akan membahas tentang penggunaan proxy di Playwright untuk menghindari deteksi sebagai bot. Dalam tutorial ini, kita akan mengikis profil Instagram untuk mengambil semua URL postingan dengan mensimulasikan perilaku pengguna, seperti menggulir dan menunggu postingan dimuat.

Alat yang akan kita gunakan dalam panduan ini:

  • Playwright (untuk otomatisasi peramban);
  • lxml (untuk ekstraksi data menggunakan XPath);
  • Python (sebagai bahasa pemrograman kita).

Panduan langkah demi langkah untuk mengikis postingan Instagram

Kami akan mengilustrasikan prosesnya dengan menggunakan contoh mengikis profil Instagram untuk mengekstrak URL kiriman, mensimulasikan tindakan pengguna seperti menggulir halaman dan menunggu data baru dimuat. Situs web dinamis secara asinkron memuat konten mereka melalui permintaan AJAX, yang berarti tidak semua konten halaman dapat langsung diakses.

Langkah 1. Instal pustaka yang diperlukan

Sebelum kita mulai, instal paket-paket yang diperlukan:


pip install playwright
pip install lxml

Anda juga harus menginstal browser Playwright:


playwright install

Langkah 2. Penyiapan penulis naskah untuk penggalian situs web dinamis

Kita akan menggunakan Playwright untuk mengotomatiskan browser, memuat konten dinamis Instagram, dan menggulir halaman untuk memuat lebih banyak postingan. Mari buat skrip otomatisasi dasar:

Skrip otomatisasi (Peramban Tanpa Kepala):


import asyncio
from playwright.async_api import async_playwright

async def scrape_instagram():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)  # Mode tanpa kepala Tidak ada umpan balik visual
        page = await browser.new_page()
        
        # Kunjungi URL profil
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")

        # Klik tombol untuk memuat lebih banyak tulisan
        await page.get_by_role("button", name="Show more posts from").click()
        
        # Gulir halaman untuk memuat konten dinamis
        scroll_count = 5  # Sesuaikan ini berdasarkan berapa kali Anda ingin menggulir
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 700);')
            await page.wait_for_timeout(3000)  # Tunggu hingga postingan dimuat
            await page.wait_for_load_state("networkidle")
        
        # Dapatkan konten halaman
        content = await page.content()
        await browser.close()
        
        return content

# Menjalankan fungsi asinkron
asyncio.run(scrape_instagram())

Langkah 3. Mengurai halaman dengan lxml dan XPath

Setelah konten dimuat, kita dapat menggunakan lxml untuk mem-parsing HTML dan mengekstrak data menggunakan XPath. Dalam kasus ini, kita mengekstrak URL semua postingan dari profil.

Mengurai konten halaman dan mengekstrak URL postingan:


from lxml import html
import json

def extract_post_urls(page_content):
    # Mengurai konten HTML menggunakan lxml
    tree = html.fromstring(page_content)
    
    # XPath untuk mengekstraksi URL posting
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Ekstrak URL
    post_urls = tree.xpath(post_urls_xpath)
    
    # Mengonversi URL relatif menjadi absolut
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

Contoh fungsi untuk menyimpan data yang diekstrak dalam format JSON:


def save_data(profile_url, post_urls):
    data = {profile_url: post_urls}
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)

# Mengikis dan mengekstrak URL
page_content = asyncio.run(scrape_instagram())
post_urls = extract_post_urls(page_content)

# Simpan URL yang diekstrak dalam file JSON
save_data("https://www.instagram.com/profile name/", post_urls)

Langkah 4. Menangani gulir tak terbatas dengan Playwright

Untuk mengikis situs web dinamis, Anda sering kali perlu mensimulasikan pengguliran tanpa batas. Dalam skrip kami, kami menggulir halaman menggunakan JavaScript:


(window.scrollBy(0, 700))

Dan tunggu hingga konten baru dimuat menggunakan perintah ini:


 wait_for_load_state("networkidle")

Langkah 5. Menggunakan proksi dengan Playwright

Instagram memiliki batas kecepatan yang ketat dan tindakan anti-bot. Untuk menghindari pemblokiran, Anda dapat menggunakan proxy untuk memutar alamat IP dan mendistribusikan permintaan. Playwright memudahkan untuk mengintegrasikan proxy ke dalam otomatisasi scraping Anda.

Menerapkan proksi di Playwright:


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Lanjutkan mengikis seperti sebelumnya...

Playwright juga mendukung proxy untuk diteruskan sebagai kata sandi nama pengguna dan contoh server diberikan di bawah ini.


async def scrape_with_proxy():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False, 
            proxy={"server": "http://your-proxy-server:port", "username": "username", "password": "password"}
        )
        page = await browser.new_page()
        await page.goto("https://www.instagram.com/profile name/", wait_until="networkidle")
        # Lanjutkan mengikis seperti sebelumnya...

Proksi membantu menghindari larangan IP, tantangan CAPTCHA, dan memastikan scraping yang lancar pada situs web yang penuh data atau dibatasi seperti Instagram.

Kode lengkap


import asyncio
from playwright.async_api import async_playwright
from lxml import html
import json

# Berfungsi untuk mengotomatiskan peramban dan mengikis konten dinamis dengan proxy
async def scrape_instagram(profile_url, proxy=None):
    async with async_playwright() as p:
        # Siapkan browser dengan proxy jika tersedia
        browser_options = {
            'headless': True,  # Gunakan browser berkepala untuk melihat aksi (dapat diatur ke True untuk mode tanpa kepala)
        }
        if proxy:
            browser_options['proxy'] = proxy

        # Meluncurkan browser
        browser = await p.chromium.launch(**browser_options)
        page = await browser.new_page()

        # Kunjungi halaman profil Instagram
        await page.goto(profile_url, wait_until="networkidle")
        
        # Coba klik tombol "Tampilkan lebih banyak postingan" (opsional, mungkin gagal jika tombol tidak ditemukan)
        try:
           await page.click('button:has-text("Show more posts from")')
        except Exception as e:
           print(f"No 'Show more posts' button found: {e}")


        # Gulir halaman untuk memuat lebih banyak postingan
        scroll_count = 5  # Jumlah gulir untuk memuat tulisan
        for _ in range(scroll_count):
            await page.evaluate('window.scrollBy(0, 500);')
            await page.wait_for_timeout(3000)  # Tunggu hingga postingan baru dimuat
            await page.wait_for_load_state("networkidle")

        # Dapatkan konten halaman lengkap setelah menggulir
        content = await page.content()
        await browser.close()  # Tutup browser setelah selesai
        
        return content

# Berfungsi untuk mengurai konten halaman yang dikikis dan mengekstrak URL posting
def extract_post_urls(page_content):
    # Mengurai konten HTML menggunakan lxml
    tree = html.fromstring(page_content)
    
    # XPath untuk mengekstraksi URL posting
    post_urls_xpath = '//a[contains(@href, "/p/")]/@href'
    
    # Mengekstrak URL postingan menggunakan XPath
    post_urls = tree.xpath(post_urls_xpath)
    
    # Mengonversi URL relatif menjadi URL absolut
    base_url = "https://www.instagram.com"
    post_urls = [f"{base_url}{url}" for url in post_urls]
    
    return post_urls

# Berfungsi untuk menyimpan URL postingan yang diekstrak ke dalam file JSON
def save_data(profile_url, post_urls):
    # Menyusun data dalam format JSON
    data = {profile_url: post_urls}
    
    # Menyimpan data ke file
    with open('instagram_posts.json', 'w') as json_file:
        json.dump(data, json_file, indent=4)
    print(f"Data saved to instagram_posts.json")

# Fungsi utama untuk menjalankan pengikis dan menyimpan data
async def main():
    # Tentukan URL profil Instagram
    profile_url = "https://www.instagram.com/profile name/"
    
    # Secara opsional, siapkan proxy
    proxy = {"server": "server", "username": "username", "password": "password"}  # Gunakan Tidak Ada jika tidak ada proxy yang diperlukan
    
    # Kikis halaman Instagram dengan proxy
    page_content = await scrape_instagram(profile_url, proxy=proxy)
    
    # Ekstrak URL postingan dari konten halaman yang dikikis
    post_urls = extract_post_urls(page_content)
    
    # Simpan URL postingan yang diekstrak ke dalam file JSON
    save_data(profile_url, post_urls)

if __name__ == '__main__':
   asyncio.run(main())

Alat otomatisasi alternatif untuk penggalian web

Meskipun Playwright adalah pilihan yang sangat baik untuk scraping situs web dinamis, alat lain mungkin cocok untuk skenario yang berbeda:

  1. Selenium: Selenium adalah salah satu kerangka kerja otomatisasi peramban tertua dan bekerja mirip dengan Playwright. Framework ini sangat serbaguna tetapi tidak memiliki beberapa kemampuan modern yang ditawarkan Playwright, seperti menangani banyak browser dengan satu API;
  2. Dalang: Puppeteer adalah alat populer lainnya untuk otomatisasi peramban, terutama untuk mengikis situs web yang banyak menggunakan JavaScript. Seperti Playwright, alat ini mengontrol peramban tanpa kepala dan memungkinkan interaksi dengan konten dinamis;
  3. Requests + BeautifulSoup: untuk situs web yang lebih sederhana yang tidak membutuhkan JavaScript untuk memuat konten, pustaka Requests yang digabungkan dengan BeautifulSoup adalah alternatif yang ringan. Namun, ini tidak menangani konten dinamis dengan baik.

Setiap alat menawarkan kekuatan yang unik dan dapat dipilih berdasarkan kebutuhan dan kondisi spesifik proyek.

Untuk keberhasilan scraping situs web dinamis yang secara aktif menggunakan permintaan JavaScript dan AJAX, diperlukan alat bantu yang kuat yang mampu menangani pengguliran tak terbatas dan elemen interaktif yang kompleks secara efisien. Salah satu solusi tersebut adalah Playwright-sebuah alat dari Microsoft yang menyediakan otomatisasi peramban secara penuh, menjadikannya pilihan ideal untuk platform seperti Instagram. Dikombinasikan dengan pustaka lxml untuk penguraian HTML, Playwright sangat menyederhanakan ekstraksi data, memungkinkan otomatisasi interaksi dengan elemen halaman dan proses penguraian tanpa intervensi manual. Selain itu, penggunaan server proxy membantu menghindari perlindungan anti-bot dan mencegah pemblokiran IP, memastikan operasi scraping yang stabil dan tidak terganggu.

Komentar:

0 komentar