Как я могу извлечь URL-адрес и текст ссылки из HTML в Perl?

Ранее я спрашивал, как это сделать в Groovy. Однако сейчас я переписываю свое приложение на Perl из-за наличия всех библиотек CPAN.

Если на странице были эти ссылки:

<a href = "http://www.google.com">Google</a>

<a href = "http://www.apple.com">Apple</a>

Результатом будет:

Google, http://www.google.com
Apple, http://www.apple.com

Как лучше всего это сделать в Perl?

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
20
0
31 474
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Взгляните на HTML :: LinkExtractor и HTML :: LinkExtor, часть пакета HTML :: Парсер.

HTML :: LinkExtractor похож на HTML :: LinkExtor, за исключением того, что помимо получения URL-адреса вы также получаете текст ссылки.

К сожалению, HTML :: LinkExtor не может предоставить вам текст внутри тега <a>, который, по его словам, его интересует. Он сообщает вам только имя тега и его атрибуты.

cjm 31.10.2008 22:39

@cjm: я добавил ссылку на HTML :: LinkExtractor, которая создает текст ссылки в дополнение к URL-адресам.

Yaakov Belch 25.05.2014 14:56

HTML - это структурированный язык разметки, который необходимо анализировать, чтобы без ошибок извлекать его значение. Указанный модуль Sherm проанализирует HTML и извлечет ссылки за вас. Специальные решения на основе регулярных выражений могут быть приемлемыми, если вы знаете, что ваши входные данные всегда будут формироваться одинаково (не забывайте атрибуты), но синтаксический анализатор почти всегда является правильным ответом для обработки структурированного текста.

Мне нравится использовать pQuery для таких вещей ...

use pQuery;

pQuery( 'http://www.perlbuzz.com' )->find( 'a' )->each(
    sub {
        say $_->innerHTML . q{, } . $_->getAttribute( 'href' );
    }
);

Также ознакомьтесь с этим предыдущим вопросом stackoverflow.com Эмуляция lex-подобной функциональности в Perl или Python для получения аналогичных ответов.

Ответ принят как подходящий

Пожалуйста, посмотрите, как использовать для этого модуль WWW :: Mechanize. Он будет загружать ваши веб-страницы за вас, а затем упрощает работу со списками URL-адресов.

my $mech = WWW::Mechanize->new();
$mech->get( $some_url );
my @links = $mech->links();
for my $link ( @links ) {
    printf "%s, %s\n", $link->text, $link->url;
}

Довольно просто, а если вы хотите перейти к другим URL-адресам на этой странице, это еще проще.

Механизм - это, по сути, браузер в объекте.

Я взял на себя смелость изменить оператор печати, включив в него текст ссылки, как того требует melling.

cjm 31.10.2008 23:05

Шерм рекомендовал HTML :: LinkExtor, что почти то, что вы хотите. К сожалению, он не может вернуть текст внутри тега <a>.

Энди рекомендуется WWW :: Mechanize. Это, наверное, лучшее решение.

Если вы обнаружите, что WWW :: Mechanize вам не нравится, попробуйте HTML :: TreeBuilder. Он построит DOM-подобное дерево из HTML, в котором вы затем сможете искать нужные ссылки и извлекать любой ближайший контент, который вам нужен.

Или подумайте о том, чтобы улучшить HTML :: LinkExtor, чтобы он делал то, что вы хотите, и отправьте изменения автору.

Другой способ сделать это - использовать XPath для запроса проанализированного HTML. Это необходимо в сложных случаях, например, при извлечении всех ссылок в div с конкретным классом. Используйте для этого HTML :: TreeBuilder :: XPath.

  my $tree=HTML::TreeBuilder::XPath->new_from_content($c);
  my $nodes=$tree->findnodes(q{//map[@name='map1']/area});
  while (my $node=$nodes->shift) {
    my $t=$node->attr('title');
  }

Также добавьте $ tree-> delete, чтобы избежать утечки памяти.

Susheel Javadi 13.01.2011 12:31

Предыдущие ответы были очень хорошими, и я знаю, что опаздываю на вечеринку, но это попало в ленту [perl], так что ...

XML :: LibXML отлично подходит для разбора HTML и непревзойден по скорости. Установите опцию recover при разборе плохо сформированного HTML.

use XML::LibXML;

my $doc = XML::LibXML->load_html(IO => \*DATA);
for my $anchor ( $doc->findnodes("//a[\@href]") )
{
    printf "%15s -> %s\n",
        $anchor->textContent,
        $anchor->getAttribute("href");
}

__DATA__
<html><head><title/></head><body>
<a href = "http://www.google.com">Google</a>
<a href = "http://www.apple.com">Apple</a>
</body></html>

–Yields–

     Google -> http://www.google.com
      Apple -> http://www.apple.com

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

#!/usr/bin/perl

if ($#ARGV < 0) {
  print "$0: Need URL argument.\n";
  exit 1;
}

my @content = split(/\n/,`wget -qO- $ARGV[0]`);
my @links = grep(/<a.*href=.*>/,@content);

foreach my $c (@links){
  $c =~ /<a.*href = "([\s\S]+?)".*>/;
  $link = $1;
  $c =~ /<a.*href.*>([\s\S]+?)</a>/;
  $title = $1;
  print "$title, $link\n";
}

Скорее всего, я сделал несколько ошибок здесь, но он работает в нескольких тестовых примерах, которые я пробовал после его написания (он не учитывает такие вещи, как теги <img> и т. д.).

ты хозяин, ты сэкономил мне много времени .. спасибо за тонну.

run 10.09.2012 11:56

Мы можем использовать регулярное выражение для извлечения ссылки с ее текстом. Это тоже один путь.

local $/ = '';
my $a = <DATA>;

while( $a =~ m/<a[^>]*?href=\"([^>]*?)\"[^>]*?>\s*([\w\W]*?)\s*</a>/igs )
{   
    print "Link:$1 \t Text: $2\n";
}


__DATA__

<a href = "http://www.google.com">Google</a>

<a href = "http://www.apple.com">Apple</a>

HTML :: LinkExtractor лучше, чем HTML :: LinkExtor

Он может давать как текст ссылки, так и URL-адрес.

Использование:

 use HTML::LinkExtractor;
 my $input = q{If <a href = "http://apple.com/"> Apple </a>}; #HTML string
 my $LX = new HTML::LinkExtractor(undef,undef,1);
 $LX->parse(\$input);
 for my $Link( @{ $LX->links } ) {
        if ( $$Link{_TEXT}=~ m/Apple/ ) {
            print "\n LinkText $$Link{_TEXT} URL $$Link{href}\n";
        }
    }

Другие вопросы по теме