Parses the DOM and returns anime attributes in the sidebar.

    :type anime_page: :class:`bs4.BeautifulSoup`
    :param anime_page: MAL anime page's DOM

    :rtype: dict
    :return: anime attributes

    :raises: :class:`.InvalidAnimeError`, :class:`.MalformedAnimePageError`

def parse_sidebar(self, anime_page):
    """Parses the DOM and returns anime attributes in the sidebar.

    :type anime_page: :class:`bs4.BeautifulSoup`
    :param anime_page: MAL anime page's DOM

    :rtype: dict
    :return: anime attributes

    :raises: :class:`.InvalidAnimeError`, :class:`.MalformedAnimePageError`
    """
    # if MAL says the series doesn't exist, raise an InvalidAnimeError.
    error_tag = anime_page.find(u'div', {'class': 'badresult'})
    if error_tag:
        raise InvalidAnimeError(self.id)

    title_tag = anime_page.find(u'div', {'id': 'contentWrapper'}).find(u'h1')
    if not title_tag.find(u'div'):
      # otherwise, raise a MalformedAnimePageError.
      raise MalformedAnimePageError(self.id, anime_page, message="Could not find title div")

    anime_info = super(Anime, self).parse_sidebar(anime_page)
    info_panel_first = anime_page.find(u'div', {'id': 'content'}).find(u'table').find(u'td')

    try:
      episode_tag = info_panel_first.find(text=u'Episodes:').parent.parent
      utilities.extract_tags(episode_tag.find_all(u'span', {'class': 'dark_text'}))
      anime_info[u'episodes'] = int(episode_tag.text.strip()) if episode_tag.text.strip() != 'Unknown' else 0
    except:
      if not self.session.suppress_parse_exceptions:
        raise

    try:
      aired_tag = info_panel_first.find(text=u'Aired:').parent.parent
      utilities.extract_tags(aired_tag.find_all(u'span', {'class': 'dark_text'}))
      aired_parts = aired_tag.text.strip().split(u' to ')
      if len(aired_parts) == 1:
        # this aired once.
        try:
          aired_date = utilities.parse_profile_date(aired_parts[0], suppress=self.session.suppress_parse_exceptions)
        except ValueError:
          raise MalformedAnimePageError(self.id, aired_parts[0], message="Could not parse single air date")
        anime_info[u'aired'] = (aired_date,)
      else:
        # two airing dates.
        try:
          air_start = utilities.parse_profile_date(aired_parts[0], suppress=self.session.suppress_parse_exceptions)
        except ValueError:
          raise MalformedAnimePageError(self.id, aired_parts[0], message="Could not parse first of two air dates")
        try:
          air_end = utilities.parse_profile_date(aired_parts[1], suppress=self.session.suppress_parse_exceptions)
        except ValueError:
          raise MalformedAnimePageError(self.id, aired_parts[1], message="Could not parse second of two air dates")
        anime_info[u'aired'] = (air_start, air_end)
    except:
      if not self.session.suppress_parse_exceptions:
        raise

    try:
      producers_tag = info_panel_first.find(text=u'Producers:').parent.parent
      utilities.extract_tags(producers_tag.find_all(u'span', {'class': 'dark_text'}))
      utilities.extract_tags(producers_tag.find_all(u'sup'))
      anime_info[u'producers'] = []
      for producer_link in producers_tag.find_all('a'):
        if producer_link.text == u'add some':
          # MAL is saying "None found, add some".
          break
        link_parts = producer_link.get('href').split('p=')
        # of the form: /anime.php?p=14
        if len(link_parts) > 1:
          anime_info[u'producers'].append(self.session.producer(int(link_parts[1])).set({'name': producer_link.text}))
    except:
      if not self.session.suppress_parse_exceptions:
        raise

    try:
      duration_tag = info_panel_first.find(text=u'Duration:').parent.parent
      utilities.extract_tags(duration_tag.find_all(u'span', {'class': 'dark_text'}))
      anime_info[u'duration'] = duration_tag.text.strip()
      duration_parts = [part.strip() for part in anime_info[u'duration'].split(u'.')]
      duration_mins = 0
      for part in duration_parts:
        part_match = re.match(u'(?P<num>[0-9]+)', part)
        if not part_match:
          continue
        part_volume = int(part_match.group(u'num'))
        if part.endswith(u'hr'):
          duration_mins += part_volume * 60
        elif part.endswith(u'min'):
          duration_mins += part_volume
      anime_info[u'duration'] = datetime.timedelta(minutes=duration_mins)
    except:
      if not self.session.suppress_parse_exceptions:
        raise

    try:
      rating_tag = info_panel_first.find(text=u'Rating:').parent.parent
      utilities.extract_tags(rating_tag.find_all(u'span', {'class': 'dark_text'}))
      anime_info[u'rating'] = rating_tag.text.strip()
    except:
      if not self.session.suppress_parse_exceptions:
        raise

    return anime_info