在Python中提取唯一的网址

问题描述

我想在列表中提取整个唯一的url项目,以便继续进行网络抓取项目。尽管我身边有很多URL,但我想在这里生成一些极简方案来解释我这一方面的主要问题。假设我的清单是这样的:

url_list = ["https://www.ox.ac.uk/","http://www.ox.ac.uk/","https://www.ox.ac.uk","http://www.ox.ac.uk","https://www.ox.ac.uk/index.PHP","https://www.ox.ac.uk/index.html","http://www.ox.ac.uk/index.PHP","http://www.ox.ac.uk/index.html","www.ox.ac.uk/","ox.ac.uk","https://www.ox.ac.uk/research"        
            ]
def ExtractUniqueUrls(urls):
    pass

ExtractUniqueUrls(url_list)

对于极简方案,我希望只有两个唯一的URL:“ https://www.ox.ac.uk”和“ https://www.ox.ac.uk/research”。尽管每个url元素都有一些不同,例如“ http ”,“ https ”,但以“ / ”结尾,而没有以“ ”结尾/ ”, index.PHP index.html ;他们都指向完全相同的网页。我可能已经错过了其他一些可能性(如果发现任何可能性,请记住它们)。无论如何,使用Python 3处理此问题的正确有效的方法是什么?

我不是在寻找像每个案例都专门针对每个案例的硬编码解决方案。例如,我不想手动检查URL末尾是否有“ /”。可能还有其他更好的解决方案,例如urllib?出于这个原因,我查看了urllib.parse的方法,但是到目前为止我还没有找到合适的解决方案。 谢谢

编辑:为了更好地解释,我在清单末尾添加一个示例。否则,您可能会假设我正在寻找根URL,但事实并非如此。

解决方法

仅在您了解所有情况后:

url_list = ["https://www.ox.ac.uk/","http://www.ox.ac.uk/","https://www.ox.ac.uk","http://www.ox.ac.uk","https://www.ox.ac.uk/index.php","https://www.ox.ac.uk/index.html","http://www.ox.ac.uk/index.php","http://www.ox.ac.uk/index.html","www.ox.ac.uk/","ox.ac.uk","ox.ac.uk/research","ox.ac.uk/index.php?12"]

def url_strip_gen(source: list):
    replace_dict = {".php": "",".html": "","http://": "","https://": ""}

    for url in source:
        for key,val in replace_dict.items():
            url = url.replace(key,val,1)
        url = url.rstrip('/')

        yield url[4:] if url.startswith("www.") else url


print(set(url_strip_gen(url_list)))
{'ox.ac.uk/index?12','ox.ac.uk/index','ox.ac.uk/research','ox.ac.uk'}

如果url如.html包含www.htmlsomething,则不会覆盖这种情况,在这种情况下,可以用urlparse进行补偿,因为它分别存储路径和url,如下所示:

>>> import pprint
>>> from urllib.parse import urlparse
>>> a = urlparse("http://ox.ac.uk/index.php?12")
>>> pprint.pprint(a)
ParseResult(scheme='http',netloc='ox.ac.uk',path='/index.php',params='',query='12',fragment='')

但是,如果没有方案:

>>> a = urlparse("ox.ac.uk/index.php?12")
>>> pprint.pprint(a)
ParseResult(scheme='',netloc='',path='ox.ac.uk/index.php',fragment='')

所有主机都具有path属性。

为弥补这一点,我们要么删除方案并为所有方案添加一个,要么检查url是否以方案开头,否则添加一个。 Prior更易于实现。

replace_dict = {"http://": "","https://": ""}

    for url in source:
        # Unify scheme to HTTP
        for key,1)

        url = "http://" + (url[4:] if url.startswith("www.") else url)
        parsed = urlparse(url)

以此保证您可以通过urlparse对URL的每个部分进行单独控制。但是,由于您没有指定要使url 唯一足够的url应该考虑的参数,因此我将把该任务留给您。

,

这是一种快速而肮脏的尝试:

def extract_unique_urls(url_list):

    unique_urls = []
    for url in url_list:
        # Removing the 'https://' etc. part
        if url.find('//') > -1:
            url = url.split('//')[1]
        # Removing the 'www.' part
        url = url.replace('www.','')
        # Removing trailing '/'
        url = url.rstrip('/')
        # If not root url then inspect the last part of the url
        if url.find('/') > -1:
            # Extracting the last part
            last_part = url.split('/')[-1]
            # Deciding if to keep the last part (no if '.' in it)
            if last_part.find('.') > -1:
                # If no to keep: Removing last part and getting rid of
                # trailing '/'
                url = '/'.join(url.split('/')[:-1]).rstrip('/')
        # Append if not already in list
        if url not in unique_urls:
            unique_urls.append(url)

    # Sorting for the fun of it
    return sorted(unique_urls)

我确定它不会涵盖所有可能的情况。但是,如果不是这样,您可以扩展它。我也不确定您是否要保留'http(s)://'部分。如果是,则将它们添加到结果中。