Защо proxy заявката изчерпа опитите си
Проблемът
POST /api/proxy/ извикване се връща с грешка и без данни. Съобщението е кратко и винаги в същия формат:
{
"error": "Download maxTry limit reached",
"total": 34.812,
"request": { "...": "..." }
}
Това изречение звучи по един и същ начин, независимо дали всеки изходен възел е бил блокиран, всеки изходен възел не е работил или FourA е извлякъл реалната страница при почти всеки опит, а вашите собствени validate правила са я отхвърлили. Тези три случая изискват напълно противоположни решения.
Отговорът: attemptReport
Всяко Proxy извикване, което е изпълнило своите опити и се е провалило, съдържа attemptReport обект заедно с грешката, включително и такова, което е завършило с "error": "Timeout". Име на хост, което не може да бъде резолвнато, се проваля преди какъвто и да е опит, с status: 0 и без отчет. Той отчита с какво всъщност са се сблъскали опитите:
{
"error": "Download maxTry limit reached",
"attemptReport": {
"total": 25,
"noResponse": 0,
"defense": 0,
"contentRejected": 25,
"statusRejected": 0,
"other": 0,
"vendors": [],
"profilesTried": ["default"],
"summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
},
"total": 34.812
}
Низът error е умишлено непроменен, така че клиент, който прави съпоставка по него, да продължи да работи. Прочетете attemptReport.summary за отговор в един ред или броячите, когато искате да разклонявате логиката според тях.
Полета
| Поле | Тип | Какво брои |
|---|---|---|
total |
integer | Направени опити |
noResponse |
integer | Изходната точка не отговори или сайтът не отговори навреме |
defense |
integer | Сайтът отговори и при този отговор беше разпознат доставчик на защита срещу ботове |
contentRejected |
integer | HTTP 200, без защита срещу ботове, отхвърлено единствено от вашето validate.data |
statusRejected |
integer | Сайтът отговори, без защита срещу ботове, отхвърлено от вашето validate.status |
other |
integer | Получен е отговор и нито едно от горните не е налице |
vendors |
string[] | Всеки доставчик на защита срещу ботове, разпознат някъде в рамките на задачата |
profilesTried |
string[] | Профилите на браузъра, които задачата изпрати, подредени по първо използване. default означава, че заявката е изпратена точно както сте я написали. |
summary |
string | Едно изречение, съставено от броячите. Безопасно за записване в логове или показване на потребител. |
Разчитане
contentRejected е с висока стойност
Страниците са получени. Вашето правило validate.data не съвпада с тях.
Това е проблемът, който можете да поправите сами, и е този, който всеки друг сигнал скрива: заявките изглеждат като неуспешни във всяка метрика, а FourA през цялото време е доставял реално съдържание. Изтеглете страницата веднъж през POST /api/single/ без никакво validate, вижте какво всъщност се връща и пренапишете правилото спрямо него.
Честа причина е прилагането на едно правило към набор от страници, които не са напълно еднакви. Селектор, който съществува на страници с новини, но не и на страници с видеоклипове, се проваля всеки път, когато попадне на страница с видео, непрекъснато, при пълна цена.
statusRejected е с висока стойност
Сайтът отговори и вашето правило validate.status върна отказ. Ако тези статуси са 401, 403, 429 или 503, сайтът отказва достъп на клиента, вместо да казва, че страницата липсва. Опитайте:
- Друг браузърен профил (
browser,os,versionвъв вътрешния обектrequest) exitCountries, ако съдържанието е ограничено по регионPOST /api/browser/, ако отказът изисква JavaScript за преодоляване
defense е с висока стойност
В отговорите беше разпозната защита срещу ботове, а vendors посочва коя точно. Вижте Site checks за това какво FourA преодолява в момента и за какво само докладва. Ако доставчикът не е сред тези, които се преодоляват на тази крайна точка, преместете извикването към POST /api/browser/ или POST /api/auto/.
noResponse е с висока стойност
Изходните точки изобщо не отговориха, така че нищо не беше научено за целта. Увеличете maxTries, увеличете timeout_ms и проверете дали URL адресът се разрешава от публичния интернет.
other е с висока стойност
Сайтът отговори със статус, не беше разпозната защита срещу ботове и опитът беше неуспешен по друга причина, като например правило validate.headers. Цел, която е по-бавна от вашето timeout_ms, се отчита в noResponse.
Ротация на профила на браузъра
Когато даден сайт отхвърли браузъра, изпратен от FourA, Proxy спира да настоява за него и опитва друга фамилия от публичния каталог с профили. Това не струва допълнителен опит: ротацията променя това, което изпраща повторният опит, а не дали изобщо се извършва такъв.
Proxy също така запомня за всеки сайт фамилията, която последно е сработила там, след като сайтът е отказал браузъра по подразбиране. Следващ request към този сайт може да стартира с тази фамилия още от първия си опит, като FourA преминава към следващата фамилия, щом сайтът започне да отхвърля и нея. Мобилен браузър се запомня само за сайт, който връща JSON.
profilesTried показва как се случва това. Един запис означава, че всеки опит е изпратил същия браузър: default е подаденият request, а catalogue id е фамилията, която FourA вече е научил за този сайт. Няколко записа означават, че ротацията е била изпълнена и сайтът е отхвърлил всеки от тях, което е различна ситуация от това изобщо да не е имало ротация.
При успешен Proxy response полето profile се появява само когато ротацията е избрала браузър, който не сте заявили:
{
"status": 200,
"data": "<!doctype html>...",
"proxy": "A1B2C3",
"profile": "...",
"total": 4.108
}
Стойността е catalogue id от GET /api/profiles. Липсата му означава, че заявката е изпратена точно както е написана. Наличието му означава, че браузърът, който е сработил, не е бил този, който сте въвели, така че подайте това id обратно като profile при следващи извиквания, вместо да повтаряте неуспешния. Playground в таблото прави това вместо вас чрез Carry.
Изрично зададен profile, browser, os или version във вашата заявка никога не се презаписва. Същото важи и за заявка, съдържаща ваш собствен User-Agent или Cookie header, тъй като clearance е обвързан с подписа, чрез който е получен.
Четене в код
import requests
API = "https://eu.api.foura.ai"
H = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}
r = requests.post(f"{API}/api/proxy/", headers=H, json={
"maxTries": 5,
"request": {
"method": "GET",
"url": "https://example.com/product/42",
"validate": {"data": {"accept": ["Add to cart"]}},
},
}).json()
if "error" in r:
rep = r.get("attemptReport", {})
print(rep.get("summary", r["error"]))
if rep.get("contentRejected", 0) > rep.get("total", 0) / 2:
# The pages arrived. The validate rule is what threw them away.
raise SystemExit("validate.data did not match the real page")
if rep.get("defense", 0):
print("bot check met:", ", ".join(rep.get("vendors", [])))
Свързани
- API Endpoints: Пълна документация за Proxy request и response
- Проверки на сайтове: Доставчици,
defenseи повторно използване на clearance - Резултати от заявки: Как се класифицира и таксува отхвърлен response
- Чести проблеми: Други проблеми и техните решения
- Избор на правилния Endpoint: Кога Proxy не е правилният инструмент