2012-05-14 10 views
9

मैं पाइथन में एक यूआरएल को सामान्य करने के लिए लाइब्रेरी फ़ंक्शन खोज रहा हूं, जो पथ में "./" या "../" भागों को निकालना है, या एक डिफ़ॉल्ट पोर्ट जोड़ें या विशेष वर्णों से बचें और इसी तरह। नतीजा एक स्ट्रिंग होना चाहिए जो एक ही वेब पेज पर इंगित दो यूआरएल के लिए अद्वितीय है। उदाहरण के लिए http://google.com और http://google.com:80/a/../ एक ही परिणाम लौटाएंगे।URL को कैनोनिकल/सामान्यीकृत करें?

मैं पाइथन 3 पसंद करूंगा और पहले ही urllib मॉड्यूल को देख सकता हूं। यह यूआरएल को विभाजित करने के लिए कार्यों की पेशकश करता है लेकिन उन्हें canonicalize करने के लिए कुछ भी नहीं। जावा में URI.normalize() फ़ंक्शन है जो एक समान चीज करता है (हालांकि यह किसी दिए गए बंदरगाह के बराबर डिफ़ॉल्ट पोर्ट 80 पर विचार नहीं करता है), लेकिन क्या ऐसा कुछ है जो पाइथन है?

+0

एक तरफ ध्यान दें, इस तरह के रूप में एक संसाधन के रूप में 'http: // google.com /' 'http से समान नहीं है: // गूगल .com: 80/एक /../ '। यही है, अगर '/ a' मौजूद नहीं है, तो दूसरा पथ विफल हो जाएगा। इसे "कैनोलिकलाइजिंग" करके, आप उस विशेष मामले को खो देते हैं और एक वैध यूआरआई के साथ समाप्त होते हैं जब आपने अमान्य एक के साथ शुरू किया ... –

उत्तर

0

good start के बाद, मैंने एक ऐसी विधि तैयार की जो आमतौर पर वेब में पाए जाने वाले अधिकांश मामलों में फिट बैठती है।

def urlnorm(base, link=''): 
    '''Normalizes an URL or a link relative to a base url. URLs that point to the same resource will return the same string.''' 
    new = urlparse(urljoin(base, url).lower()) 
    return urlunsplit((
    new.scheme, 
    (new.port == None) and (new.hostname + ":80") or new.netloc, 
    new.path, 
    new.query, 
    '')) 
4

कैसे इस बारे में:

In [1]: from urllib.parse import urljoin 

In [2]: urljoin('http://example.com/a/b/c/../', '.') 
Out[2]: 'http://example.com/a/b/' 

this question के जवाब से प्रेरित होकर। यह बंदरगाहों को सामान्य नहीं करता है, लेकिन यह एक समारोह को चाबुक करना आसान होना चाहिए।

+0

मेरे पास 'urllib.parse' नहीं है, लेकिन मेरे पास 'urlparse' है। – osa

+3

'urllib.parse' पायथन 3 स्थान है - मूल प्रश्न पूछा गया था कि पाई 3. –

4

यही वह है जो मैं उपयोग करता हूं और यह अब तक काम करता है। आप पाइप से urlnorm प्राप्त कर सकते हैं।

ध्यान दें कि मैं क्वेरी पैरामीटर को सॉर्ट करता हूं। मैंने यह आवश्यक पाया है।

from urlparse import urlsplit, urlunsplit, parse_qsl 
from urllib import urlencode 
import urlnorm 

def canonizeurl(url): 
    split = urlsplit(urlnorm.norm(url)) 
    path = split[2].split(' ')[0] 

    while path.startswith('/..'): 
     path = path[3:] 

    while path.endswith('%20'): 
     path = path[:-3] 

    qs = urlencode(sorted(parse_qsl(split.query))) 
    return urlunsplit((split.scheme, split.netloc, path, qs, '')) 
+0

अच्छा है, अमान्य पैरेंट निर्देशिका – hoju

+0

हटा देता है आपको' split [2] .split ('') [0] 'को' urllib.parse.quote (विभाजन [2]) '- कुछ मामलों में, एक यूआरएल में रिक्त स्थान होने से पूरी तरह सामान्य है, और वास्तव में आवश्यक है। इसके अलावा, urlnorm केवल py2k है –

+0

इसके अलावा, आप कुछ असामान्य मामलों में, खंड को त्याग रहे हैं, जो वास्तव में एक आवश्यक यूआरएल घटक हो सकता है। हां, वेबपृष्ठों की एक गैर-शून्य संख्या है जहां 'blah.com/# wat' एक पूरी तरह से अलग पृष्ठ है तो' blah.com/'। यह आम तौर पर जावास्क्रिप्ट के साथ किया जाता है, और यह एक विशाल पिटा है, लेकिन यह अस्तित्व में है। –

2

urltools मॉड्यूल http:// में डबल स्लैश अप खिलवाड़ बिना एकाधिक स्लैश, . और .. घटकों को सामान्य।

एक बार जब आप pip install urltools कर इस प्रकार के उपयोग है:

print urltools.normalize('http://domain.com:80/a////b/../c') 
>>> 'http://domain.com/a/c' 
संबंधित मुद्दे