Scrape tanpa terblokir: panduan praktis dengan kode
Terblokir saat scraping biasanya berarti salah satu dari tiga hal: Anda mengirim terlalu banyak request terlalu cepat, klien Anda sama sekali tidak terlihat seperti browser atau bot yang dikenal, atau alamat IP Anda ada dalam daftar yang tidak dipercaya situs. Ketiganya bisa dikurangi dengan beberapa kebiasaan: menyadari pemblokiran sejak dini, memperlambat ketika situs memberi tekanan balik, menjaga identitas yang konsisten dan jujur, dan menggunakan proxy hanya jika memang sesuai. Panduan ini membahas masing-masing dengan kode yang berfungsi. Gunakan untuk situs yang boleh Anda scrape.
Kenali pemblokiran
Pemblokiran tidak selalu terlihat seperti halaman error. Perhatikan hal-hal berikut:
- 403 Forbidden, yang sering berarti situs telah menolak klien Anda. Berhenti dan periksa apakah Anda memang diizinkan berada di sana sebelum mencoba lagi.
- 429 Too Many Requests, yang berarti Anda mengirim terlalu banyak. Sering kali disertai header
Retry-After. - 503 Service Unavailable, yang bisa berarti situs kelebihan beban. Mundurlah.
- Respons 200 dengan hampir tanpa konten, pengalihan ke halaman login atau tantangan, atau halaman yang tidak memuat data yang Anda harapkan.
Catat status code dan contoh singkat isi respons untuk setiap kegagalan. Pemblokiran yang tidak terlihat di log Anda adalah pemblokiran yang tidak bisa Anda perbaiki.
Mundur dengan retry
Ketika situs berkata "perlambat", kode Anda harus melambat lebih dari sekadar sedikit. Exponential backoff, dengan batas jumlah percobaan, adalah pendekatan standar. Ini juga menghormati Retry-After ketika situs mengirimkannya:
import time
import requests
session = requests.Session()
session.headers.update({
"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)",
"Accept-Language": "en-US,en;q=0.9",
})
def polite_get(url: str, max_attempts: int = 4) -> requests.Response:
delay = 2.0
resp = None
for _ in range(max_attempts):
resp = session.get(url, timeout=30)
if resp.status_code not in (429, 503):
return resp
retry_after = resp.headers.get("Retry-After", "")
wait = float(retry_after) if retry_after.isdigit() else delay
time.sleep(wait)
delay *= 2
return resp # masih terblokir: kembalikan respons terakhir untuk ditangani pemanggil
resp = polite_get("https://example.com/products?page=1")
print(resp.status_code, len(resp.text))
Perhatikan apa yang tidak dilakukan fungsi ini. Fungsi ini tidak mencoba ulang 403, dan tidak berputar melalui identitas untuk melewati satu pemblokiran. 403 adalah keputusan untuk berhenti, bukan teka-teki yang harus dipecahkan.
Diagnosis pemblokiran langkah demi langkah
Ketika sebuah run mulai gagal, lakukan pemeriksaan berikut sebelum mengubah hal lain:
- Lihat URL pertama yang gagal dan status code-nya. Pemblokiran biasanya dimulai di titik tertentu, bukan secara acak.
- Bandingkan laju request dalam beberapa menit sebelum kegagalan pertama. Lonjakan adalah penyebab paling umum.
- Periksa apakah kegagalan terkait dengan satu path, satu bagian, atau satu waktu dalam sehari.
- Ambil URL yang sama sekali secara manual di browser biasa. Jika browser memuatnya, perbedaannya ada pada pola request Anda. Jika browser juga diblokir, situs untuk sementara berhenti menyajikan halaman tersebut kepada Anda.
- Baru kemudian ubah kode. Perlambat dulu, tambahkan backoff kedua, dan tinjau identitas Anda paling akhir.
Mengubah beberapa hal sekaligus membuat Anda tidak mungkin tahu mana yang membantu.
Jaga identitas yang konsisten dan jujur
Scraper diblokir ketika identitasnya berubah di antara request, atau ketika identitasnya tidak cocok dengan lalu lintas lainnya. Satu sesi dengan satu User-Agent yang jelas adalah identitas stabil yang paling sederhana. Beri nama bot Anda, tambahkan tautan kontak, dan kirim hanya header yang biasanya dikirim klien normal. Mengganti User-Agent agar terlihat seperti banyak pengunjung berbeda adalah bentuk penghindaran, dan itu cenderung membuat pemblokiran lebih mungkin, bukan kurang.
Jika situs menyajikan konten yang berbeda untuk browser dibanding klien HTTP biasa, gunakan browser sungguhan untuk halaman tersebut dan pertahankan batas laju yang sama. Itu adalah rute yang sah, dan itu menjaga pola request tetap masuk akal.
Gunakan proxy dengan hati-hati
Proxy mengubah alamat tempat request berasal. Ini adalah alat untuk kebutuhan yang sah, seperti menguji dari wilayah tertentu di situs yang boleh Anda uji, atau menyebarkan beban di infrastruktur Anda sendiri. Ini bukan cara untuk lolos dari batas yang ditetapkan situs kepada Anda. Format proxy adalah format yang digunakan oleh jenis tugas proxy:
proxies = {
"http": "http://user:pass@proxy.example.net:8000",
"https": "http://user:pass@proxy.example.net:8000",
}
resp = session.get("https://example.com/products", proxies=proxies, timeout=30)
Memilih jenis proxy adalah pertanyaan terpisah, yang dibahas di proxy residensial vs datacenter dan proxy berputar untuk scraping.
Ketika pemblokiran berubah menjadi captcha
Beberapa situs menjawab masalah laju dengan captcha, bukan pemblokiran keras. Urutan yang masuk akal adalah: berhenti, perlambat, periksa aturannya lagi, dan hanya kemudian pertimbangkan untuk memecahkan. Untuk widget PopularCaptcha, API Scarnox yang aktif mengembalikan token yang Anda kirimkan di field h-captcha-response. Untuk jenis captcha lain, periksa daftar yang aktif, karena dukungan untuk reCAPTCHA, Cloudflare Turnstile, GeeTest, AWS WAF, dan Arkose segera hadir. Panduan lengkapnya ada di scraping captcha web.
Jika Anda mulai melihat pemblokiran di suatu situs, penyebabnya hampir selalu pola request. Menghindari captcha saat scraping membahas kebiasaan yang mencegahnya.
Scraping secara bertanggung jawab
- Periksa
robots.txtdan ketentuan layanan sebelum Anda mulai, dan ikuti path serta jeda yang mereka minta. - Berhenti ketika Anda menerima 403 atau pesan "jangan scrape" yang jelas. Jangan terus mencoba.
- Jaga laju tetap cukup rendah sehingga pengunjung normal tidak akan menyadari lalu lintas Anda.
- Jangan mengumpulkan data pribadi yang tidak punya alasan untuk Anda simpan, dan tangani data yang Anda kumpulkan sesuai aturan privasi yang berlaku bagi Anda.
- Jika Anda membutuhkan volume yang jauh lebih besar daripada yang nyaman dilayani situs, mintalah feed atau API kepada pemilik situs.