Duplicate possible:
Quelle est la meilleure expression régulière pour vérifier si une chaîne est une URL valide?
Considérant une chaîne comme suit:
string = "<p>Hello World</p><a href="http://example.com">More Examples</a><a href="http://example2.com">Even More Examples</a>"
Comment pourrais-je, avec Python, extraire les URL, à l'intérieur du href de la balise anchor? Quelque chose comme:
>>> url = getURLs(string)
>>> url
['http://example.com', 'http://example2.com']
Merci!
import re
url = '<p>Hello World</p><a href="http://example.com">More Examples</a><a href="http://example2.com">Even More Examples</a>'
urls = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url)
>>> print urls
['http://example.com', 'http://example2.com']
La meilleure réponse est ...
L'expression dans le réponse acceptée manque de nombreux cas. Entre autres choses , les URL peuvent contenir des caractères unicode . La regex que vous voulez est ici , et après l'avoir examinée, vous pouvez en conclure que vous ne le voulez pas vraiment après tout. La version la plus correcte est dix mille caractères .
Certes, si vous débutiez avec du texte brut, non structuré contenant une multitude d'URL, vous pourriez avoir besoin de cette expression rationnelle longue de dix mille caractères. Mais si votre entrée est structurée, utilisez la structure . Votre objectif déclaré est "d'extraire l'URL, à l'intérieur du href de la balise d'ancrage". Pourquoi utiliser une expression rationnelle longue de dix mille caractères lorsque vous pouvez faire quelque chose de beaucoup plus simple?
Pour de nombreuses tâches, utiliser Beautiful Soup sera beaucoup plus rapide et facile à utiliser:
>>> 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 vous préférez ne pas utiliser d'outils externes, vous pouvez également utiliser directement la propre bibliothèque d'analyse HTML intégrée de Python. Voici une sous-classe très simple de HTMLParser
qui fait exactement ce que vous voulez:
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'))
Tester:
>>> p = MyParser()
>>> p.feed(s)
>>> p.output_list
['http://example.com', 'http://example2.com']
Vous pouvez même créer une nouvelle méthode qui accepte une chaîne, appelle feed
et renvoie output_list
. Il s'agit d'un moyen beaucoup plus puissant et extensible que les expressions régulières pour extraire des informations à partir de HTML.