request의 validate 규칙이 이제 모든 outcome의 분류 방식을 결정합니다. 403을 허용 가능한 것으로 선언하면, 전달된 403은 success로 간주되어 success로 과금되며, 200과 함께 Activity 피드에 기록됩니다.
사소해 보일 수 있습니다. 하지만 이는 대규모 스크래핑 정확도를 측정하는 방식을 완전히 바꿉니다.
How It Works
FourA로 보내는 모든 request는 과금 및 분석을 결정하는 7가지 outcome 중 하나를 받게 됩니다. 오직 success만 과금 대상입니다. 나머지는 실패의 원인에 따라 다음과 같이 나뉩니다.
- 대상 사이트가 거부했거나 에러 body를 반환한 경우의
application_fail및application_error - 보낸 request의 형식이 잘못된 경우의
client_error - 당사 측의 문제로 request가 차단된 경우의
service_fail,service_error및rate_limit
이번 변경 전에는 성공이 오직 한 가지, 즉 HTTP 200만을 의미했습니다. 403이 원하던 response라는 것을 알고 있었더라도 403은 항상 application_fail이었습니다. (일부 스포츠 데이터 API는 지역 제한된 마켓에 대해 403을 반환하며, 이는 여러분의 코드가 대기하는 신호이기도 합니다.)
이제는 validate 블록이 이를 결정합니다. request는 실행 중에 정의된 규칙을 실행합니다. response가 이 규칙을 충족하면 outcome은 success가 됩니다.
curl -X POST "https://eu.api.foura.ai/v1/request" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/api/feed",
"unblocker": true,
"validate": {
"status": { "accept": [200, 403] },
"data": { "fail": ["captcha", "Access Denied"] }
}
}'
이는 200과 403을 유효한 상태 코드로 취급합니다. body에 CAPTCHA 마커나 access-denied 문자열이 포함되어 있으면 request는 실패합니다. 그 외의 모든 경우는 success가 됩니다.
기억해야 할 두 가지 규칙은 다음과 같습니다.
validate가 없으면 동작은 변경되지 않습니다. validation을 선언하지 않은 request는 여전히 HTTP 200에 대해서만 과금됩니다. 직접 선택하여 적용하는 방식입니다.validate는 양방향으로 작동합니다. accept 규칙은 통과시키고, fail 규칙은 거부합니다. 이 규칙들은 조합됩니다. 따라서[200, 403]을 허용하면서도 body에 잘못된 콘텐츠가 포함되어 있을 때 실패하도록 처리할 수 있습니다.
Impact
이번 변화는 대상 사이트가 실제로 원하는 non-200 response를 반환하는 팀에게 가장 중요합니다.
매일 확인되는 request의 예시는 다음과 같습니다.
- 지역 제한된 마켓에 대해 403을 반환하는 스포츠 데이터 API (여전히 유용한 데이터이며, success로 기록할 가치가 있음)
- SKU가 품절되었을 때 404를 반환하는 이커머스 검색 endpoint (코드가 읽어야 하는 신호이며, 실패가 아님)
- 206을 반환하는 스트리밍 및 부분 콘텐츠 API
변경 전에는 이러한 팀들이 당사의 Activity 로그 외에 자체적인 기록 관리 작업을 별도로 수행해야 했습니다. 그들이 정의한 성공과 당사의 정의가 일치하지 않았기 때문에 outcome 열을 신뢰할 수 없었습니다. 또한 실제로 중요하게 생각하지 않는 숫자를 기준으로 요금이 부과되었습니다.
이제 해당 열은 실제 상황을 반영합니다. Dashboard의 Activity 탭은 당사가 추측한 것이 아니라 여러분이 성공으로 정의한 내용을 보여줍니다. 과금 총액은 여러분이 직접 집계한 수치와 일치하게 됩니다 (참고: 이 변경 사항은 향후 데이터에만 적용되므로, 이전 Activity 행은 원래의 분류를 유지합니다).
스크래핑 작업에 미치는 실질적인 효과는 파이프라인과 인보이스 간의 대조 단계가 줄어든다는 점입니다. 이미 사후에 response body에 대한 validation을 실행하고 있었다면, 해당 규칙을 request 자체로 이동하여 API 외부에서 별도의 통과/실패 규칙을 관리할 필요가 없어집니다. 서로 일치하지 않던 두 개의 기준 대신, request가 데이터 세트에 포함될 자격이 있는지 판단하는 단 하나의 정의만 남게 됩니다.
하지만 안전장치는 그대로 유지했습니다. validate 블록을 전달하지 않으면 아무것도 변경되지 않습니다. 분류기는 기존의 "200은 성공을 의미함" 방식으로 돌아가므로, 어제 작동했던 request는 오늘도 동일하게 작동합니다.
For Power Users
validate는 독립적으로 실행되는 세 가지 규칙 세트인 status, headers, data를 허용합니다. 각 세트는 선택 사항으로 accept 및 fail 목록을 가집니다.
curl -X POST "https://eu.api.foura.ai/v1/request" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/product/9876",
"followRedirects": 5,
"unblocker": true,
"validate": {
"status": { "accept": [200, 304] },
"headers": { "accept": { "content-type": "application/json" } },
"data": { "accept": ["\"price\":"], "fail": ["maintenance", "captcha"] }
}
}'
이는 다음을 요구합니다.
- status가 200 또는 304여야 함
- response가 JSON content-type을 나타내야 함
- body에 price 필드가 포함되어야 함
- body에 점검 공지나 captcha 트랩이 포함되지 않아야 함
규칙 중 하나라도 실패하면 outcome은 application_fail이 됩니다. 모든 규칙을 통과하면 success가 됩니다. 분류기는 request 자체 내부에서 실행되므로, 별도의 validation 단계에서 발생하는 왕복 비용(round trip)을 줄일 수 있습니다.
followRedirects와 결합하면 최대 5번의 홉을 추적한 다음 최종 response를 검증합니다. 정상적인 URL에서 CAPTCHA 게이트로 유도하는 낚시성 리디렉션이 발생하더라도, 데이터 세트를 오염시키지 않고 깔끔하게 실패 처리됩니다.
당사에서 직접 스크래퍼를 운영하며 얻은 팁을 드리자면, data.fail 패턴을 적극적으로 선언하는 것이 좋습니다. 내부에 CAPTCHA가 포함된 200 OK는 보안이 적용된 사이트에서 가장 흔하게 발생하는 무음 실패(silent failure) 모드입니다. 상태 코드가 아닌 body를 신뢰할 수 있는 기준으로 취급하세요.
전체 스키마는 request reference에서 모든 validate 필드와 각 필드의 조합 방식을 확인할 수 있습니다.
What's Next
당사는 data에 대한 regex 매처, 구조화된 JSON-path predicate, 더 유연한 header 매칭 등 더 풍부한 규칙 프리미티브를 준비하고 있습니다. 원칙은 동일합니다. 여러분이 성공의 기준을 선언하면, API는 request부터 인보이스에 이르기까지 이를 엔드투엔드로 준수합니다.
스크래퍼가 중단되면 명확하게 표시되어야 합니다. 그리고 직접 작성한 규칙에 따라 정상적으로 작동할 때, 비로소 그 수치를 진정으로 신뢰할 수 있게 됩니다.