返回 douyin-downloader
url_parser.py
根目录 / core / url_parser.py
1 import re
2 from typing import Any, Dict, Optional
3
4 from utils.logger import setup_logger
5 from utils.validators import parse_url_type
6
7 logger = setup_logger("URLParser")
8
9
10 class URLParser:
11 @staticmethod
12 def parse(url: str) -> Optional[Dict[str, Any]]:
13 url_type = parse_url_type(url)
14 if not url_type:
15 logger.error("Unsupported URL type: %s", url)
16 return None
17
18 result = {
19 "original_url": url,
20 "type": url_type,
21 }
22
23 if url_type == "video":
24 aweme_id = URLParser._extract_video_id(url)
25 if aweme_id:
26 result["aweme_id"] = aweme_id
27
28 elif url_type == "user":
29 sec_uid = URLParser._extract_user_id(url)
30 if sec_uid:
31 result["sec_uid"] = sec_uid
32
33 elif url_type == "collection":
34 mix_id = URLParser._extract_mix_id(url)
35 if mix_id:
36 result["mix_id"] = mix_id
37
38 elif url_type == "gallery":
39 note_id = URLParser._extract_note_id(url)
40 if note_id:
41 result["note_id"] = note_id
42 result["aweme_id"] = note_id
43
44 elif url_type == "music":
45 music_id = URLParser._extract_music_id(url)
46 if music_id:
47 result["music_id"] = music_id
48
49 elif url_type == "live":
50 room_id = URLParser._extract_room_id(url)
51 if room_id:
52 result["room_id"] = room_id
53
54 return result
55
56 @staticmethod
57 def _extract_video_id(url: str) -> Optional[str]:
58 match = re.search(r"/video/(\d+)", url)
59 if match:
60 return match.group(1)
61
62 match = re.search(r"modal_id=(\d+)", url)
63 if match:
64 return match.group(1)
65
66 return None
67
68 @staticmethod
69 def _extract_user_id(url: str) -> Optional[str]:
70 match = re.search(r"/user/([A-Za-z0-9_-]+)", url)
71 if match:
72 return match.group(1)
73 return None
74
75 @staticmethod
76 def _extract_mix_id(url: str) -> Optional[str]:
77 match = re.search(r"/collection/(\d+)", url)
78 if not match:
79 match = re.search(r"/mix/(\d+)", url)
80 if match:
81 return match.group(1)
82 return None
83
84 @staticmethod
85 def _extract_note_id(url: str) -> Optional[str]:
86 match = re.search(r"/(?:note|gallery|slides)/(\d+)", url)
87 if match:
88 return match.group(1)
89 return None
90
91 @staticmethod
92 def _extract_music_id(url: str) -> Optional[str]:
93 match = re.search(r"/music/(\d+)", url)
94 if match:
95 return match.group(1)
96 return None
97
98 @staticmethod
99 def _extract_room_id(url: str) -> Optional[str]:
100 # 直播链接形态:
101 # https://live.douyin.com/123456789
102 # https://www.douyin.com/follow/live/123456789
103 match = re.search(r"/live/(\d+)", url)
104 if match:
105 return match.group(1)
106 match = re.search(r"live\.douyin\.com/(\d+)", url)
107 if match:
108 return match.group(1)
109 return None
110
110 lines PYTHON