@@ -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