:param num: :return:
(self, num: int)
| 50 | self.ip_cache = IpCache() |
| 51 | |
| 52 | async def get_proxy(self, num: int) -> List[IpInfoModel]: |
| 53 | """ |
| 54 | :param num: |
| 55 | :return: |
| 56 | """ |
| 57 | |
| 58 | # Prioritize getting IP from cache |
| 59 | ip_cache_list = self.ip_cache.load_all_ip( |
| 60 | proxy_brand_name=self.proxy_brand_name |
| 61 | ) |
| 62 | if len(ip_cache_list) >= num: |
| 63 | return ip_cache_list[:num] |
| 64 | |
| 65 | # If the quantity in cache is insufficient, get from IP provider to supplement, then store in cache |
| 66 | need_get_count = num - len(ip_cache_list) |
| 67 | self.params.update({"num": min(need_get_count, 100)}) # Maximum 100 |
| 68 | ip_infos = [] |
| 69 | async with make_async_client() as client: |
| 70 | url = self.api_path + "?" + urlencode(self.params) |
| 71 | utils.logger.info(f"[WanDouHttpProxy.get_proxy] get ip proxy url:{url}") |
| 72 | response = await client.get( |
| 73 | url, |
| 74 | headers={ |
| 75 | "User-Agent": "MediaCrawler https://github.com/NanmiCoder/MediaCrawler", |
| 76 | }, |
| 77 | ) |
| 78 | res_dict: Dict = response.json() |
| 79 | if res_dict.get("code") == 200: |
| 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="", # WanDou HTTP does not require username password authentication |
| 87 | password="", |
| 88 | expired_time_ts=utils.get_unix_time_from_time_str( |
| 89 | ip_item.get("expire_time") |
| 90 | ), |
| 91 | ) |
| 92 | ip_key = f"WANDOUHTTP_{ip_info_model.ip}_{ip_info_model.port}" |
| 93 | ip_value = ip_info_model.model_dump_json() |
| 94 | ip_infos.append(ip_info_model) |
| 95 | self.ip_cache.set_ip( |
| 96 | ip_key, ip_value, ex=ip_info_model.expired_time_ts - current_ts |
| 97 | ) |
| 98 | else: |
| 99 | error_msg = res_dict.get("msg", "unknown error") |
| 100 | # Handle specific error codes |
| 101 | error_code = res_dict.get("code") |
| 102 | if error_code == 10001: |
| 103 | error_msg = "General error, check msg content for specific error information" |
| 104 | elif error_code == 10048: |
| 105 | error_msg = "No available package" |
| 106 | raise IpGetError(f"{error_msg} (code: {error_code})") |
| 107 | return ip_cache_list + ip_infos |
| 108 | |
| 109 |
nothing calls this directly
no test coverage detected