Remove unnecessary intermediate web request to genius.com when fetching lyrics.

The search results already include the correct song page url, making it superfluous to do another request via the /song api just to get it.
This commit is contained in:
stlutz 2020-05-16 16:28:17 +02:00
parent ac043f9be0
commit 46143d9762
2 changed files with 8 additions and 20 deletions

View file

@ -359,14 +359,9 @@ class Genius(Backend):
'User-Agent': USER_AGENT,
}
def lyrics_from_song_api_path(self, song_api_path):
song_url = self.base_url + song_api_path
response = requests.get(song_url, headers=self.headers)
json = response.json()
path = json["response"]["song"]["path"]
def lyrics_from_song_page(self, page_url):
# Gotta go regular html scraping... come on Genius.
page_url = "https://genius.com" + path
self._log.debug(u'fetching lyrics from: {0}', page_url)
try:
page = requests.get(page_url)
except requests.RequestException as exc:
@ -404,7 +399,6 @@ class Genius(Backend):
self._log.debug(u'Genius API request returned invalid JSON')
return None
song_info = None
for hit in json["response"]["hits"]:
# Genius uses zero-width characters to denote lowercase
# artist names.
@ -412,15 +406,9 @@ class Genius(Backend):
strip(u'\u200b').lower()
if hit_artist == artist.lower():
song_info = hit
break
return self.lyrics_from_song_page(hit["result"]["url"])
if song_info:
self._log.debug(u'fetched: {0}', song_info["result"]["url"])
song_api_path = song_info["result"]["api_path"]
return self.lyrics_from_song_api_path(song_api_path)
else:
self._log.debug(u'genius: no matching artist')
self._log.debug(u'genius: no matching artist')
class LyricsWiki(SymbolsReplaced):

View file

@ -456,7 +456,7 @@ class LyricsGeniusBaseTest(unittest.TestCase):
self.skipTest("Python's built-in HTML parser is not good enough")
class LyricsGeniusScrapTest(LyricsGeniusBaseTest):
class LyricsGeniusScrapeTest(LyricsGeniusBaseTest):
"""Checks that Genius backend works as intended.
"""
@ -469,12 +469,12 @@ class LyricsGeniusScrapTest(LyricsGeniusBaseTest):
@patch.object(requests, 'get', GeniusMockGet())
def test_no_lyrics_div(self):
"""Ensure that `lyrics_from_song_api_path` doesn't crash when the html
for a Genius page contain <div class="lyrics"></div>
"""Ensure that `lyrics_from_song_page` doesn't crash when the html
for a Genius page doesn't contain <div class="lyrics"></div>
"""
# https://github.com/beetbox/beets/issues/3535
# expected return value None
self.assertEqual(genius.lyrics_from_song_api_path('/nolyric'),
self.assertEqual(genius.lyrics_from_song_page('https://genius.com/sample'),
None)