2008-09-23 12 views
64

में एक यूआरएल कैसे सामान्य कर सकता हूं मैं जानना चाहता हूं कि मैं पाइथन में एक यूआरएल सामान्य करता हूं।मैं पाइथन

उदाहरण के लिए, अगर मैं की तरह एक यूआरएल स्ट्रिंग है: मैं अजगर में एक पुस्तकालय है कि एक उचित करने के लिए अतिरिक्त स्थान (या किसी भी अन्य गैर सामान्यीकृत चरित्र) को बदलने की जरूरत होगी "http://www.example.com/foo goo/bar.html"

यूआरएल।

+0

एक और अधिक अप-टू-डेट जवाब नहीं है यहां StackOverflow पर: http://stackoverflow.com/questions/10584861/canonize-normali ze-an-url-in-python/15629657 – stuckintheshuck

+1

मुझे नहीं लगता कि यह बेहतर है ... –

उत्तर

10
import urlparse, urllib 
def myquote(url): 
    parts= urlparse.urlparse(url) 
    return urlparse.urlunparse(parts[:2] + urllib.quote(parts[2]) + parts[3:]) 

यह केवल पथ घटक उद्धृत करता है।

अन्यथा, आप कर सकता है: urllib.quote(url, safe=":/")

+2

यह सिर्फ सभी वर्णों को उद्धृत करता है। वह उसकी मदद नहीं करेगा। –

+0

इस उदाहरण में, यह ':' वर्ण उद्धृत करेगा (सभी नहीं)। टिप्पणी के लिए धन्यवाद। – tzot

21

उपयोग urllib.quote या urllib.quote_plus

urllib documentation से:

बोली (स्ट्रिंग [, सुरक्षित])

विशेष वर्ण बदलें स्ट्रिंग "% xx" से बचने में। पत्र, अंक, और वर्ण "_.-" कभी उद्धृत नहीं हैं। वैकल्पिक सुरक्षित पैरामीटर अतिरिक्त वर्ण निर्दिष्ट करता है जिन्हें उद्धृत नहीं किया जाना चाहिए - इसका डिफ़ॉल्ट मान '/' है।

उदाहरण: quote('/~connolly/')'/%7econnolly/' पैदा करता है।

quote_plus (स्ट्रिंग [, सुरक्षित])

बोली (जैसा), लेकिन यह भी रिक्त स्थान धन चिह्नों से, की जगह के रूप में HTML प्रपत्र मूल्यों के हवाले करने के लिए आवश्यक। मूल स्ट्रिंग में प्लस संकेत तब तक बच गए हैं जब तक उन्हें सुरक्षित में शामिल नहीं किया जाता है। यह में '/' के लिए सुरक्षित डिफ़ॉल्ट नहीं है।

संपादित करें: पूरे यूआरएल पर urllib.quote या urllib.quote_plus का उपयोग करते हुए यह वध करना होगा, @ ΤΖΩΤΖΙΟΥ बताते हैं:

>>> quoted_url = urllib.quote('http://www.example.com/foo goo/bar.html') 
>>> quoted_url 
'http%3A//www.example.com/foo%20goo/bar.html' 
>>> urllib2.urlopen(quoted_url) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "c:\python25\lib\urllib2.py", line 124, in urlopen 
    return _opener.open(url, data) 
    File "c:\python25\lib\urllib2.py", line 373, in open 
    protocol = req.get_type() 
    File "c:\python25\lib\urllib2.py", line 244, in get_type 
    raise ValueError, "unknown url type: %s" % self.__original 
ValueError: unknown url type: http%3A//www.example.com/foo%20goo/bar.html 

@ ΤΖΩΤΖΙΟΥ एक समारोह urlparse.urlparse and urlparse.urlunparse का उपयोग करता है यूआरएल पार्स करने के लिए प्रदान करता है और केवल पथ को एन्कोड करें। यह आपके लिए अधिक उपयोगी हो सकता है, यद्यपि यदि आप एक ज्ञात प्रोटोकॉल और होस्ट से यूआरएल बना रहे हैं लेकिन एक संदिग्ध पथ के साथ, आप शायद यूआरएलपीएस से बचने के लिए भी कर सकते हैं और यूआरएल के संदिग्ध हिस्से को उद्धृत कर सकते हैं, ज्ञात सुरक्षित भागों।

+2

तो, urllib.quote वापसी क्या प्रश्न के उदाहरण url दिया है? – tzot

+1

कचरा। एक स्पष्ट रूप से गलत जवाब समाधान के रूप में स्वीकार क्यों किया जाता है? –

+0

@ ΤΖΩΤΖΙΟΥ: उत्कृष्ट बिंदु। @ एर्मिन रोनाकर को संबोधित: संभवतः क्योंकि उत्तरदाता और Accepter समस्या से अवगत नहीं थे - सभी समस्याओं के लिए सभी समस्याएं स्पष्ट नहीं हैं। –

66

इस मॉड्यूल पर एक नज़र डालें: werkzeug.utils।(अब werkzeug.urls में)

समारोह आप देख रहे हैं "url_fix" कहा जाता है और इस तरह काम करता है:

>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)') 
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29' 

यह WERKZEUG में लागू हो जाता है इस प्रकार है:

import urllib 
import urlparse 

def url_fix(s, charset='utf-8'): 
    """Sometimes you get an URL by a user that just isn't a real 
    URL because it contains unsafe characters like ' ' and so on. This 
    function can fix some of the problems in a similar way browsers 
    handle data entered by the user: 

    >>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)') 
    'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29' 

    :param charset: The target charset for the URL if the url was 
        given as unicode string. 
    """ 
    if isinstance(s, unicode): 
     s = s.encode(charset, 'ignore') 
    scheme, netloc, path, qs, anchor = urlparse.urlsplit(s) 
    path = urllib.quote(path, '/%') 
    qs = urllib.quote_plus(qs, ':&=') 
    return urlparse.urlunsplit((scheme, netloc, path, qs, anchor)) 
+0

हालांकि यह http rfc2616 से अधिक सटीक समाधान है, मुझे लगता है कि यह अधिक है, या मुझे कुछ याद आती है? –

+1

हां। आप शायद सवाल चूक गए। उसके पास उपयोगकर्ता इनपुट से एक यूआरएल है और इसे सही यूआरएल में बदलना चाहता है। (उर्फ: फ़ायरफ़ॉक्स स्थान बार क्या करता है) –

+3

'url_fix' अब 'werkzeug.urls' – sebpiq

55

Real fix in Python 2.7 for that problem

सही समाधान था:

# percent encode url, fixing lame server errors for e.g, like space 
# within url paths. 
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]") 

अधिक जानकारी के लिए देख Issue918368: "urllib doesn't correct server returned urls"

+4

पर स्थित है उत्कृष्ट उत्तर, संक्षिप्त और सहायक। चूंकि यह परिवर्तन urllib के अंदर था, कोड जो ऐसा करना चाहता है उसे उपरोक्त पैरामीटर के साथ 'urllib' आयात करना चाहिए और 'urllib.quote()' को कॉल करना चाहिए। –

+0

पत्र पर यह बारफ, लेकिन मैं इसे अपना वोट देता हूं क्योंकि यह आसान है, और अभी तक एक और आयात की आवश्यकता नहीं है। – mlissner

+0

आकर्षण की तरह काम किया! exaclty जो मैं –

12

क्योंकि यह पेज एक शीर्ष परिणाम है गूगल विषय पर खोज के लिए, मुझे लगता है कि कुछ काम है कि urlencoding अंतरिक्ष वर्ण से परे चला जाता अजगर के साथ URL सामान्य पर किया गया है उल्लेख के लायक है। उदाहरण के लिए, डिफ़ॉल्ट बंदरगाहों, चरित्र मामले, पिछली स्लैश की कमी, आदि से निपटना

जब एटम सिंडिकेशन प्रारूप विकसित किया जा रहा था, तो यूआरएल को कैनोलिक प्रारूप में सामान्य करने के तरीके पर कुछ चर्चा हुई; यह एटम/पाई विकी पर आलेख PaceCanonicalIds में प्रलेखित है। वह लेख कुछ अच्छे परीक्षण मामलों को प्रदान करता है।

मेरा मानना ​​है कि इस चर्चा का एक परिणाम मार्क नॉटिंघम की urlnorm.py लाइब्रेरी थी, जिसे मैंने दो परियोजनाओं पर अच्छे परिणामों के साथ उपयोग किया है। हालांकि, यह स्क्रिप्ट इस प्रश्न में दिए गए यूआरएल के साथ काम नहीं करती है। तो बेहतर विकल्प Sam Ruby's version of urlnorm.py हो सकता है, जो उस यूआरएल को नियंत्रित करता है, और एटम विकी के उपर्युक्त परीक्षण मामलों में से सभी।

1

मैं इस तरह के एक समस्या का सामना: केवल अंतरिक्ष उद्धृत करने के लिए की जरूरत है।

fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]") सहायता करते हैं, लेकिन यह बहुत जटिल है।

इसलिए मैंने एक आसान तरीका उपयोग किया: url = url.replace(' ', '%20'), यह सही नहीं है, लेकिन यह सबसे आसान तरीका है और यह इस स्थिति के लिए काम करता है।

संबंधित मुद्दे