指向同一资源的URL表现形式可能存在差异,例如,下面三个URL实际上指向的是同一资源:
http://www.REDICECN.com/
http://www.redicecn.com
http://www.redicecn.com/tools/../
对于爬虫来说,合理的处理方式是将上述三个表现不同URL视为相同的URL。
下面给出一个Python的解决方案,没有考虑URL编码的问题:
# url_normal.py
# by redice
import re
import urlparse
def url_normal(url):
"""normalize url
"""
scheme, netloc, upath, qus = urlparse.urlsplit(url)[:4]
netloc = netloc.lower()
if upath:
upath = re.sub('/{2,}', '/', upath)
upath = re.sub(r'/\./', '/', upath)
parent_regex = re.compile(r'/[^/]+/\.\.')
while parent_regex.search(upath):
upath = parent_regex.sub('/', upath)
upath = re.sub('/{2,}', '/', upath)
if upath.startswith('/..') or upath.endswith('/.'):
upath = ''
else:
upath = re.sub('/$', '', upath)
if qus:
return '%s://%s%s?%s' % (scheme, netloc, upath or '/', qus)
else:
return '%s://%s%s' % (scheme, netloc, upath)
if __name__ == '__main__':
print url_normal('http://www.REDICECN.com/?id=1')
print url_normal('http://www.redicecn.com:80/.')
print url_normal('http://www.redicecn.com//tools/../index.php?upcache=1')