Регулярное выражение для извлечения URL из HTML-ссылки

Я новичок в Python. Я изучаю регулярные выражения, но мне нужна помощь здесь.

Вот источник HTML:

<a href="#" onclick="location.href='http://www.ptop.se'; return false;" target="_blank">http://www.ptop.se</a>

Я пытаюсь закодировать инструмент, который выводит только http://ptop.se. Можете ли вы мне помочь?

Ответ 1

Если вы ищете только один:

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

Если у вас длинная строка и требуется каждый экземпляр шаблона в ней:

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

Где s - строка, в которой вы ищете совпадения.

Быстрое объяснение бит регулярного выражения:

r'...' - это "сырая" строка. Это мешает вам беспокоиться об исчезновении персонажей так же, как вы обычно. (\ особенно - в исходной строке a \ - это всего лишь \. В обычной строке вам нужно будет делать \\ каждый раз, и это становится старым в регулярных выражениях.)

"href=[\'"]?" говорит, что соответствует "href=", возможно, после ' или ". "Возможно", потому что трудно сказать, насколько ужасен HTML, на который вы смотрите, и цитаты не требуются строго.

Включение следующего бита в "()" говорит, чтобы сделать его "группой", что означает разделить его и вернуть его отдельно нам. Это просто способ сказать: "Это часть интересующего меня шаблона".

"[^\'" >]+" говорит, что соответствует любым символам, которые не являются ', ", >, или пробелом. По сути это список символов, которые являются концом URL. Это позволяет нам избежать попыток написать регулярное выражение, которое надежно соответствует полному URL-адресу, что может быть немного сложным.

Предложение в другом ответе на использование BeautifulSoup неплохо, но оно вводит более высокий уровень внешних требований. Кроме того, это не поможет вам в вашей заявленной цели обучения регулярным выражениям, которые я бы предположил, что этот конкретный проект html-parsing является лишь частью.

Это довольно легко сделать:

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

Как только вы установили BeautifulSoup, в любом случае.

Ответ 2

Не используйте регулярные выражения, используйте BeautifulSoup. Это, или быть настолько жестоким, чтобы породить его, скажем, w3m/lynx и отступить в том, что делает w3m/lynx. Во-первых, это более элегантно, во-вторых, он просто работал намного быстрее на некотором неоптимизированном коде, который я написал некоторое время назад.

Ответ 3

это должно сработать, хотя могут быть более элегантные способы.

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

Ответ 4

Джон Грубер (который написал Markdown, который составлен из регулярных выражений и используется прямо здесь, в Stack Overflow), попытался создать регулярное выражение, которое распознает URL-адреса в тексте:

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

Если вы просто хотите захватить URL-адрес (т.е. вы действительно не пытаетесь разобрать HTML-код), это может быть более легким, чем парсер HTML.

Ответ 5

Regexes в корне плохи при разборе HTML (см. Можете ли вы привести несколько примеров того, почему трудно анализировать XML и HTML с регулярным выражением? для чего). Вам нужен парсер HTML. См. Можете ли вы привести пример анализа HTML с вашим любимым парсером? для примеров с использованием различных парсеров.

В частности, вы захотите посмотреть ответы Python: BeautifulSoup, HTMLParser и LXML.

Ответ 6

Там тонны из них на regexlib

Ответ 7

Да, их много на regexlib. Это только доказывает, что RE не следует использовать для этого. Используйте SGMLParser или BeautifulSoup или напишите парсер, но не используйте RE. Те, которые, кажется, работают, чрезвычайно усложняются и по-прежнему не охватывают все случаи.

Ответ 8

Это очень хорошо работает с использованием необязательных совпадений (отпечатки после href=) и получает только ссылку. Протестировано на http://pythex.org/

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

Oputput:

Матч 1./wiki/Main_Page

Матч 2./wiki/Portal: Содержание

Матч 3./wiki/Portal: Featured_content

Матч 4./wiki/Portal: Current_events

Match 5./wiki/Special: Random

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

Ответ 9

это регулярное выражение может вам помочь, вы должны получить первую группу по \1 или любому другому методу, который у вас есть на вашем языке.

href="([^"]*)

Пример:

<a href="#" onclick="location.href='http://www.amghezi.com'; return false;">amgheziName</a>

результат:

http://www.amghezi.com