Получение значения атрибутов href во всех тегах <a> в html-файле с помощью Python

Я создаю приложение на python, и мне нужно получить URL всех ссылок на одной веб-странице. У меня уже есть функция, которая использует urllib для загрузки html-файла из Интернета и преобразования его в список строк с readlines ().

В настоящее время у меня есть этот код, который использует regex (я не очень хорош в этом) для поиска ссылок в каждой строке:

for line in lines: result = re.match ('/href="(.*)"/iU', line) print result 

Это не работает, поскольку он печатает только «None» для каждой строки в файле, но я уверен, что по крайней мере есть 3 ссылки на файл, который я открываю.

Может кто-нибудь дать мне намек на это?

заранее спасибо

7 Solutions collect form web for “Получение значения атрибутов href во всех тегах <a> в html-файле с помощью Python”

Красивый суп может сделать это почти тривиально:

 from BeautifulSoup import BeautifulSoup as soup html = soup('<body><a href="123">qwe</a><a href="456">asd</a></body>') print [tag.attrMap['href'] for tag in html.findAll('a', {'href': True})] 

Другой альтернативой BeautifulSoup является lxml ( http://lxml.de/ );

 import lxml.html links = lxml.html.parse("http://stackoverflow.com/").xpath("//a/@href") for link in links: print link 

В Python есть стандартный парсер HTML. Оформить заказ htmllib .

Как уже упоминалось ранее: regex не имеет возможности анализировать HTML. Не используйте регулярное выражение для анализа HTML. Не проходите мимо. Не собирайте 200 фунтов.

Используйте парсер HTML.

Но для полноты основной проблемой является:

 re.match ('/href="(.*)"/iU', line) 

Вы не используете синтаксис «/…/flags» для украшения регулярных выражений в Python. Вместо этого поставьте флаги в отдельный аргумент:

 re.match('href="(.*)"', line, re.I|re.U) 

Еще одна проблема – это жадный шаблон «. *». Если у вас есть два hrefs в строке, он будет счастливо всасывать весь контент между открытием «первого совпадения и закрытием» второго совпадения. Вы можете использовать не-жадные '. *?' или, проще говоря, «[^»] * ', чтобы соответствовать только первой закрывающей цитате.

Но не используйте регулярные выражения для синтаксического анализа HTML. В самом деле.

То, что другие не сказали вам, заключается в том, что использование регулярных выражений для этого не является надежным решением.
Использование регулярного выражения даст вам неправильные результаты во многих ситуациях: если есть теги <A>, которые закомментированы, или если на странице есть текст, содержащий строку «href =», или если есть элементы <textarea> с html-код в нем и многие другие. Кроме того, атрибут href может существовать в тегах, других, которые привязывают тег.

Для этого вам понадобится XPath , который является языком запросов для DOM-деревьев, т. Е. Позволяет получить любой набор узлов, удовлетворяющих заданным вами условиям (атрибуты HTML являются узлами в DOM).
XPath – это хорошо зарекомендовавший себя язык в течение нескольких дней ( W3C ), и он хорошо поддерживается всеми основными языками. Я настоятельно рекомендую вам использовать XPath, а не regexp для этого.
Ответ adw показывает один пример использования XPath для вашего конкретного случая.

Не разделяйте содержимое html на строки, так как в одной строке может быть несколько совпадений. Также не предполагайте, что всегда есть котировки вокруг URL-адреса.

Сделайте что-то вроде этого:

 links = re.finditer(' href="?([^\s^"]+)', content) for link in links: print link 

Ну, просто для полноты я добавлю здесь то, что я нашел лучшим ответом, и нашел его в книге «Dive Into Python» от Марка Пилигрима.

Здесь следует код для отображения всех URL-адресов с веб-страницы:

 from sgmllib import SGMLParser class URLLister(SGMLParser): def reset(self): SGMLParser.reset(self) self.urls = [] def start_a(self, attrs): href = [v for k, v in attrs if k=='href'] if href: self.urls.extend(href) import urllib, urllister usock = urllib.urlopen("http://diveintopython.net/") parser = urllister.URLLister() parser.feed(usock.read()) usock.close() parser.close() for url in parser.urls: print url 

Спасибо за все отклики.

  • Регулярное выражение Python для извлечения части строки
  • Анализ худших случаев для регулярных выражений
  • Красивый суп, если класс «Содержит» или «Регулярное выражение»?
  • регулярное выражение получает номер из строки
  • Как обнаружить идентичную часть (-ы) внутри строки?
  • Лучший способ заменить \ x00 в списках python?
  • Номер телефона Регулярное выражение (Regex) в Python
  • словарь для доступа к python с подстановочными знаками
  • regex: заменить дефисы на en-dashes с re.sub
  • Как удалить текст в круглых скобках с помощью регулярного выражения?
  • Проверить допустимое доменное имя в строке?
  • Python - лучший язык программирования в мире.