SongScope / azapi.py
kmaurinjones's picture
Upload azapi.py
610e92c
raw
history blame
6.01 kB
from .requester import Requester
from .tools import *
class AZlyrics(Requester):
"""
Fast and Secure API for AZLyrics.com.
Attributes:
title (str): song title.
artist (str): artist name.
search_engine (str): search engine used to assist scraping lyrics.
- currently available: 'google', 'duckduckgo'.
accuracy (float): used to determine accuracy via jaro algorithm.
proxies (dict): if you want to use proxy while connecting to 'AZLyrics.com'.
"""
def __init__(self, search_engine='', accuracy=0.6, proxies={}):
self.title = ''
self.artist = ''
self.search_engine = search_engine
self.accuracy = accuracy
if not 0 < accuracy <= 1:
self.accuracy = 0.6
self.proxies = proxies
self.lyrics_history = []
self.lyrics = ''
self.songs = {}
def getLyrics(self, url=None, ext='txt', save=False, path='', sleep=3):
"""
Retrieve Lyrics for a given song details.
Parameters:
url (str): url of the song's Azlyrics page.
ext (str): extension of the lyrics saved file, default is ".txt".
save (bool): allow to or not to save lyrics in a file.
sleep (float): cooldown before next request.
Returns:
lyrics (str): Lyrics of the detected song.
"""
# Best cooldown is 5 sec
time.sleep(sleep)
link = url
if not url:
# v3.0.5: No need for artist and title if url is found
if not self.artist + self.title:
raise ValueError("Both artist and title can't be empty!")
if self.search_engine:
# If user can't remember the artist,
# he can search by title only
# Get AZlyrics url via Google Search
link = googleGet(
self.search_engine,
self.accuracy,
self.get,
self.artist,
self.title,
0,
self.proxies
)
if not link:
return 0
else:
# Sometimes search engines block you
# If happened use the normal get method
link = normalGet(
self.artist,
self.title,
0)
page = self.get(link, self.proxies)
if page.status_code != 200:
if not self.search_engine:
print('Failed to find lyrics. Trying to get link from Google')
self.search_engine = 'google'
lyrics = self.getLyrics(url=url, ext=ext, save=save, path=path, sleep=sleep)
self.search_engine = ''
return lyrics
else:
print('Error',page.status_code)
return 1
# Getting Basic metadata from azlyrics
metadata = [elm.text for elm in htmlFindAll(page)('b')]
# if metadata is empty, then it's not a valid page
if not metadata:
print('Error', 'no metadata')
return 1
# v3.0.4: Update title and artist attributes with exact names
self.artist = filtr(metadata[0][:-7], True)
self.title = filtr(metadata[1][1:-1], True)
lyrics = parseLyric(page)
self.lyrics = lyrics.strip()
# Saving Lyrics
if lyrics:
if save:
# v3.0.2: Adding custom path
p = os.path.join(
path,
'{} - {}.{}'.format(
self.title.title(),
self.artist.title(),
ext
)
)
with open(p, 'w', encoding='utf-8') as f:
f.write(lyrics.strip())
# Store lyrics for later usage
self.lyrics_history.append(self.lyrics)
return self.lyrics
self.lyrics = 'No lyrics found :('
return 2
def getSongs(self, sleep=3):
"""
Retrieve a dictionary of songs with their links.
Parameters:
sleep (float): cooldown before next request.
Returns:
dict: dictionary of songs with their links.
"""
if not self.artist:
raise Exception("Artist can't be empty!")
# Best cooldown is 5 sec
time.sleep(sleep)
if self.search_engine:
link = googleGet(
self.search_engine,
self.accuracy,
self.get,
self.artist,
'',
1,
self.proxies
)
if not link:
return {}
else:
link = normalGet(
self.artist,
'',
1)
albums_page = self.get(link, self.proxies)
if albums_page.status_code != 200:
if not self.search_engine:
print('Failed to find songs. Trying to get link from Google')
self.search_engine = 'google'
songs = self.getLyrics(sleep=sleep)
self.search_engine = ''
return songs
else:
print('Error',albums_page.status_code)
return {}
# Store songs for later usage
self.songs = parseSongs(albums_page)
return self.songs