Monitor ketersediaan tiket yang stabil butuh tiga bagian yang bekerja bersama: pengecekan berkala ke halaman event, penyelesaian CAPTCHA otomatis begitu reCAPTCHA atau Cloudflare Turnstile muncul, dan egress jaringan yang diotorisasi supaya IP Anda tidak diblokir setelah beberapa kali cek — dan panduan ini merangkai ketiganya jadi satu script Python yang cek status, selesaikan tantangan CAPTCHA, kirim alert begitu status berubah, lalu jalan otomatis lewat cron.
Kapan Monitoring Seperti Ini Layak Dibangun
- Tim price-monitoring dan agensi freelance memakai pola ini untuk memantau ketersediaan tiket atas nama klien — bukan untuk membeli otomatis, tapi supaya klien tahu lebih dulu kapan status berubah dari sold out ke tersedia.
- Event dengan volume tinggi — pembukaan penjualan konser musisi internasional yang show di Jakarta, atau final pertandingan olahraga besar — biasanya butuh frekuensi cek yang dinaikkan ke 2–5 menit di jam-jam awal penjualan, lalu diturunkan lagi begitu lonjakan reda.
- Monitor ini hanya membaca status ketersediaan yang memang publik dan tidak menyimpan data pribadi pembeli, sehingga pada umumnya aman dari sisi UU Pelindungan Data Pribadi (UU 27/2022) — tetap hindari menambahkan pengumpulan data pribadi pihak lain ke dalam scraper Anda.
Alur Kerja: Cek Ketersediaan sampai Alert
Diagram berikut meringkas logikanya, dari pengecekan pertama sampai alert terkirim:
Configure events → Check availability → CAPTCHA?
↓ Yes
Solve via CaptchaAI → Retry
↓ No
Parse availability → Changed?
↓ Yes
Send alert
- Kalau CAPTCHA terdeteksi — reCAPTCHA atau Turnstile — monitor menyelesaikannya lewat CaptchaAI dulu, baru mencoba lagi.
- Kalau tidak ada CAPTCHA, server langsung mengembalikan data ketersediaan dan monitor lompat ke proses parsing.
Komponen yang Diperlukan
- API Key CaptchaAI — daftar di captchaai.com
- Python 3.8+ dengan library
requests - Egress jaringan yang diotorisasi — direkomendasikan untuk menekan frekuensi blokir IP
pip install requests
Fungsi Helper untuk Menyelesaikan CAPTCHA
Fungsi generik berikut menangani submit dan polling untuk kedua tipe CAPTCHA yang muncul di halaman tiket — reCAPTCHA v2 dan Cloudflare Turnstile:
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_captcha(method, params):
"""Generic CaptchaAI solver for any supported method."""
params["key"] = API_KEY
params["json"] = 1
submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
initial_wait = 10 if method == "turnstile" else 20
time.sleep(initial_wait)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
Class Monitor Tiket
Class TicketMonitor memakai fungsi di atas: buka halaman event, deteksi tantangan CAPTCHA yang muncul, submit token yang sesuai, lalu bandingkan hasil parsing dengan status sebelumnya untuk memutuskan apakah alert perlu dikirim:
from datetime import datetime
import json
class TicketMonitor:
def __init__(self, proxy=None):
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
if proxy:
self.session.proxies = {
"http": f"http://{proxy}",
"https": f"http://{proxy}"
}
self.last_status = {}
def check_event(self, event):
"""Check ticket availability for an event, solving CAPTCHAs if needed."""
url = event["url"]
response = self.session.get(url)
# Handle CAPTCHA if detected
if "g-recaptcha" in response.text or "recaptcha" in response.text:
sitekey = self._extract_sitekey(response.text)
if sitekey:
token = solve_captcha("userrecaptcha", {
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": url
})
response = self.session.post(url, data={
"g-recaptcha-response": token
})
elif "cf-turnstile" in response.text:
sitekey = self._extract_turnstile_key(response.text)
if sitekey:
token = solve_captcha("turnstile", {
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url
})
response = self.session.post(url, data={
"cf-turnstile-response": token
})
# Parse availability
availability = self._parse_availability(response.text, event)
# Check for changes
event_key = event["name"]
if event_key in self.last_status:
if availability != self.last_status[event_key]:
self._send_alert(event, availability)
self.last_status[event_key] = availability
return availability
def _extract_sitekey(self, html):
if 'data-sitekey="' in html:
start = html.index('data-sitekey="') + 14
end = html.index('"', start)
return html[start:end]
return None
def _extract_turnstile_key(self, html):
if 'data-sitekey="' in html:
start = html.index('data-sitekey="') + 14
end = html.index('"', start)
return html[start:end]
return None
def _parse_availability(self, html, event):
"""Parse ticket availability. Customize per ticketing site."""
available = "sold out" not in html.lower()
return {
"event": event["name"],
"available": available,
"checked_at": datetime.now().isoformat()
}
def _send_alert(self, event, availability):
"""Send availability change notification."""
status = "AVAILABLE" if availability["available"] else "SOLD OUT"
print(f"[ALERT] {event['name']}: {status}")
def monitor_all(self, events):
"""Check all events and return results."""
results = []
for event in events:
try:
result = self.check_event(event)
results.append(result)
print(f"[OK] {event['name']}: {'available' if result['available'] else 'sold out'}")
except Exception as e:
print(f"[ERROR] {event['name']}: {e}")
return results
# Usage
events = [
{
"name": "Concert - Madison Square Garden - Aug 15",
"url": "https://example-tickets.com/event/12345"
},
{
"name": "Basketball Finals - Game 7",
"url": "https://example-tickets.com/event/67890"
}
]
monitor = TicketMonitor(proxy="user:pass@proxy.example.com:8080")
results = monitor.monitor_all(events)
for r in results:
print(json.dumps(r, indent=2))
Hasil yang diharapkan:
[OK] Concert - Madison Square Garden - Aug 15: available
[OK] Basketball Finals - Game 7: sold out
Catatan: log
[OK]/[ALERT]/[ERROR]di atas cukup untuk debugging lokal. Untuk monitoring produksi, alirkan log yang sama ke file atau layanan log terpusat supaya histori tidak hilang saat proses restart.
Jadwalkan Pengecekan dengan Cron
Jalankan script ini secara berkala lewat cron di server Anda — VPS di Singapura (ap-southeast-1) atau Jakarta (ap-southeast-3) biasanya memberi latensi paling rendah ke situs tiket yang menargetkan pasar Asia Tenggara:
# Check every 15 minutes
*/15 * * * * cd /path/to/project && python ticket_monitor.py >> /var/log/tickets.log 2>&1
Praktik Terbaik agar Monitoring Tidak Gampang Diblokir
Beberapa penyesuaian kecil membuat monitor jauh lebih tahan lama:
- Simpan cookie sesi antar-pengecekan. IP dan session yang sama tanpa persistensi memicu CAPTCHA lebih sering daripada seharusnya.
- Rotasi egress jaringan yang diotorisasi, terutama untuk event dengan traffic tinggi — satu IP yang memukul halaman yang sama tiap 2 menit adalah pola yang mudah dikenali sistem anti-bot.
- Terapkan retry dengan backoff saat solve gagal atau timeout, bukan retry langsung — mengulang instan saat beban solver tinggi biasanya hanya memperpanjang antrean.
- Naikkan
initial_waitkalau Anda sering melihat statusCAPCHA_NOT_READYberulang-ulang sebelum solve selesai; itu tanda tantangan butuh waktu penyelesaian lebih lama dari asumsi default. - Catat histori status, bukan cuma status terbaru — berguna untuk audit kapan tepatnya tiket berubah dari sold out ke tersedia, dan untuk debug kalau parser mulai salah baca halaman.
Masalah yang Sering Terjadi
| Masalah | Penyebab | Perbaikan |
|---|---|---|
| CAPTCHA muncul di hampir setiap pengecekan | IP sama, sesi tidak persisten | Simpan cookie, rotasi egress jaringan yang diotorisasi |
| Diblokir setelah beberapa kali cek | Rate limiting | Perbesar interval cek, rotasi egress jaringan yang diotorisasi |
| Status ketersediaan salah | Struktur halaman berubah | Perbarui method _parse_availability |
| Solve CAPTCHA lambat | Beban solver tinggi | Terapkan retry logic dengan backoff |
Tip: kalau CAPTCHA muncul di hampir setiap pengecekan padahal frekuensinya sudah wajar, cek dulu apakah session cookie benar-benar tersimpan antar-request — ini lebih sering soal sesi daripada soal IP. Untuk status ketersediaan yang tiba-tiba salah, hampir selalu berarti struktur HTML platform tiket berubah dan
_parse_availabilityperlu disesuaikan ulang.
Pertanyaan Umum
Berapa banyak thread CaptchaAI yang saya butuhkan untuk memantau banyak event sekaligus?
Tergantung berapa banyak event yang dicek bersamaan dan seberapa sering. Paket BASIC ($15/bulan, 5 thread) biasanya cukup untuk memantau segelintir event dengan interval 10–15 menit; kalau Anda mengelola puluhan event untuk beberapa klien sekaligus, ADVANCE ($90/bulan, 50 thread) memberi headroom tanpa perlu upgrade tiap kali menambah event baru. Karena semua paket CaptchaAI berbasis thread dengan solve tanpa batas per thread, biayanya tetap flat berapa pun jumlah CAPTCHA yang terselesaikan bulan itu.
Seberapa sering sebaiknya saya mengecek ketersediaan tiket?
- Monitoring umum: interval 10–30 menit sudah memadai.
- Event permintaan tinggi — pembukaan penjualan konser besar atau final pertandingan: turunkan ke 2–5 menit di jam-jam sibuk, lalu naikkan lagi begitu lonjakan reda.
- Semakin sering Anda mengecek, semakin sering pula CAPTCHA muncul, jadi interval yang lebih rapat butuh alokasi thread yang lebih besar juga.
Apakah saya perlu menyimpan log histori ketersediaan, bukan hanya status terbaru?
Untuk monitoring dasar tidak wajib — TicketMonitor di atas hanya membandingkan status terakhir untuk memutuskan kapan mengirim alert. Tapi kalau Anda perlu bukti kapan tepatnya tiket berubah status, atau ingin men-debug parser yang salah baca halaman, simpan tiap hasil check_event ke file log atau database kecil, alih-alih hanya menyimpannya di self.last_status.
Apakah egress jaringan yang diotorisasi wajib dipakai untuk monitor tiket?
- Kenapa perlu: situs tiket agresif memblokir IP datacenter begitu mendeteksi pola pengecekan berulang, dan egress jaringan yang diotorisasi jauh mengurangi frekuensi CAPTCHA dibanding IP datacenter biasa.
- Kapan bisa tanpanya: untuk uji coba awal dengan sedikit event, Anda bisa jalan dulu tanpa itu — tapi begitu memantau lebih dari beberapa event sekaligus, blokir biasanya datang cepat.
Apa yang harus saya lakukan kalau solve CAPTCHA gagal atau timeout di tengah monitoring?
Fungsi solve_captcha di atas melempar RuntimeError atau TimeoutError begitu submit gagal atau solve tidak selesai dalam 30 kali polling. Bungkus pemanggilan check_event dalam blok try/except seperti pada monitor_all di atas, supaya satu event yang gagal tidak menghentikan pengecekan event lain — lalu tambahkan retry dengan backoff sebelum menyerah sepenuhnya pada event tersebut.
Mulai Monitoring Tiket Anda
- Ambil API key CaptchaAI dan hubungkan ke script monitor di atas — reCAPTCHA v2 dan Cloudflare Turnstile yang muncul di halaman tiket akan terselesaikan otomatis.
- Daftar di captchaai.com dan fokus ke logika alert Anda, bukan ke CAPTCHA-nya.