NanmiCoder/MediaCrawler · error · Exception
get ip error from proxy provider and code not 0 ...
Error message
get ip error from proxy provider and code not 0 ...
What it means
Raised when the KuaiDaiLi API responds with HTTP 200 but the JSON body's 'code' field is not 0 — the provider's application-level error channel. The provider's 'msg' field is logged before raising. Typical codes signal exhausted extraction quota for the time window, invalid order, parameter errors, or signature problems that passed the HTTP layer.
Source
Thrown at proxy/providers/kuaidl_proxy.py:127
if len(ip_cache_list) >= num:
return ip_cache_list[:num]
# If the quantity in cache is insufficient, get from IP provider to supplement, then store in cache
need_get_count = num - len(ip_cache_list)
self.params.update({"num": need_get_count})
ip_infos: List[IpInfoModel] = []
async with make_async_client() as client:
response = await client.get(self.api_base + uri, params=self.params)
if response.status_code != 200:
utils.logger.error(f"[KuaiDaiLiProxy.get_proxies] statuc code not 200 and response.txt:{response.text}, status code: {response.status_code}")
raise Exception("get ip error from proxy provider and status code not 200 ...")
ip_response: Dict = response.json()
if ip_response.get("code") != 0:
utils.logger.error(f"[KuaiDaiLiProxy.get_proxies] code not 0 and msg:{ip_response.get('msg')}")
raise Exception("get ip error from proxy provider and code not 0 ...")
proxy_list: List[str] = ip_response.get("data", {}).get("proxy_list")
for proxy in proxy_list:
proxy_model = parse_kuaidaili_proxy(proxy)
# expire_ts is relative time (seconds), needs to be converted to absolute timestamp
# Consider expired DELTA_EXPIRED_SECOND seconds in advance to avoid critical time usage failure
ip_info_model = IpInfoModel(
ip=proxy_model.ip,
port=proxy_model.port,
user=self.kdl_user_name,
password=self.kdl_user_pwd,
expired_time_ts=proxy_model.expire_ts + utils.get_unix_timestamp() - DELTA_EXPIRED_SECOND,
)
ip_key = f"{self.proxy_brand_name}_{ip_info_model.ip}_{ip_info_model.port}"
# Cache expiration time uses relative time (seconds), also needs to subtract buffer time
self.ip_cache.set_ip(ip_key, ip_info_model.model_dump_json(), ex=proxy_model.expire_ts - DELTA_EXPIRED_SECOND)
ip_infos.append(ip_info_model)View on GitHub (pinned to d6f7c5bb90)
Solutions
- Check the logged msg text — it names the exact provider error (quota, order status, param)
- If quota-exhaustion: wait for the window to reset (usually 60s) and retry with a smaller num
- Confirm the KuaiDaiLi order is active and has balance; re-enable it in the provider console
- Cap need_get_count so a single request never exceeds the order's per-request/per-minute limit and refill in batches
- Catch IpGetError at the pool level and fall back to serving cached IPs while the provider recovers
Example fix
// before
need_get_count = num - len(ip_cache_list)
self.params.update({"num": need_get_count})
// after (cap per-request quantity)
need_get_count = min(num - len(ip_cache_list), KDL_MAX_PER_REQUEST)
self.params.update({"num": need_get_count}) Defensive patterns
Strategy: retry
Try / catch
try:
infos = await kdl.get_proxies(num=need)
except Exception as e: # code != 0 path
msg = str(e)
if "code not 0" in msg:
await asyncio.sleep(60) # quota window reset
infos = await kdl.get_proxies(num=min(need, 5))
else:
raise Prevention
- Cap each request's num to the order's per-request limit
- Monitor the provider msg in logs to distinguish quota vs auth errors
- Keep a warm IP cache so provider outages degrade gracefully
When it happens
Trigger: GET /GetKdlIp succeeds at HTTP level but returns {'code': ..., 'msg': ...} — e.g. asking for more IPs than the order's per-minute allowance, order expired/not active, bad 'num' parameter (note need_get_count is computed as num - len(ip_cache_list) and could be large), or wrong signature producing a JSON error body with 200.
Common situations: Exhausting the daily/minute IP quota during a long crawl; KuaiDaili order expired or in arrears; requesting a big burst of IPs when the cache is empty (need_get_count == full pool size); signature generated with a stale timestamp.
Related errors
- not invalid kuaidaili proxy info
- {error_msg} (code: {error_code})
- not match kuaidaili proxy info
- get ip error from proxy provider and status code not 200 ...
- No crawler is running
AI-assisted analysis of NanmiCoder/MediaCrawler@d6f7c5bb90 (2026-08-15).
Data as JSON: /api/errors/91bba0ec8dc4fd35.
Report an issue: GitHub.