معظم سكربتات البحث في السجلات العامة لا تتعطل بسبب منطق البحث نفسه، بل عند أول اختبار CAPTCHA يظهر في صفحة النموذج. فبوابات المحاكم وسجلات الشركات والعقارات ما تزال تعتمد على كابتشا الصور وOCR القديمة — نص مشوّه، أو معادلة حسابية بسيطة، أو رمز رقمي — ويكفي واحد منها لإيقاف الأتمتة بالكامل. الحل مباشر: يرسل سكربتك صورة الكابتشا إلى CaptchaAI، ويستقبل النص المُستخرج، ثم يُكمل إرسال النموذج كما لو أن مستخدماً بشرياً أدخله بنفسه.
لنأخذ مثالاً واقعياً: فريق تدقيق ونزاهة (due diligence) في القاهرة أو الرياض يحتاج إلى فحص مئات الكيانات التجارية في سجلات ولايات أمريكية قبل إتمام صفقة. البحث اليدوي عبر بوابة تلو الأخرى غير عملي، والعقبة المتكررة الوحيدة هي اختبار CAPTCHA للصورة عند كل استعلام. يوضح هذا الدليل كيف تتعامل مع هذه الاختبارات آلياً عبر أنواع السجلات المختلفة.
أتمتة البحث مع حل كابتشا الصورة
الفئة الأكثر شيوعاً هي كابتشا الصورة النصية، والنمط العملي لحلّها بسيط: حمّل صفحة البحث أولاً للحصول على جلسة صالحة، استخرج رابط صورة الكابتشا من HTML، نزّل الصورة وأرسلها إلى CaptchaAI بترميز base64، ثم ضع النص المُعاد في حقل النموذج. تجمع الفئة التالية في Python هذه الخطوات معاً وتستطلع النتيجة دورياً حتى تجهز:
import requests
import base64
import time
from urllib.parse import urljoin
class PublicRecordsSearcher:
def __init__(self, api_key):
self.api_key = api_key
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
def search_court_records(self, portal_url, case_number):
"""Search court records, solving image CAPTCHAs as needed."""
# Load the search page
page = self.session.get(f"{portal_url}/search")
# Extract CAPTCHA image
captcha_img_url = self._extract_captcha_url(page.text, portal_url)
if not captcha_img_url:
# No CAPTCHA on this page
return self._submit_search(portal_url, case_number)
# Download and solve CAPTCHA
img_response = self.session.get(captcha_img_url)
captcha_text = self._solve_image_captcha(img_response.content)
# Submit search with solved CAPTCHA
return self._submit_search(portal_url, case_number, captcha_text)
def _extract_captcha_url(self, html, base_url):
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Look for common CAPTCHA image patterns
captcha_img = (
soup.find("img", {"id": "captchaImage"}) or
soup.find("img", {"class": "captcha"}) or
soup.find("img", attrs={"src": lambda s: s and "captcha" in s.lower()})
)
if captcha_img and captcha_img.get("src"):
return urljoin(base_url, captcha_img["src"])
return None
def _solve_image_captcha(self, image_bytes):
img_base64 = base64.b64encode(image_bytes).decode("utf-8")
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": "base64",
"body": img_base64,
"json": 1
})
task_id = resp.json()["request"]
for _ in range(30):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key,
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"]
raise TimeoutError("CAPTCHA solve timed out")
def _submit_search(self, portal_url, case_number, captcha_text=None):
form_data = {"caseNumber": case_number}
if captcha_text:
form_data["captcha"] = captcha_text
response = self.session.post(
f"{portal_url}/search/results",
data=form_data
)
return response.text
# Usage
searcher = PublicRecordsSearcher("YOUR_API_KEY")
results = searcher.search_court_records(
"https://courts.example.gov",
"2024-CV-12345"
)
التعامل مع الكابتشا الحسابية
تلجأ بعض البوابات الحكومية إلى كابتشا حسابية بسيطة مثل «4 + 7 = ؟». يتعامل CaptchaAI معها بوصفها مهمة تعرّف على نص، مع تمرير المعلمة textinstructions لتوجيه الخدمة إلى حلّ المعادلة وإرجاع الرقم فقط:
def solve_math_captcha(self, image_bytes):
"""Solve math CAPTCHAs like '4 + 7 = ?'"""
img_base64 = base64.b64encode(image_bytes).decode("utf-8")
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": self.api_key,
"method": "base64",
"body": img_base64,
"textinstructions": "solve the math equation and return only the number",
"json": 1
})
task_id = resp.json()["request"]
# Poll for result
for _ in range(30):
time.sleep(3)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": self.api_key,
"action": "get",
"id": task_id,
"json": 1
})
data = result.json()
if data["status"] == 1:
return data["request"]
raise TimeoutError("Math CAPTCHA solve timed out")
تجميع نتائج عدة بوابات (JavaScript)
عند البحث في أكثر من بوابة ضمن العملية نفسها، يفيد تغليف المنطق في فئة واحدة تمرّ على البوابات وتتعامل مع الكابتشا عند وجودها فقط. المثال التالي بلغة JavaScript يفحص كل صفحة بحثاً عن صورة كابتشا، ويحلّها عند اللزوم، ثم يجمع النتائج مع عزل خطأ كل بوابة على حدة حتى لا تُسقط بوابةٌ واحدة العمليةَ كلها:
class RecordsAggregator {
constructor(apiKey) {
this.apiKey = apiKey;
}
async searchAcrossPortals(query, portals) {
const results = [];
for (const portal of portals) {
try {
const data = await this.searchPortal(portal, query);
results.push({ portal: portal.name, records: data });
} catch (error) {
results.push({ portal: portal.name, error: error.message });
}
}
return results;
}
async searchPortal(portal, query) {
const pageResponse = await fetch(portal.searchUrl);
const html = await pageResponse.text();
// Check for image CAPTCHA
const captchaMatch = html.match(/captcha[^"]*\.(?:png|jpg|gif)/i);
let captchaAnswer = null;
if (captchaMatch) {
const imgUrl = new URL(captchaMatch[0], portal.searchUrl).href;
const imgData = await fetch(imgUrl);
const buffer = await imgData.arrayBuffer();
const base64 = Buffer.from(buffer).toString('base64');
captchaAnswer = await this.solveImageCaptcha(base64);
}
// Submit search
const formData = new URLSearchParams({ q: query });
if (captchaAnswer) formData.append('captcha', captchaAnswer);
const response = await fetch(portal.searchUrl, {
method: 'POST',
body: formData
});
return response.text();
}
async solveImageCaptcha(base64Image) {
const submitResp = await fetch('https://ocr.captchaai.com/in.php', {
method: 'POST',
body: new URLSearchParams({
key: this.apiKey,
method: 'base64',
body: base64Image,
json: '1'
})
});
const { request: taskId } = await submitResp.json();
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 3000));
const result = await fetch(
`https://ocr.captchaai.com/res.php?key=${this.apiKey}&action=get&id=${taskId}&json=1`
);
const data = await result.json();
if (data.status === 1) return data.request;
}
throw new Error('CAPTCHA solve timed out');
}
}
// Usage
const aggregator = new RecordsAggregator('YOUR_API_KEY');
const results = await aggregator.searchAcrossPortals('Smith LLC', [
{ name: 'State Business Registry', searchUrl: 'https://sos.example.gov/search' },
{ name: 'County Court Records', searchUrl: 'https://courts.example.gov/search' }
]);
أنواع اختبارات CAPTCHA بحسب نوع البوابة
قبل ضبط المعلمات، من المفيد معرفة نوع الكابتشا الذي ستقابله في كل فئة بوابة، إذ يحدّد ذلك المسار الأنسب لحلّه:
| فئة البوابة | نوع CAPTCHA الشائع | مثال على التحدي |
|---|---|---|
| بحث قضايا المحاكم | كابتشا نصية مخصّصة | 5–6 أحرف وأرقام مشوّهة |
| سجلات عقارات المقاطعات | كابتشا حسابية | "كم يساوي 4 + 7؟" |
| بحث الكيانات التجارية | كابتشا نص داخل صورة | حروف ملتوية مع تشويش خطّي |
| السجلات الحيوية | reCAPTCHA v2 | اختيار صور ضمن شبكة |
| تراخيص البناء | كابتشا نصية بسيطة | رمز رقمي من 4 خانات |
| إيداعات UCC | كابتشا OCR مخصّصة | أحرف بحالة مختلطة مع ضوضاء خلفية |
معلمات الكابتشا لبوابات الحكومة
ضبط المعلمات الصحيحة يرفع دقة الحل مع صور السجلات الحكومية التي تكون غالباً منخفضة الجودة:
| المعلمة | القيمة | متى تستخدمها |
|---|---|---|
method |
base64 |
الصورة منزّلة إلى الذاكرة كبايتات |
method |
post |
إرسال ملف الصورة مباشرة |
language |
0 |
كابتشا نصية إنجليزية/لاتينية |
numeric |
1 |
كابتشا مكوّنة من أرقام فقط |
min_len / max_len |
يختلف | عندما يكون عدد الأحرف معروفاً مسبقاً |
textinstructions |
موجّه مخصّص | الكابتشا الحسابية أو التنسيقات الخاصة |
حل المشكلات الشائعة
| المشكلة | السبب | الحل |
|---|---|---|
| صورة الكابتشا تُرجع 403 | ملف تعريف ارتباط الجلسة مفقود | حمّل صفحة البحث أولاً، ثم اجلب الصورة |
| إجابة كابتشا خاطئة | جودة الصورة منخفضة | عالِج الصورة مسبقاً (رفع التباين وإزالة الضوضاء) |
| الكابتشا تتحدّث عند الإرسال | انتهت صلاحية رمز النموذج | استخرج حقول النموذج المخفية مع الكابتشا |
| البحث يرجع فارغاً بعد الكابتشا | فقد الإرسال ملفات الارتباط بعد إعادة التوجيه | استخدم allow_redirects=True وحافظ على الجلسة |
نمط تشغيل مسؤول للبوابات الحكومية
السجلات العامة مُصمّمة للاطلاع العلني، لكن أتمتة الاستعلام عنها تظل مسؤولية تقنية وأخلاقية في آن واحد. التزم بالمبادئ التالية لتبقى العملية مستقرة ومصرّحاً بها:
- احترم شروط البوابة ومعدل الطلبات: أضف مهلة زمنية بين الطلبات وتجنّب الضغط المتوازي الكثيف على خوادم حكومية قد تكون محدودة الموارد.
- أعد استخدام الجلسة: حمّل صفحة البحث مرة واحدة واحتفظ بملفات الارتباط بدل فتح جلسة جديدة لكل استعلام؛ هذا يقلّل عدد اختبارات الكابتشا المطلوبة منك أصلاً.
- خزّن النتائج مؤقتاً: إن كنت تفحص الكيان نفسه أكثر من مرة، احفظ النتيجة محلياً بدل تكرار البحث والحل.
- راقب معدل الحل: سجّل نسبة النجاح لكل بوابة، فإذا انخفضت فجأة فغالباً تغيّر تنسيق الكابتشا أو بنية الصفحة.
نصيحة عملية: حمّل صفحة البحث دائماً قبل جلب صورة الكابتشا؛ فمعظم أخطاء 403 على البوابات الحكومية سببها غياب ملف ارتباط الجلسة، لا حجب الخدمة.
من ناحية التكلفة، يعتمد CaptchaAI على التسعير بعدد الـ Threads المتزامنة لا بعدد عمليات الحل، مع حلول غير محدودة لكل thread ضمن الباقة. للبحث المتقطّع تكفي باقة BASIC ($15 شهرياً، 5 threads)، بينما تناسب فرق التدقيق التي تعالج دفعات كبيرة باقة ADVANCE ($90 شهرياً، 50 thread) أو أعلى. راجع صفحة الأسعار الرسمية لاختيار الباقة المناسبة لحجم عملك.
الأسئلة الشائعة
هل أتمتة البحث في السجلات العامة قانونية؟
السجلات العامة متاحة للاطلاع العلني بطبيعتها، وأتمتة الاستعلام عنها لأغراض مشروعة — كالتدقيق القانوني أو البحث أو الامتثال — أمر شائع. مع ذلك، التزم بشروط استخدام كل بوابة، ولا تتجاوز حدود المعدل المعلنة، ولا تُعِد نشر بيانات شخصية بطريقة تخالف الأنظمة المحلية. استخدم الأتمتة لتسريع وصول مصرّح به، لا لتجاوز قيود متعمَّدة.
كيف أتعامل مع بوابة تستخدم reCAPTCHA v2 بدل كابتشا الصورة؟
انتقلت بعض بوابات السجلات الحيوية إلى reCAPTCHA v2 بدل الصور المخصّصة. في هذه الحالة لا ترسل صورة، بل تستخدم مسار reCAPTCHA بمفتاح الموقع (sitekey) ورابط الصفحة، وتستقبل الرمز g-recaptcha-response لحقنه في النموذج. راجع دليل حلّ reCAPTCHA v2 عبر الـ API للخطوات الكاملة.
ما الفرق بين method=base64 وmethod=post عند إرسال الصورة؟
يُستخدم base64 حين تكون قد نزّلت الصورة إلى الذاكرة كبايتات ورمّزتها نصياً — وهو الأنسب عندما تُحمَّل الكابتشا خلف جلسة تتطلب ملفات ارتباط. أما post فيرسل ملف الصورة مباشرة، ويناسب الصور المتاحة كملف على القرص. النتيجة واحدة؛ الاختلاف في طريقة تمرير الصورة فقط.
هل أحتاج إلى معالجة الصور مسبقاً قبل الإرسال؟
في معظم الحالات لا. لكن مع الصور الشديدة التشويش أو المنخفضة الدقة، قد ترفع المعالجة المسبقة — التدرّج الرمادي وزيادة التباين وإزالة الضوضاء — دقة النتيجة قبل الإرسال. لمعرفة التقنيات العملية راجع دليل معالجة صور الكابتشا مسبقاً.
ابدأ الآن
تبدأ أتمتة البحث في السجلات العامة بمفتاح API واحد. أنشئ حسابك واحصل على مفتاح CaptchaAI وابدأ اليوم بالتعامل مع كابتشا البوابات الحكومية آلياً.
اقرأ أيضاً
- ابدأ سريعاً مع CaptchaAI وحلّ أول كابتشا خلال دقائق
- حلّ reCAPTCHA v2 عبر الـ API خطوة بخطوة
- حلّ Cloudflare Turnstile عبر الـ API
- حلّ GeeTest v3 عبر الـ API