Yang menghentikan proyek riset media sosial biasanya bukan parser HTML Anda, melainkan satu tantangan CAPTCHA di halaman login atau di hasil pencarian. Alurnya sebenarnya pendek: deteksi sitekey di halaman, kirim ke API CaptchaAI, tempelkan token yang kembali ke request berikutnya, lalu lanjutkan pengumpulan data seperti biasa.
Di bawah ini: peta CAPTCHA per platform, kode scraper Python untuk reCAPTCHA v2 dan Turnstile, ritme request yang wajar, plus hitungan biaya untuk agensi riset kecil di Jakarta yang anggarannya harus tetap datar.
Tentukan dulu ruang lingkup data Anda
Sebelum menulis satu baris scraper, kunci dulu apa yang boleh masuk dataset:
- Hanya data publik. Profil, postingan, dan statistik yang bisa dilihat siapa pun tanpa masuk sebagai orang lain.
- API resmi lebih dulu. Kalau platform menyediakan API dengan field yang Anda butuhkan, pakai itu — lebih stabil dan sesuai Ketentuan Layanan.
- Minimalkan data pribadi. UU Pelindungan Data Pribadi (UU 27/2022) dan UU ITE membuat pengumpulan data pribadi tanpa dasar pemrosesan yang jelas menjadi risiko nyata bagi tim riset di Indonesia. Simpan agregat dan teks postingan, bukan identitas perorangan. Ini catatan kepatuhan, bukan nasihat hukum.
- Hormati batas laju. Ritme request yang sopan menurunkan frekuensi CAPTCHA jauh lebih efektif daripada trik apa pun di sisi klien.
Peta CAPTCHA di platform sosial
Peta ini menentukan method mana yang Anda kirim ke in.php.
| Platform | Jenis CAPTCHA | Kapan biasanya muncul | Konteks |
|---|---|---|---|
| reCAPTCHA v2 | Login, pencarian, akses profil | Pembatasan laju permintaan | |
| reCAPTCHA v2 | Login, pencarian berulang | Checkpoint keamanan | |
| Twitter/X | Cloudflare Turnstile | Login, akses API | Pencegahan bot |
| TikTok | reCAPTCHA v3 | Tampilan profil, pencarian | Penilaian kualitas trafik |
| Cloudflare Challenge | Pengambilan data profil | Deteksi bot | |
| reCAPTCHA v2 | Login, penjelajahan intensif | Pencegahan penyalahgunaan |
Semua tipe di atas didukung CaptchaAI: reCAPTCHA v3 selesai di bawah 4 detik, Cloudflare Turnstile di bawah 10 detik, Cloudflare Challenge di bawah 15 detik, dan reCAPTCHA v2 di bawah 60 detik, dengan tingkat keberhasilan tinggi pada tipe yang didukung. Kalau target Anda memakai hCaptcha atau FunCaptcha, berhenti di sini: keduanya belum didukung, dan GeeTest v4 baru berstatus segera hadir.
Scraper riset sosial dengan penanganan CAPTCHA otomatis
Kelas berikut menyatukan satu sesi HTTP yang konsisten, satu fungsi penyelesaian yang dipakai ulang, dan deteksi tantangan pada tiap respons — dengan pola empat langkah yang sama seperti integrasi CaptchaAI lainnya: kirim task ke in.php, simpan task ID, polling res.php, pakai token.
import requests
import time
import re
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_captcha(method, sitekey, pageurl, **kwargs):
data = {
"key": CAPTCHAAI_KEY,
"method": method,
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
data.update(kwargs)
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
"key": CAPTCHAAI_KEY, "action": "get",
"id": task_id, "json": 1,
})
r = result.json()
if r["request"] != "CAPCHA_NOT_READY":
return r["request"]
raise TimeoutError("Solve timeout")
class SocialMediaResearcher:
def __init__(self, proxy=None):
self.session = requests.Session()
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 "
"Mobile/15E148 Safari/604.1",
"Accept-Language": "en-US,en;q=0.9",
})
def authenticate(self, login_url, credentials, sitekey):
"""Login with CAPTCHA handling."""
# Load login page
self.session.get(login_url)
# Solve CAPTCHA
token = solve_captcha("userrecaptcha", sitekey, login_url)
# Submit login
resp = self.session.post(login_url, data={
**credentials,
"g-recaptcha-response": token,
})
return resp.status_code == 200
def collect_profiles(self, profile_urls):
"""Collect public profile data with CAPTCHA handling."""
profiles = []
for url in profile_urls:
try:
resp = self.session.get(url, timeout=30)
# Handle CAPTCHA if triggered
if self._has_captcha(resp.text):
resp = self._handle_captcha(resp.text, url)
profiles.append({
"url": url,
"data": self._parse_profile(resp.text),
"status": "success",
})
time.sleep(5) # Slow down between profiles
except Exception as e:
profiles.append({
"url": url,
"error": str(e),
"status": "failed",
})
return profiles
def _has_captcha(self, html):
return any(tag in html.lower() for tag in [
'data-sitekey', 'g-recaptcha', 'cf-turnstile',
'challenge-platform', 'captcha',
])
def _handle_captcha(self, html, url):
match = re.search(r'data-sitekey="([^"]+)"', html)
if not match:
return self.session.get(url)
sitekey = match.group(1)
if 'cf-turnstile' in html:
token = solve_captcha("turnstile", sitekey, url)
return self.session.post(url, data={"cf-turnstile-response": token})
else:
token = solve_captcha("userrecaptcha", sitekey, url)
return self.session.post(url, data={"g-recaptcha-response": token})
def _parse_profile(self, html):
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
return {
"name": self._safe_text(soup, "h1, .profile-name"),
"bio": self._safe_text(soup, ".bio, .profile-bio"),
"followers": self._safe_text(soup, "[data-followers], .followers"),
"posts": self._safe_text(soup, "[data-posts], .posts-count"),
}
def _safe_text(self, soup, selector):
el = soup.select_one(selector)
return el.get_text(strip=True) if el else ""
Dua detail yang sering terlewat. _has_captcha memeriksa penanda seperti data-sitekey, g-recaptcha, dan cf-turnstile sebelum Anda membuang waktu mem-parsing halaman verifikasi. Dan nama field token harus cocok dengan jenis tantangan: g-recaptcha-response untuk reCAPTCHA, cf-turnstile-response untuk Turnstile. Salah field berarti token valid tetapi request tetap ditolak.
Mengumpulkan postingan per hashtag untuk analisis tren
Riset tren butuh volume postingan per tagar, bukan profil satu per satu. Fungsi berikut menelusuri beberapa halaman hasil dan menangani tantangan di tengah jalan tanpa memutus sesi.
def research_hashtag(hashtag, platform_url, pages=5):
"""Collect posts for a specific hashtag."""
researcher = SocialMediaResearcher(
proxy="http://user:pass@mobile.proxy.com:5000"
)
all_posts = []
for page in range(pages):
url = f"{platform_url}/explore/tags/{hashtag}?page={page}"
resp = researcher.session.get(url, timeout=30)
if researcher._has_captcha(resp.text):
resp = researcher._handle_captcha(resp.text, url)
from bs4 import BeautifulSoup
soup = BeautifulSoup(resp.text, "html.parser")
posts = soup.select(".post-item, article")
for post in posts:
all_posts.append({
"text": post.get_text(strip=True)[:500],
"hashtag": hashtag,
"page": page,
})
time.sleep(5)
return all_posts
Jalankan terjadwal dan simpan hasilnya mentah dulu; normalisasi teks sebaiknya jadi tahap terpisah.
Memantau penyebutan merek setiap hari
Ini kasus yang paling sering dipesan klien agensi di Indonesia: laporan harian berisi berapa kali sebuah merek disebut di beberapa platform, dipecah per kata kunci.
import json
from datetime import datetime
class BrandMonitor:
def __init__(self, brand_name, keywords, proxy=None):
self.brand = brand_name
self.keywords = keywords
self.researcher = SocialMediaResearcher(proxy=proxy)
def daily_scan(self, platform_urls):
"""Run daily brand mention scan across platforms."""
report = {
"brand": self.brand,
"date": datetime.now().isoformat(),
"platforms": {},
}
for name, url in platform_urls.items():
mentions = []
for keyword in self.keywords:
search_url = f"{url}/search?q={keyword}"
try:
resp = self.researcher.session.get(search_url, timeout=30)
if self.researcher._has_captcha(resp.text):
resp = self.researcher._handle_captcha(
resp.text, search_url,
)
from bs4 import BeautifulSoup
soup = BeautifulSoup(resp.text, "html.parser")
results = soup.select(".search-result, .post")
mentions.append({
"keyword": keyword,
"count": len(results),
})
time.sleep(5)
except Exception as e:
mentions.append({
"keyword": keyword,
"error": str(e),
})
report["platforms"][name] = mentions
return report
# Usage
monitor = BrandMonitor(
brand_name="CaptchaAI",
keywords=["captchaai", "captcha ai", "captcha solver"],
proxy="http://user:pass@mobile.proxy.com:5000",
)
report = monitor.daily_scan({
"twitter": "https://twitter-alternative.example.com",
"reddit": "https://www.reddit.com",
})
print(json.dumps(report, indent=2))
Karena pemindaian harian berjalan tanpa pengawasan, catat kegagalan per kata kunci alih-alih menghentikan seluruh proses: laporan dengan tiga kata kunci gagal masih berguna.
Ritme request dan durasi sesi yang wajar
Frekuensi tantangan berbanding lurus dengan agresivitas pola akses Anda. Angka berikut adalah titik awal konservatif, bukan janji.
| Platform | Jeda antar request | Durasi sesi sebelum jeda panjang |
|---|---|---|
| 1 request / 10 detik | Maks 5 menit | |
| 1 request / 5 detik | Maks 10 menit | |
| Twitter/X | 1 request / 3 detik | Maks 15 menit |
| TikTok | 1 request / 5 detik | Maks 5 menit |
| 1 request / 10 detik | Maks 5 menit | |
| 1 request / 2 detik | Maks 30 menit |
Dua catatan pelengkap. Gunakan egress jaringan yang diotorisasi dan konsisten selama satu sesi berjalan — berpindah jalur keluar di tengah sesi hampir selalu memicu tantangan baru. Lalu cocokkan lokasi jaringan dengan audiens yang diteliti; untuk deployment, region seperti AWS ap-southeast-1 (Singapura) atau ap-southeast-3 (Jakarta) memberi latensi yang masuk akal bagi target Indonesia.
Biaya: dihitung per thread, bukan per penyelesaian
CaptchaAI menagih per thread berjalan, dengan penyelesaian tanpa batas selama bulan berjalan. Biaya Anda ditentukan oleh berapa banyak CAPTCHA yang diselesaikan bersamaan, bukan berapa totalnya.
Freelancer yang menjalankan pemindaian merek harian untuk dua atau tiga klien umumnya cukup dengan BASIC ($15/bulan, 5 thread). Agensi riset dengan beberapa pipeline di jam yang sama biasanya naik ke STANDARD ($30/bulan, 15 thread), sementara tim data yang mengumpulkan data sepanjang hari cocok di ADVANCE ($90/bulan, 50 thread). Semua harga dalam USD.
Karena tidak ada biaya per CAPTCHA, menambah kata kunci atau tagar tidak menaikkan tagihan.
Masalah umum dan cara menanganinya
| Gejala | Penyebab paling mungkin | Penanganan |
|---|---|---|
| CAPTCHA di hampir setiap request | Pola akses terlalu rapat | Perbesar jeda, perpendek sesi |
| Halaman kembali kosong | Konten di balik login | Autentikasi dulu, atau ganti sumber |
| Token diterima tetapi request ditolak | Field token salah | g-recaptcha-response atau cf-turnstile-response |
| Cloudflare Challenge berulang | Sinyal browser tidak konsisten | Puppeteer/Playwright konfigurasi standar |
| Batas waktu tercapai saat polling | Batas percobaan terlalu pendek | Jeda 5 detik, perpanjang percobaan |
Pertanyaan umum
Bagaimana kalau platform target memakai hCaptcha atau FunCaptcha?
Berhenti di situ. hCaptcha dan FunCaptcha (Arkose Labs) tidak didukung, dan GeeTest v4 baru berstatus segera hadir. Yang didukung dan relevan di sini: reCAPTCHA v2 (termasuk Invisible dan Enterprise), reCAPTCHA v3, Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, serta image CAPTCHA. CaptchaFox (beta), Friendly Captcha (beta), dan Lemin (beta) masih berstatus beta.
Berapa lama satu tantangan diselesaikan?
Bergantung tipenya: reCAPTCHA v3 di bawah 4 detik, Turnstile di bawah 10 detik, Cloudflare Challenge di bawah 15 detik, reCAPTCHA v2 di bawah 60 detik. Itu batas atas layanan, jadi jangan menetapkan timeout 15 detik untuk reCAPTCHA v2.
Paket mana yang masuk akal untuk pemindaian harian ratusan profil?
Hitung dari konkurensi, bukan total. Kalau scraper hanya memproses lima halaman bersamaan, BASIC ($15/bulan, 5 thread) sudah cukup meski total profilnya ribuan. Naikkan paket ketika thread menjadi antrean yang menahan pipeline.
Bagaimana cara menurunkan jumlah CAPTCHA yang perlu diselesaikan?
Perbesar jeda antar request, pertahankan satu sesi dan satu jalur keluar selama pengumpulan, dan hentikan permintaan berulang ke endpoint pencarian yang sama. Penanganan otomatis lewat API adalah jaring pengaman, bukan pengganti pola akses yang wajar.
Bacaan lanjutan
- Pengaruh jalur jaringan keluar terhadap tingkat keberhasilan penyelesaian CAPTCHA
- Menjaga sesi browser tetap konsisten dalam alur kerja CAPTCHA
- Isolasi profil browser pada integrasi CaptchaAI
Jangan biarkan riset sosial Anda berhenti di halaman verifikasi — ambil API key CaptchaAI dan tangani reCAPTCHA v2, reCAPTCHA v3, serta Cloudflare Turnstile lewat satu fungsi.