Regex pour extraire les URLs de l'attribut href en HTML avec Python [dupliquer]

Double 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 de caractères 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 urls, à l'intérieur des href de la balise d'ancrage? Quelque chose comme:

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

Merci!

74
demandé sur Al Sweigart 2011-07-30 16:16:49

2 réponses

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']
166
répondu JohnJohnGa 2018-03-18 09:54:08

La meilleure réponse est...

N'utilisez pas de regex

l'expression accepted answer passe à côté de nombreux cas. Entre autres choses, URLs peuvent avoir des caractères unicode dans eux . La regex que vous voulez est ici , et après l'avoir regardé, vous pouvez conclure que vous ne voulez pas vraiment, après tout. La version la plus correcte est de dix mille caractères .

Certes, si vous commenciez avec un texte simple et non structuré avec un tas D'URLs dedans, alors vous pourriez avoir besoin de ce regex 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 de la balise d'ancrage href."Pourquoi utiliser un regex de dix mille caractères quand on peut faire quelque chose de beaucoup plus simple?

Parser le HTML au lieu de

pour de nombreuses tâches, en utilisant belle soupe sera beaucoup plus rapide et plus 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 HTML 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'))

Test:

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

Vous pourriez même créer un nouveau méthode qui accepte une chaîne de caractères, appelle feed , et retourne output_list . C'est un moyen beaucoup plus puissant et extensible que les expressions régulières pour extraire des informations de html.

35
répondu senderle 2018-02-19 16:39:34