问题描述
我想在列表中提取整个唯一的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)://'部分。如果是,则将它们添加到结果中。