Spotalike ํ๋ก์ ํธ ๊ฐ์ - ๊ฐ์๋ช ๋งค์นญ ๋ฌธ์ ํด๊ฒฐ
๋ฌธ์ ์ํฉ
์ด์ ํฌ์คํ (์ง๋ ํฌ์คํ )์์ Spotalike ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ , FastAPI ์๋ฒ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๊น์ง ๊ตฌํํ๋ค. ๊ทธ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋์๋ค.
-
๊ฐ์๋ช ๋ฏธ์ฌ์ฉ
- ๊ฒ์์ ์ ๋ ฅํ ๊ฐ์๋ช ์ ์ฌ์ฉํ์ง ์์ ํน์ ๊ฐ์์ ๋ ธ๋๋ฅผ ์ ํํ์ง ๋ชปํจ.
-
์ฒซ ๋ฒ์งธ ๊ณก ์๋ ์ ํ
- ๋์ผํ ๊ณก๋ช ์ด ์๋ ๊ฒฝ์ฐ ๋๋กญ๋ค์ด์์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ๋ ธ๋๋ฅผ ์๋์ผ๋ก ์ ํํจ.
์๋ฅผ ๋ค์ด, โChristopherโ์ When I Get Old๋ฅผ ๊ฒ์ํ๋ ค ํ์ผ๋, ๋๋กญ๋ค์ด์์ ์๋์ผ๋ก โDescendentsโ์ ๋์ผ ๊ณก๋ช ์ด ์ ํ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
ํด๊ฒฐ ๋ฐฉ์
1. ๊ฒ์ ๋ฌธ์์ด ์กฐํฉ ๋ฐฉ์
์ฒ์์๋ ๊ณก๋ช ๊ณผ ๊ฐ์๋ช ์ ์กฐํฉํ ๋ฌธ์์ด๋ก ๊ฒ์ํ๋ ค ํ์ผ๋, Spotalike์ ๊ฒ์์ฐฝ์ ์ฒ์๋ถํฐ โWhen I Get Old by Christopherโ ํ์์ผ๋ก ์ ๋ ฅํ๋ฉด ๊ด๋ จ ๋ ธ๋๊ฐ ๋ํ๋์ง ์์๋ค. ๋ฐ๋ผ์ ์ด ๋ฐฉ๋ฒ์ ์ ํฉํ์ง ์์๋ค.
2. URL ์ง์ ์์ฑ ๋ฐฉ์
๊ฒ์ ๊ฒฐ๊ณผ ํ์ด์ง URL์ ๋ถ์ํด๋ณด๋ ๊ณ ์ ๋ฒํธ๊ฐ ํฌํจ๋์ด ์์๋ค.
- ๊ธฐ๋ณธ URL:
https://spotalike.com/en - ๊ฒ์ ํ URL:
https://spotalike.com/en/songs-similar-to/christopher-when-i-get-old/3952490
์ด ๊ณ ์ ๋ฒํธ๋ฅผ ์์ธกํ๊ฑฐ๋ ์ฐธ์กฐํ ๋ฐฉ๋ฒ์ด ์์ด ์ด ์ ๊ทผ ๋ฐฉ์๋ ํฌ๊ธฐํ๋ค.
3. ๋๋กญ๋ค์ด์์ ๊ฐ์๋ช ๋งค์นญ
๋ง์ง๋ง์ผ๋ก, ๋๋กญ๋ค์ด์์ ํน์ ๊ณก๋ช ๊ณผ ๊ฐ์๋ช ์ ์ผ์นํ๋ ํญ๋ชฉ์ ์ฐพ์ ์ ํํ๋ ๋ฐฉ์์ ๊ตฌํํ๋ค.
- ๋๋กญ๋ค์ด ๋ด ๊ณก๋ช ๊ณผ ๊ฐ์๋ช ์์๋ฅผ ๊ฐ๊ฐ ์ถ์ถ.
- ์ ๋ ฅ๊ฐ๊ณผ ์ผ์นํ๋ ํญ๋ชฉ์ ์ฐพ์ ํด๋ฆญ.
- ์ผ์นํ๋ ํญ๋ชฉ์ด ์์ผ๋ฉด ๊ฒฝ๊ณ ๋ฉ์์ง ์ถ๋ ฅ.
๊ฐ์ ๋ ์ฝ๋
์ฃผ์ ์์ ๋ด์ฉ
- ๋๋กญ๋ค์ด ๋ด ๊ณก๋ช ๊ณผ ๊ฐ์๋ช ์ ๊ฐ๊ฐ ์ถ์ถ.
- ์ ๋ ฅ๊ฐ๊ณผ ์ผ์นํ๋ ํญ๋ชฉ์ ํด๋ฆญํ๋๋ก ๊ฐ์ .
- ์ผ์นํ๋ ํญ๋ชฉ์ด ์์ ๊ฒฝ์ฐ ๋น ๋ฆฌ์คํธ ๋ฐํ.
def get_spotalike_tracks(song_title: str, artist_name: str):
"""
Fetch tracks similar to the given song and artist.
Args:
song_title (str): The title of the song.
artist_name (str): The artist of the song.
Returns:
list: A list of tracks with title, artist, and duration.
"""
options = Options()
options.add_argument("--disable-gpu")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
# options.add_argument("--headless") # Uncomment for performance in production
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
tracks = []
try:
logging.info("Opening Spotalike...")
driver.get(BASE_URL)
wait = WebDriverWait(driver, 10)
# Enter the song title and artist name into the search field
logging.info(f"Searching for: {song_title} by {artist_name}")
search_field = wait.until(EC.presence_of_element_located((By.ID, "search")))
query = f"{song_title}"
search_field.send_keys(query)
# Wait for the dropdown to appear and validate
dropdown_locator = (By.CSS_SELECTOR, "ul[class^='Dropdown_dropdown']")
wait.until(EC.visibility_of_element_located(dropdown_locator))
# Find all dropdown items
dropdown_items = driver.find_elements(By.CSS_SELECTOR, "ul[class^='Dropdown_dropdown'] li button")
match_found = False
for item in dropdown_items:
# Extract song title and artist from the dropdown
song_title_elements = item.find_elements(By.CSS_SELECTOR, "span.Dropdown_highlighted__81RfT")
extracted_song_title = "".join([elem.text for elem in song_title_elements]).strip()
artist_elements = item.find_elements(By.CSS_SELECTOR, "span.Dropdown_artist__DoTwq")
extracted_artist = "".join([elem.text for elem in artist_elements]).strip()
# Check for an exact match
if extracted_artist.lower() == artist_name.lower() and extracted_song_title.lower() == song_title.lower():
logging.info(f"Found match: {extracted_song_title} by {extracted_artist}")
item.click() # Click the matched item
match_found = True
break
if not match_found:
logging.warning("No exact match found in the dropdown.")
return []
# Wait for the table of recommendations to load
table_body = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "tbody")))
tracks = extract_tracks(table_body)
except Exception as e:
logging.error(f"An error occurred: {e}", exc_info=True)
finally:
logging.info("Closing the driver.")
driver.quit()
return tracks๊ฒฐ๊ณผ
์ด์ ํน์ ๊ณก๋ช ๊ณผ ๊ฐ์๋ช ์ ์ ํํ ์ ๋ ฅํ๋ฉด ์ํ๋ ํญ๋ชฉ์ ์ ํํ ์ ์๋ค. ์๋ฅผ ๋ค์ด, Christopher์ When I Get Old๋ฅผ ๊ฒ์ํ๋ฉด ๋๋กญ๋ค์ด์์ ์ ํํ ์ผ์นํ๋ ๊ณก๋ช ์ ์ฐพ์ ํด๋ฆญํ ํ ์ถ์ฒ ๊ณก ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์จ๋ค.
ํฅํ ๊ฐ์ ์ฌํญ
-
์์ธ ์ฒ๋ฆฌ ๊ฐ์
- ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์นํ์ ์ธ ๋ฉ์์ง ์ ๊ณต.
-
๊ฐ์๋ช /๊ณก๋ช ์คํ ์ฒ๋ฆฌ
- ๊ฐ์๋ช ์ด๋ ๊ณก๋ช ์ ์คํ๊ฐ ์๋ ๊ฒฝ์ฐ ์ ์ฌ ํญ๋ชฉ ์ถ์ฒ ๊ธฐ๋ฅ ์ถ๊ฐ.