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:
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.
Sebelum kita mulai, instal paket-paket yang diperlukan:
pip install playwright
pip install lxml
Anda juga harus menginstal browser Playwright:
playwright install
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())
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)
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")
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.
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())
Meskipun Playwright adalah pilihan yang sangat baik untuk scraping situs web dinamis, alat lain mungkin cocok untuk skenario yang berbeda:
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