# 403, 429 dan CAPTCHA: tanggapi, jangan mengelak

> Cara mengatasi 403, 429 dan CAPTCHA saat scraping: arti tiap sinyal, crawler Python yang sopan dengan robots.txt dan Retry-After, dan apa yang tidak boleh dilakukan.

- URL: https://crawlrelay.com/id/guides/403-429-captcha/
- Terakhir diperbarui: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

403, 429, atau CAPTCHA adalah cara situs berkomunikasi dengan crawler Anda. Jawaban yang benar hampir selalu adalah melambatkan kecepatan, membaca aturannya, atau bertanya; jawaban salah adalah menyamarkan crawler. Berikut cara membangun jawaban yang tepat ke dalam kode.

**Jawaban cepat — Bagaimana seharusnya scraper menangani respons 403, 429, dan CAPTCHA?**

Perlakukan mereka sebagai sinyal, bukan hambatan. Pada **429**, tunggu selama `Retry-After` dan turunkan laju pada host itu. Pada **403**, coba sekali lagi setelah jeda, lalu berhenti dan periksa aturan situs. Pada **CAPTCHA**, hentikan host itu: jangan selesaikan otomatis. **CrawlRelay proxy residensial**, dari US$0,50/GB, mendistribusikan beban dan mengatur lokasi; ini bukan cara mengakali keputusan situs. Tanpa KYC. Bayar dengan crypto.

## Tiga sinyal dalam sekejap

| Atribut | Nilai |
| --- | --- |
| 429 Too Many Requests | Anda terlalu cepat. Hormati Retry-After, mundur, turunkan concurrency per-host |
| 403 Forbidden | Permintaan ini ditolak. Coba sekali setelah jeda, lalu berhenti dan tinjau kembali |
| Halaman CAPTCHA atau tantangan | Situs ingin tahu apakah Anda manusia. Hentikan host dan perlambat |
| Standar untuk aturan crawl | robots.txt, RFC 9309; Crawl-delay adalah ekstensi umum |
| Yang tidak kami dukung | Penyelesaian CAPTCHA, plugin penyamaran, pemalsuan sidik jari |

## Apa arti masing-masing sinyal untuk crawler saya?

- **429** adalah yang paling sopan: kontennya tersedia, tapi tidak dengan kecepatan Anda. RFC 6585 mendefinisikannya, biasanya dengan header `Retry-After` yang memberi tahu kapan harus kembali.
- **403** adalah penolakan permintaan ini. Bisa diperbaiki (negara salah, header hilang, terlalu cepat) atau final (situs tidak mengizinkan akses otomatis ke konten itu).
- **CAPTCHA atau halaman tantangan**, sering dengan status 403 atau 503, berarti manajemen bot situs meragukan traffic Anda. Ini eskalasi: langkah setelah 429 yang diabaikan.

Ketiganya adalah sinyal yang meningkat. Situs yang mengabaikan 429 akan meningkat ke 403 dan tantangan, lalu blok panjang untuk keseluruhan rentang IP, yang merugikan semua pengguna rentang itu.

## Apa yang harus dilakukan crawler saya untuk setiap sinyal?

| Sinyal | Respon pertama | Jika terus berlanjut | Berhenti saat |
| --- | --- | --- | --- |
| 429 | Tunggu Retry-After atau mundur secara eksponensial dengan jitter | Kurangi concurrency pada host itu setengahnya | Retry-After terus bertambah, atau 429 tetap ada meski satu permintaan sekaligus |
| 403 | Satu kali coba ulang setelah jeda, negara sama | Bandingkan dengan browser dari negara sama; cek robots.txt dan ketentuan | 403 kedua pada pola URL sama |
| CAPTCHA / tantangan | Jeda host beberapa menit | Mulai ulang dengan laju jauh lebih rendah | Tantangan kembali pada laju rendah: situs tidak mengizinkan akses otomatis |
| 503 dengan Retry-After | Tunggu sesuai permintaan | Jeda host | Kebanyakan permintaan gagal lebih dari beberapa menit |

## Bagaimana membangun crawler yang merespon dengan benar?

Letakkan aturan dalam fetcher, bukan di tiap spider. Fetcher ini mengirim satu permintaan per saat per host, menghormati robots.txt dan `Crawl-delay`, menunggu `Retry-After`, dan berhenti menanyakan host setelah tiga penolakan berturut-turut. Menganggap 4xx pada robots.txt sebagai izin, dan 5xx sebagai larangan penuh, sesuai RFC 9309.

*Python: fetcher yang sopan*

```python
import time
import urllib.robotparser
from urllib.parse import urlsplit

import requests

PROXY = "http://USERNAME-country-us:PASSWORD@gw.crawlrelay.com:7777"
USER_AGENT = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"


class PoliteFetcher:
    """One request at a time per host; robots.txt, Crawl-delay and Retry-After honoured."""

    def __init__(self, min_interval=1.0, max_refusals=3):
        self.min_interval, self.max_refusals = min_interval, max_refusals
        self.http = requests.Session()
        self.http.proxies = {"http": PROXY, "https": PROXY}
        self.http.headers["User-Agent"] = USER_AGENT
        self.robots, self.next_time, self.refusals = {}, {}, {}

    def _robots(self, root):
        if root not in self.robots:
            rp = urllib.robotparser.RobotFileParser(root + "/robots.txt")
            try:
                r = self.http.get(root + "/robots.txt", timeout=(10, 30))
                if r.status_code >= 500:
                    rp.parse(["User-agent: *", "Disallow: /"])  # unreachable: assume disallow
                else:
                    rp.parse(r.text.splitlines() if r.status_code == 200 else [])  # 4xx: allowed
            except requests.RequestException:
                rp.parse(["User-agent: *", "Disallow: /"])
            self.robots[root] = rp
        return self.robots[root]

    def get(self, url):
        scheme, host = urlsplit(url)[:2]
        if self.refusals.get(host, 0) >= self.max_refusals:
            return None  # this host said no: stop asking
        rp = self._robots("%s://%s" % (scheme, host))
        if not rp.can_fetch(USER_AGENT, url):
            return None
        delay = max(self.min_interval, rp.crawl_delay(USER_AGENT) or 0)
        wait = self.next_time.get(host, 0) - time.monotonic()
        if wait > 0:
            time.sleep(wait)
        r = self.http.get(url, timeout=(10, 30))
        pause = delay
        if r.status_code in (429, 503):
            retry_after = r.headers.get("Retry-After", "")
            pause = max(delay, int(retry_after) if retry_after.isdigit() else 60)
        refused = r.status_code in (403, 429) or "captcha" in r.text[:5000].lower()
        self.refusals[host] = self.refusals.get(host, 0) + 1 if refused else 0
        self.next_time[host] = time.monotonic() + pause
        return r


fetcher = PoliteFetcher()
resp = fetcher.get("https://example.com/")
print(resp.status_code if resp is not None else "skipped")
```

## Apa yang memperbaiki 403 secara sah?

Beberapa penyebab 403 berasal dari sisi Anda, dan memperbaikinya wajar:

- **Negara yang salah.** Banyak situs melayani satu wilayah. Targetkan negara dengan `-country-<code>` proxy residensial.
- **Header tidak lengkap.** Kirim `Accept`, `Accept-Language` dan user agent yang jujur dengan URL kontak. User agent mirip browser pada klien HTTP biasa tidak konsisten dan sering ditolak.
- **Kecepatan Anda sendiri.** 403 yang muncul setelah N permintaan adalah masalah laju; perlambat.

Yang bukan perbaikan: mengganti-ganti user agent untuk terlihat seperti banyak orang berbeda, memalsukan sidik jari browser, atau mengganti IP untuk mengakali blok yang sengaja dibuat situs. Jika situs memfilter rentang hosting untuk menghalangi traffic otomatis, IP residensial tidak membuat akses itu diizinkan.

## Kenapa tidak sekadar menyelesaikan CAPTCHA?

Karena CAPTCHA adalah situs yang menanyakan pertanyaan yang akan Anda jawab dengan salah. Penyelesaian otomatis mengubah crawler yang sopan menjadi alat yang dibuat untuk mengalahkan kontrol akses, yang meningkatkan risiko hukum Anda: kasus AS tahun 2026 tentang scraping pencarian, Google v. SerpApi dan Reddit v. SerpApi serta lainnya, mengangkat klaim bahwa terdakwa mengakali sistem anti-bot di bawah aturan anti-sirkumvensi DMCA. Pengadilan belum memutuskan masalah ini, tapi risikonya nyata.

CrawlRelay tidak mendukung penyelesaian CAPTCHA atau penghindaran deteksi bot, dan [Kebijakan Penggunaan yang Dapat Diterima](https://crawlrelay.com/id/acceptable-use/) melarangnya melalui gateway. Jika Anda butuh data di balik tantangan, mintalah akses ke situs, gunakan API-nya, atau lisensikan datanya.

## Kapan saya harus menghubungi situs?

Saat Anda membutuhkan lebih dari yang diizinkan default-nya. Banyak situs menawarkan API, data feed, program mitra atau batas lebih tinggi untuk crawler yang mengidentifikasi dirinya dan menjelaskan tujuan. Cantumkan URL kontak pada user agent Anda, sediakan halaman yang menjelaskan crawler dan cara opt out, dan tanggapi laporan penyalahgunaan dengan cepat. Crawler yang bisa dihubungi akan mendapat peringatan sebelum diblokir.

## 403, 429, dan CAPTCHA: pertanyaan

### Apakah proxy residensial menghentikan CAPTCHA?

Jangan mengandalkannya. Exit proxy residensial mengubah IP yang dilihat situs, bukan perilaku crawler Anda: CAPTCHA yang disebabkan oleh kecepatan atau perilaku tetap ada, dan memang sengaja begitu. Jika tantangan muncul pada tingkat permintaan rendah, situs tidak menginginkan akses otomatis ke konten itu.

### Berapa lama saya harus menunggu setelah mendapat 429 tanpa Retry-After?

Mulailah dari beberapa detik dan gandakan waktu tunggu setelah setiap 429 baru, dengan tambahan acak dan batas sekitar satu menit. Saat permintaan kembali berhasil, lanjutkan dengan tingkat lebih rendah dari yang menyebabkan 429, dan tingkatkan perlahan saat tingkat kesalahan stabil.

### Apakah rotasi IP untuk menghindari batas rate diperbolehkan?

Rotasi menyebarkan beban di beberapa exit dan memungkinkan Anda memilih lokasi, yang normal. Menggunakan rotasi untuk tetap di bawah batas per-IP sambil mempertahankan tingkat permintaan yang ditolak situs adalah pengelakan. Sebagian besar ketentuan penggunaan melarangnya, begitu juga Kebijakan Penggunaan yang Dapat Diterima kami.

### User agent apa yang harus scraper saya kirim?

Gunakan milik Anda sendiri: nama, versi, dan URL yang menjelaskan crawler serta cara menghubungi Anda, misalnya `ExampleCrawler/1.0 (+https://example.com/crawler-info)`. Jangan gunakan nama crawler lain seperti Googlebot atau GPTBot.

## Sumber

1. [RFC 9309: Protokol Pengecualian Robot](https://www.rfc-editor.org/rfc/rfc9309.html) — IETF (2022-09)
2. [RFC 6585: Kode Status HTTP Tambahan (429)](https://www.rfc-editor.org/rfc/rfc6585) — IETF (2012-04)
3. [Reddit v. SerpApi LLC](https://www.loeb.com/en/insights/publications/2026/08/reddit-v-serpapi-llc) — Loeb & Loeb (2026-08)
4. [Google v. SerpApi: pengadilan mengabulkan mosi kami untuk menghentikan perkara](https://serpapi.com/blog/google-v-serpapi-the-court-granted-our-motion-to-dismiss/) — SerpApi (2026-07-21)

**Proxy residensial untuk crawler yang sopan** US$1,50 untuk 1 GB, US$0,50/GB dari 50 GB. [Lihat harga](https://crawlrelay.com/id/pricing/) · [Referensi error](https://crawlrelay.com/id/docs/errors/)

---

CrawlRelay: CrawlRelay adalah layanan proxy residensial dan proxy seluler 4G/5G yang berfokus pada pengembang untuk scraper dan pipeline data AI: trafik pay-as-you-go tanpa kedaluwarsa mulai dari US$0,50/GB, dibayar dengan crypto, tanpa perlu unggah ID. Tanpa KYC — tanpa ID, tanpa selfie, tanpa dokumen. Bayar dengan crypto.
