парсинг большого html-файла (локального) - с помощью Perl или PHP - PullRequest
0 голосов
/ 02 декабря 2010

У меня большой документ - мне нужно разобрать его и выложить только эту часть: schule.php? Schulnr = 80287 & lschb =

как мне разобрать вещи!?

<td>
    <A HREF="schule.php?schulnr=80287&lschb=" target="_blank">
        <center><img border=0 height=16 width=15 src="sh_info.gif"></center>
    </A>
</td>

Рад тебя слышать

Ответы [ 4 ]

5 голосов
/ 02 декабря 2010

В Perl самый быстрый и лучший способ, который я знаю, сканировать HTML - это HTML::PullParser.Это основано на надежном синтаксическом анализаторе HTML, а не на простом FSA, подобном регулярному выражению Perl (без рекурсии).

Это больше похоже на фильтр SAX, чем на DOM.

use 5.010;
use constant NOT_FOUND => -1;
use strict;
use warnings;

use English qw<$OS_ERROR>;
use HTML::PullParser ();

my $pp 
    = HTML::PullParser->new(
      # your file or even a handle
      file        => 'my.html'
      # specifies that you want a tuple of tagname, attribute hash
    , start       => 'tag, attr' 
      # you only want to look at tags with tagname = 'a'
    , report_tags => [ 'a' ],
    ) 
    or die "$OS_ERROR"
    ;

my $anchor_url;
while ( defined( my $t = $pp->get_token )) { 
    next unless ref $t or $t->[0] ne 'a'; # this shouldn't happen, really
    my $href = $t->[1]->{href};
    if ( index( $href, 'schule.php?' ) > NOT_FOUND ) { 
        $anchor_url = $href;
        last;
    }
}
5 голосов
/ 02 декабря 2010

Вам следует использовать синтаксический анализатор DOM, например PHP Simple HTML DOM Parser

// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');

// Find all links 
foreach($html->find('a') as $element) 
       echo $element->href . '<br>';
4 голосов
/ 02 декабря 2010

То, что сказал Rfvgyhn, но во вкусе Perl, поскольку это был один из тегов: используйте HTML :: TreeBuilder

Кроме того, по причинам, объясняющим, почему RegEx почти никогда не является хорошей идеей для анализа XML / HTML (иногда это достаточно хорошо с серьезными предостережениями), прочитайте обязательную и позорную статью StackOverflow:

RegEx соответствует открытым тегам, кроме автономных тегов XHTML

Имейте в виду, если весь объем вашей задачи буквально "разбирает ссылки HREF", И у вас нет тегов "" И ссылки (например, HREF="something" подстроки) гарантированно не будут использоваться в любом другом контексте (например, в комментариях, или в виде текста, или если «HREF =» является частью самой ссылки), он может просто попасть в категорию «Достаточно хорошо» выше для использования регулярных выражений:

my @lines = <>; # Replace with proper method of reading in your file
my @hrefs = map { $_ =~ /href="([^"]+)"/gi; } @lines;
3 голосов
/ 02 декабря 2010

Вы также можете сделать это следующим образом (это не perl, а более «визуально»):

  • Загрузите документ в браузер, если это возможно
  • Установите расширение Firebug / добавьте-on
  • Установить расширение FirePath
  • Скопировать + вставить это выражение XPath в текстовое поле, помеченное «XPpath:»

    // a [содержит (@href,"schule")] / @ href

  • Нажмите кнопку "Eval".

В командной строке также есть инструменты,например, "xmllint" (для unix)

xmllint --html --xpath '//a[contains(@href, "schule")]/@href' myfile.php.or.html

Вы можете выполнить дальнейшую обработку оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...