Чести проблеми
Решения за най-често срещаните проблеми при използване на FourA API.
Празно или непълно съдържание
Симптом: API връща статус 200, но полето data е празно или в него липсва очакваното съдържание.
Причина: Целевата страница използва JavaScript за рендиране на съдържание след първоначалното зареждане.
Решение: Превключете от единичния endpoint към browser endpoint. Използвайте checkText, за да потвърдите, че съдържанието е заредено:
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/products",
"timeout_ms": 15000,
"checkText": "product-list"
}'
Забележка: browser endpoint връща съдържание в полето body (а не data).
403 Forbidden или страници за верификация
Симптом: API връща HTML, съдържащ страница за верификация или страница за отказан достъп.
Причина: Целевият сайт е разпознал заявката като автоматизирана и я е блокирал.
Решение: Използвайте proxy endpoint за автоматична ротация на IP:
curl -X POST https://eu.api.foura.ai/api/proxy/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"maxTries": 5,
"request": {
"method": "GET",
"url": "https://example.com/prices",
"unblocker": true
}
}'
Ако проблемът продължава, увеличете maxTries, за да дадете повече опити на ротацията на proxy.
Грешка 403, върната от целевия сайт, пристига като HTTP 200 с status: 403 в тялото. Грешка 403 при самата заявка, с хедър X-FourA-Limit, е различно нещо: вижте 403 Not in Your Plan.
Timeout грешки
Симптом: Заявките се провалят с timeout грешка.
Причина: Целевата страница се зарежда по-бавно от конфигурирания timeout.
Решение: Увеличете timeout_ms (по подразбиране е 15s за single, 30s за browser, 45s за proxy):
curl -X POST https://eu.api.foura.ai/api/browser/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://slow-site.com",
"timeout_ms": 60000
}'
За browser заявки проверете също дали стойността на checkText действително се появява на страницата. Правописна грешка ще провали повикването с checkText:<your text> not found.
403 Not in Your Plan
Симптом: API връща 403 с X-FourA-Limit header и reason от plan_limit_feature или plan_limit_premium.
{
"error": "Geo targeting (the exitCountries parameter) is not included in your plan (Free). Remove the parameter or upgrade.",
"reason": "plan_limit_feature",
"documentation": "https://foura.ai/prices"
}
Причина: Вашият план не включва извикания endpoint или изпратения параметър. plan_limit_feature покрива изключен endpoint и exitCountries без географско таргетиране; plan_limit_premium покрива exitClass: premium без премиум изходни точки. Целевият адрес изобщо не е бил потърсен и нищо не е изразходено.
Решение: Премахнете параметъра, извикайте endpoint, който планът ви включва, или надградете плана си. Разделът Limits & Features в Usage & Limits описва какво включва вашият план. Не повтаряйте същата заявка без промяна: заглавка Retry-After не е зададена, тъй като изчакването няма да промени резултата.
429 Too Many Requests
Симптом: API връща 429.
Причина: Една от две проверки е отказала извикването и отговорът посочва коя точно. Ако съдържа header X-FourA-Limit, е достигнат някой от лимитите на плана ви: едновременни заявки или заявки в минута за този endpoint, Browser заявки за деня или кредитите или трафика за отчетния период. Ако няма такъв header, споделеният за платформата минутен лимит за тази услуга е бил запълнен, което се дължи на трафика на FourA, а не на вашия.
Решение: Първо проверете X-FourA-Limit. Изчакайте, ако лимитът се нулира след няколко секунди, и спрете заявките, ако това не е така. Лимитите на плана, които се изчистват с изчакване, записват секундите в заглавката Retry-After и в retry_after_seconds; споделеният лимит ги записва в retryAfter:
import time
import requests
# Plan limits that come back in hours or days, not seconds.
STOP_ON = {"plan_limit_browser_daily", "plan_limit_credits", "plan_limit_bandwidth"}
def make_request(endpoint_url, payload, retries=3):
for i in range(retries):
resp = requests.post(
endpoint_url,
headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
json=payload
)
if resp.status_code == 429:
limit = resp.headers.get("X-FourA-Limit")
if limit in STOP_ON:
raise Exception(f"stopped by {limit}: {resp.json().get('error')}")
header = resp.headers.get("Retry-After")
body = resp.json()
wait = (
int(header) if header and header.isdigit()
else body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** i
)
time.sleep(wait)
continue
return resp
raise Exception("Rate limit not resolved after retries")
# Example: single request
make_request(
"https://eu.api.foura.ai/api/single/",
{"method": "GET", "url": "https://example.com"}
)
Ако заглавната част съдържа plan_limit_concurrency или plan_limit_rate, решението е да ограничите броя на отворените заявки и броя на стартираните в минута, вместо да опитвате по-агресивно повторно изпълнение. Незабавното повторно изпращане на отхвърлен пакет води до повторно отхвърляне на целия пакет. Отхвърлените заявки не се броят към лимита за минута, но ако продължат да пристигат с повече от два пъти над този лимит, отхвърлянията преминават в период на изчакване (cooldown): тялото на 429 съдържа cooldown: true и изисква да паузирате за 30 секунди (retry_after_seconds: 30). Паралелно изпълнение на заявки съдържа правилния модел, а Usage & Limits в Dashboard показва броячите ви в реално време до зададените лимити.
503 Service Unavailable
Симптом: API връща статус 503.
Причина: Това се случва в два случая:
- Услугата е с изчерпан капацитет. FourA вече изпълнява максималния допустим брой едновременни заявки на този engine, изчислен за целия трафик, а не само за вашия.
Service at capacityв полетоerror. Обикновено се изчиства за секунди. - Услугата е временно деактивирана. Извършва се техническа поддръжка.
Service disabledв полетоerror.
И двата случая включват поле retryAfter в отговора. Нито един от тях не е лимит на плана: лимитите на собствения ви план винаги връщат заглавна част X-FourA-Limit при статус 403 или 429, никога при 503.
Решение: Изчакайте retryAfter секунди, след което опитайте отново:
import time
import requests
def make_request_with_retry(endpoint_url, payload, retries=3):
for i in range(retries):
resp = requests.post(
endpoint_url,
headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
json=payload
)
if resp.status_code in (429, 503):
header = resp.headers.get("Retry-After")
body = resp.json()
wait = (
int(header) if header and header.isdigit()
else body.get("retry_after_seconds") or body.get("retryAfter") or 2 ** i
)
time.sleep(wait)
continue
return resp
raise Exception("Request not resolved after retries")
Грешка 503 при запълнен капацитет означава, че FourA е зает, така че временното изчакване и повторният опит са пълното решение. Ако заявките биват отказвани с 429 и X-FourA-Limit, проблемът е от ваша страна: намалете броя на паралелните заявки във вашия pipeline.
504 Upstream Timeout
Симптом: API връща 504 с {"error": "Upstream timeout"}.
Причина: Обработката не приключи в рамките на зададения времеви лимит за заявката. Бавен краен сървър, начално решаване на challenge или много голяма страница могат да доведат до това. Проблемът не е във вашия ключ, параметри или proxy.
Решение: Дайте повече време на извикването или опитайте отново. FourA изчаква стойността на вашия timeout_ms плюс малък допълнителен марж, така че увеличаването му реално удължава времето за изчакване:
{
"url": "https://slow-site.com/report",
"timeout_ms": 90000
}
За /api/auto/ към защитена цел първото студено извикване може да отнеме десетки секунди. Неговият timeout_ms покрива цялата поредица от опити и приема до 180000.
Когато самият /api/auto/ изчерпи този лимит от време, извикването все пак връща HTTP 200. В тялото се съдържа error, което започва с time budget exhausted, а status обикновено е 504 (по-ранен неуспешен опит може да остави своя собствен статус там). Увеличете timeout_ms или опитайте отново.
502 Upstream Unavailable
Симптом: API връща 502 с {"error": "Upstream unavailable"} или 503 с {"error": "Backend service unavailable"}.
Причина: FourA се свърза със своя собствен енджин, но не успя да използва отговора, обикновено поради рестартиране на инстанция.
Решение: Опитайте отново с кратък backoff. И двата случая се класифицират като service_error, а се таксува само success, така че повторният опит не ви струва нищо допълнително. Ако продължи повече от минута или две, проверете страницата за статус.
401 Грешки при автентикация
Симптом: Всяка заявка връща 401 Unauthorized.
Контролен списък:
- Проверете дали header е
X-API-Key: YOUR_API_KEY(а неAuthorization: BearerилиApi-Key) - Проверете за излишни интервали или нови редове във вашия API ключ
- Създайте нов ключ от Dashboard, ако текущият е компрометиран
400 Target Resolves to a Private or Reserved IP
Симптом: API връща 400 с Refusing to fetch <target>: target resolves to a private or reserved IP range, преди заявката да напусне FourA.
Причина: Вашият url се резолва към частен, loopback или резервиран IP диапазон (RFC 5735, RFC 6598 или IPv6 резервирани блокове). FourA отхвърля тези цели, за да не бъде използвана мрежата за достъп до вътрешни хостове.
Решение: Извикайте публичен URL. Ако тествате, използвайте публична цел като https://example.com или https://httpbin.org/get. Ако желаната цел е услуга, която управлявате, първо я осигурете на публичен hostname.
{ "error": "Refusing to fetch <target>: target resolves to a private or reserved IP range. The FourA scraping API only forwards requests to public internet hosts." }
Хостнейм, който не може да бъде намерен, не се отхвърля. Заявката се връща като HTTP 200 с status: 0 и причината (could not resolve <host>: <reason>), както при всяка цел, която FourA не може да достигне, и не се таксува.
no_eligible_proxy при използване на exitCountries
Симптом: Заявка към /api/proxy/ с exitCountries връща HTTP 200 с JSON грешка:
{
"error": "No eligible proxy found for exit countries: CZ, GB",
"code": "no_eligible_proxy",
"details": { "exitCountries": ["CZ", "GB"] },
"total": 0.084
}
Причина: Текущият proxy pool няма работещ изход, чиято видима за целта държава съвпада с вашия allowlist. FourA никога не превключва към незаявена държава, когато зададете exitCountries.
Решение: Запазете заявения обхват и опитайте отново по-късно. Pool-ът се обновява приблизително на всеки десет минути, така че държава, която няма съвпадение в момента, често получава такова в рамките на час.
import time, requests
def fetch_scoped(url, countries, max_attempts=6, wait_sec=600):
for _ in range(max_attempts):
r = requests.post("https://eu.api.foura.ai/api/proxy/",
headers={"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"},
json={"maxTries": 5, "exitCountries": countries,
"request": {"method": "GET", "url": url}}).json()
if r.get("code") == "no_eligible_proxy":
time.sleep(wait_sec)
continue
return r
raise RuntimeError(f"no eligible exit in {countries} after {max_attempts} attempts")
Разширявайте списъка с държави само ако изискването за държава във вашия работен процес действително се е променило. Тихите превключвания към други държави могат да нарушат гео-зависимата логика на следващите етапи.
Тялото на отговора се връща като нечетим текст
Симптом: data (или body) в отговора съдържа mojibake или нечетими символи, когато целта използва кодиране, различно от UTF-8.
Причина: По подразбиране FourA автоматично декодира телата на отговорите към UTF-8 въз основа на заглавката Content-Type на целта или HTML таг <meta charset>. Ако целта подава невярна информация за кодирането си, получавате нечетим текст.
Решение: За двоични данни (изображения, protobuf, необработено аудио), задайте returnBuffer: true в заявката. Тогава Single и Proxy връщат data като обект, съдържащ суровите байтове, {"type": "Buffer", "data": [<byte values>]}, без прилагане на транскодиране на кодировката.
{
"method": "GET",
"url": "https://example.com/image.png",
"returnBuffer": true
}
За текстови цели, които декларират грешно своя charset, декодирайте суровите байтове сами: извлечете с returnBuffer: true, прочетете байтовите стойности в data.data, след което ги декодирайте с правилния charset.
Неочакван HTML вместо JSON
Симптом: Очаквахте JSON от целевия сайт, но получихте HTML.
Причина: Целевата страница може да връща различно съдържание в зависимост от headers.
Решение: Добавете Accept header и активирайте unblocker за реалистични browser headers:
curl -X POST https://eu.api.foura.ai/api/single/ \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "GET",
"url": "https://api.example.com/data",
"headers": [["Accept", "application/json"]],
"unblocker": true
}'
Можете също да зададете tryJsonData на true, за да може FourA автоматично да парсне JSON отговорите.
Тялото е challenge страница, а не съдържание
Симптом: Заявката е успешна, status е 200, но data (или body) представлява проверка за ботове вместо желаната страница.
Причина: Целевият сайт е стартирал проверка за ботове, която FourA е срещнал, но не е успял да премине. Отговорът показва това: Single и Proxy връщат defense с solved: false, а Browser връща defenseSolved: false с доставчика в defenses.present.
Решение: Проверете първо defense.vendor, след което ескалирайте. Опитайте различен профил на браузъра в Single, преминете към Proxy за различен изходен IP адрес или използвайте Browser, за да се изпълни JavaScript. Пълна справка за полетата и списък с доставчици: Site checks.
Добавете validate.data.accept подниз, който се съдържа само в реалната страница. Страница за проверка, която FourA разпознава, никога не е успешна: тя се връща с X-FourA-Check-Page header и не се таксува. Без validate страница за проверка, която FourA не разпознава, върната с HTTP 200, се счита за успешна и ще разберете за това на по-късен етап, а не при самото извикване.
Все още срещате проблеми?
Ако никое от горните решения не помогне:
- Проверете status page за текущи инциденти
- Прегледайте метриките за заявките си в Dashboard
- Свържете се с поддръжката на support@foura.ai с детайли за вашата заявка (включете
X-FourA-Request-Idот неуспешния отговор)
Следващи стъпки
- Error Handling: Справка за кодовете за грешка на API
- Rate Limits: Всички лимити на планове и платформи с полета
- Request Outcomes: Как резултатите класифицират случилото се
- Site checks: Какво показва полето
defense - Choosing the Right Endpoint: Изберете най-добрия подход за вашата цел
- Dashboard Overview: Мониторинг на вашите заявки