docs: def find_changelog(session, repo_url, deep=True):
      """
      Tries to find changelogs on the given `repo_url`.
      :param session: requests Session instance
      :param repo_url: str, URL to the repo
      :param deep: bool, deep search
      :return: str, URL to the raw changelog content
      """
      logger.debug("Trying to find changelog on repo {}".format(repo_url))
      resp = session.get(repo_url)
      if resp.status_code == 200:
          # build up a list of URLs on this repo. xpath() isn't returning raw strings, so we have to
          # convert them first. We also need to strip out all GET parameters if any.
          tree = etree.HTML(resp.content)
          try:
              links = frozenset([str(l).split("?")[0] for l in tree.xpath("//a/@href")])
          except UnicodeEncodeError:
              links = []
          match, found = False, False
          for link in links:
              # we are going to check for valid changelog links on the root first. We do that by
              # checking if the link ends with one of out changelog filename candidates.
              for candidate in CHANGELOG_FILENAME_CANDIDATES:
                  if link.endswith(candidate):
                      if "github.com" in repo_url and "blob" in link:
                          link = link.replace(repo_url, "")
                          match = validate_url("https://raw.githubusercontent.com" + link.replace("/blob/", "/"))
                      elif "bitbucket.org" in repo_url and "src" in link:
                          match = validate_url("https://bitbucket.org" + link.replace("/src/", "/raw/"))
                      elif "sourceforge.net" in repo_url:
                          match = validate_url(repo_url + link + "?format=raw")
                      if match:
                          yield match
                          match, found = False, True
  
          # if this is a deep search and we haven't found any changelogs on the repo root, we are
          # going to check every potential doc page.
          if deep and not found:
              for link in links:
                  sublink = False
                  for doc_candidate in DOCS_CANDIDATES:
                      if link.endswith(doc_candidate):
                          if "github.com" in repo_url and "tree" in link:
                              if link.startswith("https://github.com"):
                                  sublink = link
                              else:
                                  sublink = "https://github.com" + link
                          elif "bitbucket.org" in repo_url and "src" in link:
                              sublink = "https://bitbucket.org" + link
                          # if we find a valid link to a doc subdirectory on the repo call this
                          # function again and yield all possible changelog hits
                          if sublink:
                              for _url in find_changelog(session, sublink, deep=False):
                                  yield _url
                                  sublink = False