Получить конкретные ссылки в HTML

0

прекрасные люди. Я пытаюсь получить массив Perl файлов, к которым привязан HTML файл. Я все еще довольно новичок в Perl, и я в значительной степени не знаком с HTML, поэтому, пожалуйста, несите меня. Некоторые из файлов отмечены звездочкой (*), за пределами текста ссылки, что указывает на то, что файл регулярно обновляется. Я хочу только извлекать ссылки на файлы, которые регулярно обновляются. HTML файл выглядит следующим образом:

<tr>
    <td height="34" nowrap width="170">
    <a href="/Files/link1.pdf">Link 1</a>*</td>
</tr>

<!--
<tr>
    <td height="34" nowrap width="170">
    <a href="/Files/link2.pdf">Link 2</a>*</td>
</tr>
-->

<tr>
    <td height="34" nowrap width="170">
    <a href="/Files/link3.pdf">Link 3</a>
    *</td>
</tr>

<tr>
    <td height="34" nowrap width="170">
    <a href="/Files/link4.pdf">Link 4</a></td>
</tr>

Так что я хочу в моем массиве - это URL для ссылок 1 и 3, которые помечены как обновление звездочкой, но не 2, потому что это в комментарии, а не 4, потому что у него нет звездочки. Я попробовал следующее на основе принятого ответа на этот вопрос:

use strict;
use warnings;
use WWW::Mechanize;

my $page = "file://server/web/site.htm";

my $mech = WWW::Mechanize->new();
$mech->get($page);

my @links = $mech->links();
my @urls;

for my $lnk (@links) {
    push(@urls, $lnk->url);
}

Я все еще получаю ссылку # 2, хотя это в комментарии. Кроме того, я не знаю, где начать с только push ING в связи со звездочкой, тем более, что звездочка для связи № 3 находится на новой линии. Я изначально пробовал это с использованием регулярных выражений и без использования WWW :: Mechanize, но мне не удалось получить звездочку на следующей строке.

use strict;
use warnings;

my $html = do {
    local $/ = undef;
    open(my $fh, "<", "file") || die $!;
    <$fh>;
};

$html =~ s/(<!--)+.*(-->)+//;

my @urls = ($html =~ /\bhref[ ]?=[ ]?"([^"]+)".*\*/gc);

Это будет получать ссылки 1 и 2, но не 3. Это получает ссылки в комментариях, потому что, видимо, мое нахождение и замена regex не работает, как я ожидаю.

Итак, как мне получить только выделенные ссылки и пропустить прокомментированные? Я открыт для любых идей вообще - возможно, мой подход от выхода был неправильным. Любая помощь, понимание или направление были бы фантастическими. Большое спасибо всем вам!

  • 3
    Regex - это, вероятно, не тот путь, которым нужно ... использовать настоящий HTML-парсер .
  • 2
    Пони, это приходит ...
Показать ещё 6 комментариев
Теги:

2 ответа

2
Лучший ответ

В моем примере звездочка обозначает файл, который регулярно обновляется, и звездочки живут в тегах td. Я определил, как извлечь эти файлы, используя HTML :: TokeParser.

use strict;
use warnings;
use HTML::TokeParser;

my $html = HTML::TokeParser->new("file.html");

my @urls;

while(my $td = $html->get_tag("td")) {
    my $txt = $html->get_trimmed_text("/td");
    my $url = $html->get_tag("a")->[1]{href};
    if ($txt =~ /\*/) {
        push(@urls, $url);
    }
}

Спасибо @sabujhassan за ваше рабочее решение и спасибо @ThisSuitIsBlackNot за то, что он побудил меня к применению более общеприменимого решения.

1

Основываясь на вашем примере, он должен работать.

$html =~ s/<!--.*?-->//sg;
my @urls = ($html =~ /\bhref\s*=\s*"([^"]*)"[^>]*>[^<]*<\/a>\s*\*/sg);
## my @urls = ($html =~ /<a\s+[^>]*href\s*=\s*"([^"]*)"[^>]*>[^<]*<\/a>\s*\*/sg);
  • 2
    если текстовая ссылка содержит теги, [^<]* завершится ошибкой. Поскольку вы используете модификатор /s , вы можете заменить его на .*?
  • 1
    @sabuj hassan: Использование ваших модифицированных регулярных выражений сделало эту работу отлично. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню