Skip to content

Commit 8dccd96

Browse files
committed
chore: use iplark as default ip-library
1 parent 5ba981c commit 8dccd96

File tree

1 file changed

+65
-18
lines changed

1 file changed

+65
-18
lines changed

subscribe/location.py

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -817,20 +817,31 @@ def random_delay(min_delay: float = 0.01, max_delay: float = 0.5):
817817
time.sleep(random.uniform(min_delay, max_delay))
818818

819819

820-
def check_residential(proxy: dict, port: int, api_key: str = "", use_ipinfo: bool = True) -> ProxyQueryResult:
820+
def check_residential(proxy: dict, port: int, api_key: str = "", ip_library: str = "iplark") -> ProxyQueryResult:
821821
"""
822822
Check if a proxy is residential by making a request through it
823823
824824
Args:
825825
proxy: The proxy information dict
826826
port: The port of the proxy
827827
api_key: Optional API key for ipapi.is. Uses free tier if not provided
828-
use_ipinfo: Whether to use ipinfo.io instead of ipapi.is, defaults to True
828+
ip_library: IP query provider, supported: iplark/ipinfo/ipapi (default: iplark)
829829
830830
Returns:
831831
ProxyQueryResult: Complete proxy query result
832832
"""
833833

834+
def _get_provider(library: str) -> str:
835+
aliases = {"iplark": "iplark", "ipinfo": "ipinfo", "ipapi": "ipapi"}
836+
name = utils.trim(library).lower()
837+
if name in aliases:
838+
return aliases[name]
839+
840+
if name:
841+
logger.warning(f"Unsupported ip library: {name}, fallback to iplark")
842+
843+
return "iplark"
844+
834845
def _get_ipapi_url(key: str = "") -> str:
835846
url, key = "https://api.ipapi.is", utils.trim(key)
836847
if key:
@@ -859,6 +870,50 @@ def _get_ipinfo_url(port: int, name: str) -> str:
859870
# Now get detailed information using the IP
860871
return f"https://ipinfo.io/widget/demo/{ip}"
861872

873+
def _get_iplark_url() -> str:
874+
return "https://iplark.com/ipapi/public/ipinfo"
875+
876+
def _build_query_url(provider: str, port: int, name: str, api_key: str) -> tuple[str, str]:
877+
if provider == "ipinfo":
878+
url = _get_ipinfo_url(port=port, name=name)
879+
if url:
880+
return url, provider
881+
882+
logger.warning(f"Fallback to ipapi for proxy {name} because ipinfo URL generation failed")
883+
return _get_ipapi_url(key=api_key), "ipapi"
884+
885+
if provider == "ipapi":
886+
return _get_ipapi_url(key=api_key), provider
887+
888+
return _get_iplark_url(), "iplark"
889+
890+
def _extract_provider_data(provider: str, response: dict) -> tuple[dict, str, str, str]:
891+
data, country_code, company_type, asn_type = {}, "", "", ""
892+
893+
if provider == "ipinfo":
894+
data = response.get("data", {}) if isinstance(response, dict) else {}
895+
country_code = data.get("country", "")
896+
company_type = data.get("company", {}).get("type", "")
897+
asn_type = data.get("asn", {}).get("type", "")
898+
elif provider == "ipapi":
899+
data = response if isinstance(response, dict) else {}
900+
country_code = data.get("location", {}).get("country_code", "")
901+
company_type = data.get("company", {}).get("type", "")
902+
asn_type = data.get("asn", {}).get("type", "")
903+
else:
904+
data = response if isinstance(response, dict) else {}
905+
906+
country_code = data.get("country_code", "")
907+
node_type = utils.trim(data.get("type", "")).lower()
908+
if node_type == "isp":
909+
company_type, asn_type = "isp", "isp"
910+
elif node_type == "business":
911+
company_type, asn_type = "business", "business"
912+
else:
913+
company_type, asn_type = "hosting", "hosting"
914+
915+
return data, utils.trim(country_code).upper(), utils.trim(company_type).lower(), utils.trim(asn_type).lower()
916+
862917
name = proxy.get("name", "")
863918
result = ProxyInfo(name=name)
864919

@@ -870,32 +925,24 @@ def _get_ipinfo_url(port: int, name: str) -> str:
870925
random_delay()
871926

872927
try:
873-
url = ""
874-
if use_ipinfo:
875-
url = _get_ipinfo_url(port=port, name=name)
876-
928+
url, provider = _build_query_url(provider=_get_provider(ip_library), port=port, name=name, api_key=api_key)
877929
if not url:
878-
url = _get_ipapi_url(key=api_key)
879-
use_ipinfo = False
930+
logger.warning(f"Failed to build query URL for proxy {name} with ip-library: {provider}")
931+
return ProxyQueryResult(proxy=proxy, result=result, success=False)
880932

881933
# Call API for IP information through the proxy
882934
success, response = make_proxy_request(port=port, url=url, max_retries=2, timeout=12)
883935

884936
# Parse data from response
885937
if success:
886938
try:
887-
data = response.get("data", {}) if use_ipinfo else response
888-
889-
# Extract country code from data
890-
if use_ipinfo:
891-
country_code = data.get("country", "")
892-
else:
893-
country_code = data.get("location", {}).get("country_code", "")
939+
data, country_code, company_type, asn_type = _extract_provider_data(provider, response)
894940

895-
result.country = ISO_TO_CHINESE.get(country_code, "") if country_code else ""
941+
if country_code:
942+
result.country = ISO_TO_CHINESE.get(country_code, "")
896943

897-
company_type = data.get("company", {}).get("type", "")
898-
asn_type = data.get("asn", {}).get("type", "")
944+
if not result.country:
945+
result.country = utils.trim(data.get("country_zh", "") or data.get("country", ""))
899946

900947
# Check if it's residential (both company and asn type should be "isp")
901948
if company_type == "isp" and asn_type == "isp":

0 commit comments

Comments
 (0)