"""Spotify parsing module.""" import re import requests from bs4 import BeautifulSoup from src import constants class ParsingError(Exception): """Error parsing the Spotify API.""" def __init__(self, details=''): """Create ParsingError instance.""" super().__init__() self.details = f'Failed to parse Spotify response: {details}' def __str__(self): """Convert to string.""" return self.details def get_spotify_monthly_listeners(spotify_id: str) -> int: """Get spotify monthly listeners. Args: spotify_id (str): the id of the model. Returns: int: the number of monthly listeners. Raises: HTTPError: Spotify returned an error (usually 404). ParsingError: Failed to parse the spotify artist page. """ url = constants.SPOTIFY_URL_TEMPLATE + spotify_id response = requests.get(url) response.raise_for_status() soup = BeautifulSoup(response.text, features='html.parser') try: listeners_count = int(re.findall( r'\"monthly_listeners_count\":(\d+)', str(soup))[0]) except Exception: listeners_count = None if not listeners_count: about_block = soup.find('h2', text='About') monthly_listeners_block = None if about_block: monthly_listeners_block = about_block.find_next('div') if not about_block: monthly_listeners_block = soup.find('div', class_='Type__TypeElement-sc-goli3j-0') if monthly_listeners_block and monthly_listeners_block.text: if 'monthly listener' not in monthly_listeners_block.text: raise ParsingError( 'The element containing monthly listeners figure was not found.') listeners_count = int( monthly_listeners_block.text.replace( 'monthly listeners', '').replace( 'monthly listener', '').strip().replace(',', '')) else: raise ParsingError('About block was not found') return listeners_count