def find_repo_urls(session, name, candidates):
    """
    Visits the given URL candidates and searches the page for valid links to a repository.
    :param session: requests Session instance
    :param name: str, project name
    :param candidates: list, list of URL candidates
    :return: str, URL to a repo
    """
    for _url in candidates:
        if validate_url(_url):
            try:
                resp = session.get(_url)
                if resp.status_code == 200:
                    tree = etree.HTML(resp.content)
                    if tree:
                        for link in frozenset([str(l) for l in tree.xpath("//a/@href")]):
                            # check if the link 1) is to github.com / bitbucket.org AND 2) somewhat
                            # contains the project name
                            if ("github.com" in link or "bitbucket.org" in link or
                                    "sourceforge.net" in link) \
                                    and contains_project_name(name, link):
                                link = validate_url(validate_repo_url(url=link))
                                if link:
                                    logger.debug("Found repo URL {}".format(link))
                                    yield link
            except ConnectionError:
                # we really don't care about connection errors here. a lot of project pages are simply
                # down because the project is no longer maintained
                pass
            except etree.XMLSyntaxError:
                # unable to parse HTML
                pass
            except UnicodeEncodeError:
                pass