69 votes

Python : Obtenir des sections de chemin d'accès aux URL

Comment obtenir des sections de chemin spécifiques à partir d'une url ? Par exemple, je veux une fonction qui fonctionne sur ceci :

http://www.mydomain.com/hithere?image=2934

et renvoie "hithere"

ou fonctionne sur ce point :

http://www.mydomain.com/hithere/something/else

et renvoie la même chose ("hithere")

Je sais que cela utilisera probablement urllib ou urllib2 mais je n'arrive pas à trouver dans la documentation comment obtenir seulement une section du chemin.

2 votes

La syntaxe de l'URL est quelque chose comme : scheme://domain:port/path?query_string#fragment_id Donc, "hithere" est l'ensemble de path dans le premier cas et 1 section de celui-ci dans le second. Il suffit de l'urlparser pour que 'hithere' devienne path.split('/')[1].

1 votes

Ne serait-ce pas path.split('/')[0] ? (le premier élément de la liste)

2 votes

Non, car le chemin commence par un '/' et [0] est donc une chaîne vide. C'est-à-dire que ideone.com/hJRxk

69voto

Josh Lee Points 53741

Extraire le composant chemin de l'URL avec urlparse :

>>> import urlparse
>>> path = urlparse.urlparse('http://www.example.com/hithere/something/else').path
>>> path
'/hithere/something/else'

Divisez le chemin en composants avec os.path.split :

>>> import os.path
>>> os.path.split(path)
('/hithere/something', 'else')

Les fonctions dirname et basename vous donnent les deux parties de la division ; utilisez peut-être dirname dans une boucle while :

>>> while os.path.dirname(path) != '/':
...     path = os.path.dirname(path)
... 
>>> path
'/hithere'

3 votes

Est-ce qu'urllib n'a pas une fonction qui peut faire cela sans faire un tas d'analyse de chaîne de caractères/splitting/looping ? Je pensais qu'il y aurait un raccourci...

0 votes

Comment urlparse.parse se compare-t-il à cgi.parse ?

0 votes

Urlparse.parse ne fonctionne pas (au moins sur Python 2.7). Vous devez utiliser urlparse.urlparse

53voto

Navin Points 935

Solution Python 3.4+ :

from urllib.parse import unquote, urlparse
from pathlib import PurePosixPath

url = 'http://www.example.com/hithere/something/else'

PurePosixPath(
    unquote(
        urlparse(
            url
        ).path
    )
).parts[1]

# returns 'hithere' (the same for the URL with parameters)

# parts holds ('/', 'hithere', 'something', 'else')
#               0    1          2            3

26voto

Iwan Aucamp Points 385

La meilleure option est d'utiliser le posixpath lorsque vous travaillez avec le composant "chemin" des URL. Ce module a la même interface que os.path et fonctionne de manière cohérente sur les chemins POSIX lorsqu'il est utilisé sur des plateformes basées sur POSIX et Windows NT.


Code échantillon :

#!/usr/bin/env python3

import urllib.parse
import sys
import posixpath
import ntpath
import json

def path_parse( path_string, *, normalize = True, module = posixpath ):
    result = []
    if normalize:
        tmp = module.normpath( path_string )
    else:
        tmp = path_string
    while tmp != "/":
        ( tmp, item ) = module.split( tmp )
        result.insert( 0, item )
    return result

def dump_array( array ):
    string = "[ "
    for index, item in enumerate( array ):
        if index > 0:
            string += ", "
        string += "\"{}\"".format( item )
    string += " ]"
    return string

def test_url( url, *, normalize = True, module = posixpath ):
    url_parsed = urllib.parse.urlparse( url )
    path_parsed = path_parse( urllib.parse.unquote( url_parsed.path ),
        normalize=normalize, module=module )
    sys.stdout.write( "{}\n  --[n={},m={}]-->\n    {}\n".format( 
        url, normalize, module.__name__, dump_array( path_parsed ) ) )

test_url( "http://eg.com/hithere/something/else" )
test_url( "http://eg.com/hithere/something/else/" )
test_url( "http://eg.com/hithere/something/else/", normalize = False )
test_url( "http://eg.com/hithere/../else" )
test_url( "http://eg.com/hithere/../else", normalize = False )
test_url( "http://eg.com/hithere/../../else" )
test_url( "http://eg.com/hithere/../../else", normalize = False )
test_url( "http://eg.com/hithere/something/./else" )
test_url( "http://eg.com/hithere/something/./else", normalize = False )
test_url( "http://eg.com/hithere/something/./else/./" )
test_url( "http://eg.com/hithere/something/./else/./", normalize = False )

test_url( "http://eg.com/see%5C/if%5C/this%5C/works", normalize = False )
test_url( "http://eg.com/see%5C/if%5C/this%5C/works", normalize = False,
    module = ntpath )

Sortie du code :

http://eg.com/hithere/something/else
  --[n=True,m=posixpath]-->
    [ "hithere", "something", "else" ]
http://eg.com/hithere/something/else/
  --[n=True,m=posixpath]-->
    [ "hithere", "something", "else" ]
http://eg.com/hithere/something/else/
  --[n=False,m=posixpath]-->
    [ "hithere", "something", "else", "" ]
http://eg.com/hithere/../else
  --[n=True,m=posixpath]-->
    [ "else" ]
http://eg.com/hithere/../else
  --[n=False,m=posixpath]-->
    [ "hithere", "..", "else" ]
http://eg.com/hithere/../../else
  --[n=True,m=posixpath]-->
    [ "else" ]
http://eg.com/hithere/../../else
  --[n=False,m=posixpath]-->
    [ "hithere", "..", "..", "else" ]
http://eg.com/hithere/something/./else
  --[n=True,m=posixpath]-->
    [ "hithere", "something", "else" ]
http://eg.com/hithere/something/./else
  --[n=False,m=posixpath]-->
    [ "hithere", "something", ".", "else" ]
http://eg.com/hithere/something/./else/./
  --[n=True,m=posixpath]-->
    [ "hithere", "something", "else" ]
http://eg.com/hithere/something/./else/./
  --[n=False,m=posixpath]-->
    [ "hithere", "something", ".", "else", ".", "" ]
http://eg.com/see%5C/if%5C/this%5C/works
  --[n=False,m=posixpath]-->
    [ "see\", "if\", "this\", "works" ]
http://eg.com/see%5C/if%5C/this%5C/works
  --[n=False,m=ntpath]-->
    [ "see", "if", "this", "works" ]

Notes :

  • Sur les plates-formes basées sur Windows NT os.path es ntpath
  • Sur les plateformes basées sur Unix/Posix os.path es posixpath
  • ntpath ne traitera pas les antislashs ( \ ) correctement (voir les deux derniers cas dans le code/sortie) - ce qui est la raison pour laquelle posixpath est recommandé.
  • n'oubliez pas d'utiliser urllib.parse.unquote
  • envisager d'utiliser posixpath.normpath
  • La sémantique des séparateurs de chemins multiples ( / ) n'est pas défini par RFC 3986 . Cependant, posixpath fusionne plusieurs séparateurs de chemins adjacents (c'est-à-dire qu'il traite /// , // y / la même chose)
  • Même si les chemins POSIX et URL ont une syntaxe et une sémantique similaires, ils ne sont pas identiques.

Références normatives :

10voto

iamaziz Points 49

Remarque : dans Python3, import a été remplacé par from urllib.parse import urlparse Voir documentation . Voici un exemple :

>>> from urllib.parse import urlparse
>>> url = 's3://bucket.test/my/file/directory'
>>> p = urlparse(url)
>>> p
ParseResult(scheme='s3', netloc='bucket.test', path='/my/file/directory', params='', query='', fragment='')
>>> p.scheme
's3'
>>> p.netloc
'bucket.test'
>>> p.path
'/my/file/directory'

3voto

import urlparse

output = urlparse.urlparse('http://www.example.com/temp/something/happen/index.html').path

output

'/temp/something/happen/index.html'

Split the path -- inbuilt rpartition func of string 

output.rpartition('/')[0]

'/temp/something/happen'

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X