Skip to content

azlyrics

AZLyrics lyrics module.

AzLyrics() ¤

Bases: LyricsProvider

AZLyrics lyrics provider class.

Source code in spotdl/providers/lyrics/azlyrics.py
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def __init__(self):
    super().__init__()

    self.session = requests.Session()
    self.session.headers.update(
        {
            "Host": "www.azlyrics.com",
            "User-Agent": (
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
                "(KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
            ),
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "en-US,en;q=0.5",
            "Accept-Encoding": "gzip, deflate, br, zstd",
            "DNT": "1",
            "Connection": "keep-alive",
            "Upgrade-Insecure-Requests": "1",
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "none",
            "Sec-Fetch-User": "?1",
            "Priority": "u=0, i",
        }
    )

    self.x_code = self._get_x_code()

extract_lyrics(url, **_) ¤

Extracts the lyrics from the given url.

Arguments¤
  • url: The url to extract the lyrics from.
  • kwargs: Additional arguments.
Returns¤
  • The lyrics of the song or None if no lyrics were found.
Source code in spotdl/providers/lyrics/azlyrics.py
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def extract_lyrics(self, url: str, **_) -> Optional[str]:
    """
    Extracts the lyrics from the given url.

    ### Arguments
    - url: The url to extract the lyrics from.
    - kwargs: Additional arguments.

    ### Returns
    - The lyrics of the song or None if no lyrics were found.
    """

    response = self.session.get(url)
    soup = BeautifulSoup(response.content, "html.parser")

    # Find all divs that don't have a class
    div_tags = soup.find_all("div", class_=False, id_=False)

    # Find the div with the longest text
    lyrics_div = sorted(div_tags, key=lambda x: len(x.text))[-1]

    # extract lyrics from div and clean it up
    lyrics = lyrics_div.get_text().strip()

    return lyrics

get_results(name, artists, **_) ¤

Returns the results for the given song.

Arguments¤
  • name: The name of the song.
  • artists: The artists of the song.
  • kwargs: Additional arguments.
Returns¤
  • A dictionary with the results. (The key is the title and the value is the url.)
Source code in spotdl/providers/lyrics/azlyrics.py
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
def get_results(self, name: str, artists: List[str], **_) -> Dict[str, str]:
    """
    Returns the results for the given song.

    ### Arguments
    - name: The name of the song.
    - artists: The artists of the song.
    - kwargs: Additional arguments.

    ### Returns
    - A dictionary with the results. (The key is the title and the value is the url.)
    """

    if self.x_code is None:
        self.x_code = self._get_x_code()

    if self.x_code is None:
        return {}

    params = {
        "q": f"{name.strip().replace(' ', '+')}+{artists[0].strip().replace(' ', '+')}",
        "x": self.x_code,
    }

    soup = None
    for i in range(4):  # Retry up to 4 times
        try:
            response = self.session.get(
                "https://www.azlyrics.com/search/", params=params
            )

            if not response.ok:
                continue

            soup = BeautifulSoup(response.content, "html.parser")
            break

        except requests.ConnectionError:
            logger.debug(
                "AZLyrics: ConnectionError on attempt %s with params: %s", i, params
            )
            continue

    if soup is None:
        return {}

    td_tags = soup.find_all("td")
    if len(td_tags) == 0:
        return {}

    results = {}
    for td_tag in td_tags:

        # Ensure td_tag is a Tag object before calling find_all
        if not isinstance(td_tag, Tag):
            continue

        a_tags = td_tag.find_all("a", href=True)

        if len(a_tags) == 0:
            continue

        a_tag = a_tags[0]
        url = a_tag.get("href", "").strip()

        if url == "":
            continue

        title = td_tag.find("span").get_text().strip()
        artist = td_tag.find("b").get_text().strip()

        results[f"{artist} - {title}"] = url

    return results