ip_checker.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import socket
  2. from urllib.parse import urlparse
  3. import ipdb
  4. from utils.tools import resource_path
  5. class IPChecker:
  6. def __init__(self):
  7. self.db = ipdb.City(resource_path("utils/ip_checker/data/qqwry.ipdb"))
  8. self.url_host = {}
  9. self.host_ip = {}
  10. self.host_ipv_type = {}
  11. def get_host(self, url: str) -> str:
  12. """
  13. Get the host from a URL
  14. """
  15. if url in self.url_host:
  16. return self.url_host[url]
  17. host = urlparse(url).hostname or url
  18. self.url_host[url] = host
  19. return host
  20. def get_ip(self, url: str) -> str | None:
  21. """
  22. Get the IP from a URL
  23. """
  24. host = self.get_host(url)
  25. if host in self.host_ip:
  26. return self.host_ip[host]
  27. self.get_ipv_type(url)
  28. return self.host_ip.get(host)
  29. def get_ipv_type(self, url: str) -> str:
  30. """
  31. Get the IPv type of URL
  32. """
  33. host = self.get_host(url)
  34. if host in self.host_ipv_type:
  35. return self.host_ipv_type[host]
  36. try:
  37. addr_info = socket.getaddrinfo(host, None, socket.AF_UNSPEC, socket.SOCK_STREAM)
  38. ip = next((info[4][0] for info in addr_info if info[0] == socket.AF_INET6), None)
  39. if not ip:
  40. ip = next((info[4][0] for info in addr_info if info[0] == socket.AF_INET), None)
  41. ipv_type = "ipv6" if any(info[0] == socket.AF_INET6 for info in addr_info) else "ipv4"
  42. except socket.gaierror:
  43. ip = None
  44. ipv_type = "ipv4"
  45. self.host_ip[host] = ip
  46. self.host_ipv_type[host] = ipv_type
  47. return ipv_type
  48. def find_map(self, ip: str) -> tuple[str | None, str | None]:
  49. """
  50. Find the IP address and return the location and ISP
  51. :param ip: The IP address to find
  52. :return: A tuple of (location, ISP)
  53. """
  54. try:
  55. result = self.db.find_map(ip, "CN")
  56. if not result:
  57. return None, None
  58. location_parts = [
  59. result.get('country_name', ''),
  60. result.get('region_name', ''),
  61. result.get('city_name', '')
  62. ]
  63. location = "-".join(filter(None, location_parts))
  64. isp = result.get('isp_domain', None)
  65. return location, isp
  66. except Exception as e:
  67. print(f"Error on finding ip location and ISP: {e}")
  68. return None, None