web-dev-qa-db-fra.com

Expression régulière pour extraire l'URL d'un lien HTML

Je suis un débutant en Python. J'apprends les expressions rationnelles, mais j'ai besoin d'aide ici.

Voici la source HTML:

<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a>

J'essaie de coder un outil qui imprime uniquement http://ptop.se. Pouvez-vous m'aider s'il vous plaît?

31
IFake

Si vous n'en cherchez qu'un:

import re
match = re.search(r'href=[\'"]?([^\'" >]+)', s)
if match:
    print match.group(0)

Si vous avez une longue chaîne et que vous voulez chaque instance du modèle:

import re
urls = re.findall(r'href=[\'"]?([^\'" >]+)', s)
print ', '.join(urls)

s est la chaîne dans laquelle vous recherchez correspond.

Explication rapide des bits d'expressions rationnelles:

r'...' est une chaîne "brute". Cela vous évite d'avoir à vous soucier d'échapper aux personnages autant que vous le feriez normalement. (\ en particulier - dans une chaîne brute, un \ est simplement un \. Dans une chaîne normale, vous devez faire \\ à chaque fois, et cela devient old in regexps.)

"href=[\'"]?" dit de faire correspondre "href =", éventuellement suivi d'un ' ou d'un ". "Peut-être" parce qu'il est difficile de dire à quel point le code HTML que vous consultez est horrible, et les guillemets ne sont pas strictement obligatoires.

Enfermer le bit suivant dans "()", on veut en faire un "groupe", ce qui signifie le scinder et le renvoyer séparément. C'est juste une façon de dire "c'est la partie du motif qui m'intéresse".

"[^\'" >]+" dit de faire correspondre tous les caractères qui ne sont pas ', ", > ou un espace. Il s'agit essentiellement d'une liste de caractères constituant une fin à l'URL. Cela nous évite d’essayer d’écrire une expression rationnelle qui corresponde de manière fiable à une URL complète, ce qui peut être un peu compliqué.

La suggestion dans une autre réponse d’utiliser BeautifulSoup n’est pas mauvaise, mais elle introduit un niveau plus élevé d’exigences externes. De plus, cela ne vous aide pas dans votre objectif déclaré d’apprendre les expressions rationnelles, ce dont je suppose que ce projet d’analyse HTML spécifique n’est qu’une partie.

C'est assez facile à faire:

from BeautifulSoup import BeautifulSoup
soup = BeautifulSoup(html_to_parse)
for tag in soup.findAll('a', href=True):
    print tag['href']

Une fois que vous avez installé BeautifulSoup, en tout cas.

66
David

N'utilisez pas de regex, utilisez BeautifulSoup . Cela, ou être assez cruel pour le faire apparaître, disons, w3m/lynx et retirer ce que w3m/lynx rend. La première est probablement plus élégante, la deuxième vient de travailler énormément plus rapidement sur du code non optimisé que j'ai écrit il y a quelque temps.

13
JosefAssad

cela devrait fonctionner, bien qu'il puisse y avoir des manières plus élégantes.

import re
url='<a href="http://www.ptop.se" target="_blank">http://www.ptop.se</a>'
r = re.compile('(?<=href=").*?(?=")')
r.findall(url)
11
jannis

John Gruber (qui a écrit Markdown, qui est composé d'expressions régulières et est utilisé ici même dans Stack Overflow) a essayé de produire une expression régulière qui reconnaît les URL dans le texte:

http://daringfireball.net/2009/11/liberal_regex_for_matching_urls

Si vous souhaitez simplement récupérer l’URL (c’est-à-dire que vous n’essayez pas vraiment d’analyser le code HTML), cette opération est peut-être plus légère qu’un analyseur HTML.

10
Paul D. Waite

Les expressions rationnelles sont fondamentalement mauvaises pour l’analyse HTML (voir Pouvez-vous donner quelques exemples des raisons pour lesquelles il est difficile d’analyser XML et HTML avec une expression régulière? pour pourquoi). Ce dont vous avez besoin, c'est d'un analyseur HTML. Voir Pouvez-vous donner un exemple d'analyse HTML avec votre analyseur préféré? pour des exemples utilisant divers analyseurs.

En particulier, vous voudrez vous pencher sur les réponses Python: BeautifulSoup , HTMLParser et lxml .

4
Chas. Owens

Oui, il y en a des tonnes sur regexlib . Cela prouve seulement que les ER ne devraient pas être utilisées pour le faire. Utilisez SGMLParser ou BeautifulSoup ou écrivez un analyseur - mais n'utilisez pas d'ER. Ceux qui semblent fonctionner sont extrêmement compliqués et ne couvrent toujours pas tous les cas.

1
Jarek

Il y en a des tonnes sur regexlib

1
Chris S

Cela fonctionne assez bien avec l'utilisation de correspondances facultatives (imprime après href=) et obtient uniquement le lien. Testé sur http://pythex.org/

(?:href=['"])([:/.A-z?<_&\s=>0-9;-]+)

Oputput:

Match 1./wiki/Main_Page

Match 2./wiki/Portal: Contenu

Match 3./wiki/Portal: Featured_content

Match 4./wiki/Portal: Evénements en cours

Match 5./wiki/Special: Aléatoire

Match 6. //donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate&utm_medium=sidebar&utm_campaign=C13_en.wikipedia.org&uselang=en

1
Rohit Malgaonkar

Vous pouvez utiliser ceci.

<a[^>]+href=["'](.*?)["']
0
arjan

cette regex peut vous aider, vous devriez obtenir le premier groupe par\1 ou quelle que soit la méthode que vous avez dans votre langue.

href="([^"]*)

exemple:

<a href="http://www.amghezi.com">amgheziName</a>

résultat:

http://www.amghezi.com
0
Hamedz