| 34 | |
| 35 | |
| 36 | class JiSuHttpProxy(ProxyProvider): |
| 37 | |
| 38 | def __init__(self, key: str, crypto: str, time_validity_period: int): |
| 39 | """ |
| 40 | JiSu HTTP proxy IP implementation |
| 41 | :param key: Extraction key value (obtain after registering on the official website) |
| 42 | :param crypto: Encryption signature (obtain after registering on the official website) |
| 43 | """ |
| 44 | self.proxy_brand_name = "JISUHTTP" |
| 45 | self.api_path = "https://api.jisuhttp.com" |
| 46 | self.params = { |
| 47 | "key": key, |
| 48 | "crypto": crypto, |
| 49 | "time": time_validity_period, # IP usage duration, supports 3, 5, 10, 15, 30 minute validity |
| 50 | "type": "json", # Data result is json |
| 51 | "port": "2", # IP protocol: 1:HTTP, 2:HTTPS, 3:SOCKS5 |
| 52 | "pw": "1", # Whether to use account password authentication, 1: yes, 0: no, no means whitelist authentication; default is 0 |
| 53 | "se": "1", # Whether to show IP expiration time when returning JSON format, 1: show, 0: don't show; default is 0 |
| 54 | } |
| 55 | self.ip_cache = IpCache() |
| 56 | |
| 57 | async def get_proxy(self, num: int) -> List[IpInfoModel]: |
| 58 | """ |
| 59 | :param num: |
| 60 | :return: |
| 61 | """ |
| 62 | |
| 63 | # Prioritize getting IP from cache |
| 64 | ip_cache_list = self.ip_cache.load_all_ip(proxy_brand_name=self.proxy_brand_name) |
| 65 | if len(ip_cache_list) >= num: |
| 66 | return ip_cache_list[:num] |
| 67 | |
| 68 | # If the quantity in cache is insufficient, get from IP provider to supplement, then store in cache |
| 69 | need_get_count = num - len(ip_cache_list) |
| 70 | self.params.update({"num": need_get_count}) |
| 71 | ip_infos = [] |
| 72 | async with make_async_client() as client: |
| 73 | url = self.api_path + "/fetchips" + '?' + urlencode(self.params) |
| 74 | utils.logger.info(f"[JiSuHttpProxy.get_proxy] get ip proxy url:{url}") |
| 75 | response = await client.get(url, headers={ |
| 76 | "User-Agent": "MediaCrawler https://github.com/NanmiCoder/MediaCrawler", |
| 77 | }) |
| 78 | res_dict: Dict = response.json() |
| 79 | if res_dict.get("code") == 0: |
| 80 | data: List[Dict] = res_dict.get("data") |
| 81 | current_ts = utils.get_unix_timestamp() |
| 82 | for ip_item in data: |
| 83 | ip_info_model = IpInfoModel( |
| 84 | ip=ip_item.get("ip"), |
| 85 | port=ip_item.get("port"), |
| 86 | user=ip_item.get("user"), |
| 87 | password=ip_item.get("pass"), |
| 88 | expired_time_ts=utils.get_unix_time_from_time_str(ip_item.get("expire")), |
| 89 | ) |
| 90 | ip_key = f"JISUHTTP_{ip_info_model.ip}_{ip_info_model.port}_{ip_info_model.user}_{ip_info_model.password}" |
| 91 | ip_value = ip_info_model.json() |
| 92 | ip_infos.append(ip_info_model) |
| 93 | self.ip_cache.set_ip(ip_key, ip_value, ex=ip_info_model.expired_time_ts - current_ts) |
no outgoing calls
no test coverage detected