url.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import re
  2. from urllib.parse import urlparse, urlunparse, quote
  3. PORT_MAP = {
  4. "ftp": "21",
  5. "gopher": "70",
  6. "http": "80",
  7. "https": "443",
  8. "ws": "80",
  9. "wss": "443"
  10. }
  11. class Url:
  12. def __init__(self, url_str):
  13. self._url = urlparse(url_str)
  14. @staticmethod
  15. def new_url(url_str):
  16. try:
  17. return Url(url_str)
  18. except Exception as e:
  19. raise e
  20. def path(self):
  21. if not self._url.query:
  22. return self._url.path
  23. return f"{self._url.path}?{self._url.query}"
  24. def pathname(self):
  25. return self._url.path
  26. def protocol(self):
  27. return self._url.scheme
  28. def hostname(self):
  29. return self._url.hostname
  30. def host(self):
  31. if self._url.port:
  32. return f"{self._url.hostname}:{self._url.port}"
  33. return self._url.hostname
  34. def port(self):
  35. if self._url.port:
  36. return str(self._url.port)
  37. return PORT_MAP.get(self.protocol(), "")
  38. def hash(self):
  39. return self._url.fragment
  40. def search(self):
  41. return self._url.query
  42. def href(self):
  43. return urlunparse(self._url)
  44. def auth(self):
  45. if self._url.username or self._url.password:
  46. return f"{self._url.username}:{self._url.password or ''}"
  47. return ""
  48. @staticmethod
  49. def parse(url_str):
  50. return Url.new_url(url_str)
  51. @staticmethod
  52. def url_encode(url_str):
  53. if not url_str:
  54. return ""
  55. parts = url_str.split('/')
  56. encoded_parts = [quote(part, safe='') for part in parts]
  57. encoded_url = '/'.join(encoded_parts)
  58. encoded_url = encoded_url.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
  59. return encoded_url
  60. @staticmethod
  61. def percent_encode(uri):
  62. if not uri:
  63. return ""
  64. encoded_uri = quote(uri, safe='')
  65. encoded_uri = encoded_uri.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
  66. return encoded_uri
  67. @staticmethod
  68. def path_encode(path):
  69. if not path or path == "/":
  70. return path
  71. parts = path.split('/')
  72. encoded_parts = [quote(part, safe='') for part in parts]
  73. encoded_path = '/'.join(encoded_parts)
  74. encoded_path = encoded_path.replace("+", "%20").replace("*", "%2A").replace("%7E", "~")
  75. return encoded_path