Pregunta ¿Cómo obtener la extensión de archivo de forma segura desde una URL?


Considere las siguientes URL

http://m3u.com/tunein.m3u
http://asxsomeurl.com/listen.asx:8024
http://www.plssomeotherurl.com/station.pls?id=111
http://22.198.133.16:8024

¿Cuál es la forma correcta de determinar las extensiones de archivo (.m3u / .asx / .pls)? Obviamente, el último no tiene una extensión de archivo.

EDIT: olvidé mencionar que m3u / asx / pls son listas de reproducción (archivos de texto) para transmisiones de audio y deben analizarse de manera diferente. El objetivo determina la extensión y luego envía la url a la función de análisis adecuada. P.ej.


url = argv[1]
ext = GetExtension(url)
if ext == "pls":
  realurl = ParsePLS(url)
elif ext == "asx":
  realurl = ParseASX(url)
(etc.)
else:
  realurl = url
Play(realurl)


15
2018-01-23 22:15


origen


Respuestas:


los real La forma correcta es no usar extensiones de archivos. Realice una solicitud GET (o HEAD) a la URL en cuestión y use el encabezado HTTP "Content-type" para obtener el tipo de contenido. Las extensiones de archivo no son confiables.

Ver Referencia multimedia MIME para obtener una lista de tipos MIME útiles.


11
2018-01-23 22:21



Utilizar urlparse para analizar el camino de la URL, luego os.path.splitext para obtener la extensión

import urlparse, os

url = 'http://www.plssomeotherurl.com/station.pls?id=111'
path = urlparse.urlparse(url).path
ext = os.path.splitext(path)[1]

Tenga en cuenta que la extensión puede no ser un indicador confiable del tipo de archivo. El HTTP Content-Type encabezado puede ser mejor.


35
2018-01-23 22:22



Esto es más fácil con requests y mimetypes:

import requests
import mimetypes

response = requests.get(url)
content_type = response.headers['content-type']
extension = mimetypes.guess_extension(content_type)

La extensión incluye un prefijo de punto. Por ejemplo, extension es '.png' para el tipo de contenido 'image/png'.


11
2018-02-17 18:15



Las extensiones de archivo son básicamente insignificantes en las URL. Por ejemplo, si vas a http://code.google.com/p/unladen-swallow/source/browse/branches/release-2009Q1-maint/Lib/psyco/support.py?r=292 ¿Quieres que la extensión sea ".py" a pesar del hecho de que la página es HTML, no Python?

Use el encabezado Content-Type para determinar el "tipo" de una URL.


6
2018-01-23 22:22



$ python3
Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from os.path import splitext
>>> from urllib.parse import urlparse 
>>> 
>>> urls = [
...     'http://m3u.com/tunein.m3u',
...     'http://asxsomeurl.com/listen.asx:8024',
...     'http://www.plssomeotherurl.com/station.pls?id=111',
...     'http://22.198.133.16:8024',
... ]
>>> 
>>> for url in urls:
...     path = urlparse(url).path
...     ext = splitext(path)[1]
...     print(ext)
... 
.m3u
.asx:8024
.pls

>>> 

3
2018-01-23 22:35



Para obtener el tipo de contenido puede escribir una función como la que he escrito usando urllib2. Si necesita utilizar el contenido de la página de todos modos, es probable que use urllib2, por lo que no es necesario importar el sistema operativo.

import urllib2

def getContentType(pageUrl):
    page = urllib2.urlopen(pageUrl)
    pageHeaders = page.headers
    contentType = pageHeaders.getheader('content-type')
    return contentType

2
2018-03-16 09:31



Use urlparse, que obtendrá la mayoría de los anteriores:

http://docs.python.org/library/urlparse.html

luego divide el "camino" hacia arriba. Es posible que pueda dividir la ruta usando os.path.split, pero su ejemplo 2 con: 8024 en el extremo necesita un manejo manual. ¿Son sus extensiones de archivo siempre tres letras? ¿O siempre letras y números? Usa una expresión regular.


0
2018-01-23 22:21



puedes probar el rfc6266 módulo como:

import requests
import rfc6266

req = requests.head(downloadLink)
headersContent = req.headers['Content-Disposition']
rfcFilename = rfc6266.parse_headers(headersContent, relaxed=True).filename_unsafe
filename = requests.utils.unquote(rfcFilename)

0
2018-05-11 05:49



Un enfoque diferente que no tiene en cuenta nada más, excepto la extensión de archivo real de una url:

def fileExt( url ):
    # compile regular expressions
    reQuery = re.compile( r'\?.*$', re.IGNORECASE )
    rePort = re.compile( r':[0-9]+', re.IGNORECASE )
    reExt = re.compile( r'(\.[A-Za-z0-9]+$)', re.IGNORECASE )

    # remove query string
    url = reQuery.sub( "", url )

    # remove port
    url = rePort.sub( "", url )

    # extract extension
    matches = reExt.search( url )
    if None != matches:
        return matches.group( 1 )
    return None

editar: manejo adicional de puertos explícitos desde: 1234


0
2018-06-25 13:34