Regex para extraer las URL de los atributos href en HTML con Python

Posible duplicado:
¿Cuál es la mejor expresión regular para verificar si una cadena es una URL válida?

Teniendo en cuenta una cadena de la siguiente manera:

string = "

Hello World

More ExamplesEven More Examples"

¿Cómo podría yo, con Python, extraer las URL, dentro del href de la etiqueta de anclaje? Algo como:

 >>> url = getURLs(string) >>> url ['http://example.com', 'http://example2.com'] 

¡Gracias!

 import re url = '

Hello World

More ExamplesEven More Examples' urls = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url) >>> print urls ['http://example.com', 'http://example2.com']

La mejor respuesta es …

No use un regex

La expresión en la respuesta aceptada pierde muchos casos. Entre otras cosas, las URL pueden tener caracteres Unicode en ellas . La expresión regular que desea está aquí , y después de mirarla, puede concluir que, después de todo, no la quiere realmente. La versión más correcta es de diez mil caracteres .

Es cierto que si comenzara con un texto simple y no estructurado con un montón de URL en él, es posible que necesite esa expresión regular de diez mil caracteres. Pero si su entrada es estructurada, use la estructura . Tu objective declarado es “extraer la url, dentro del href de la etiqueta de anclaje”. ¿Por qué usar una expresión regular de diez mil caracteres cuando puedes hacer algo mucho más simple?

Analizar el HTML en su lugar

Para muchas tareas, usar Beautiful Soup será mucho más rápido y fácil de usar:

 >>> from bs4 import BeautifulSoup as Soup >>> html = Soup(s, 'html.parser') # Soup(s, 'lxml') if lxml is installed >>> [a['href'] for a in html.find_all('a')] ['http://example.com', 'http://example2.com'] 

Si prefiere no utilizar herramientas externas, también puede usar directamente la propia biblioteca de análisis HTML incorporada de Python. Aquí hay una subclase realmente simple de HTMLParser que hace exactamente lo que quieres:

 from html.parser import HTMLParser class MyParser(HTMLParser): def __init__(self, output_list=None): HTMLParser.__init__(self) if output_list is None: self.output_list = [] else: self.output_list = output_list def handle_starttag(self, tag, attrs): if tag == 'a': self.output_list.append(dict(attrs).get('href')) 

Prueba:

 >>> p = MyParser() >>> p.feed(s) >>> p.output_list ['http://example.com', 'http://example2.com'] 

Incluso podría crear un nuevo método que acepte una cadena, llame al feed y devuelva output_list . Esta es una forma mucho más poderosa y extensible que las expresiones regulares para extraer información de html.