Grep и извлечение данных в Perl

У меня есть HTML-контент, хранящийся в переменной. Как мне извлечь данные, которые находятся между набором общих тегов на странице? Например, меня интересуют данные (представленные DATA, хранящиеся между набором тегов, одна строка за другой:

...
<td class="jumlah">*DATA_1*</td>
<td class="ud"><a href="">*DATA_2*</a></td>
...

И затем я хотел бы сохранить отображение DATA_2 => DATA_1 в хеше


person syker    schedule 21.05.2010    source источник


Ответы (4)


Поскольку это HTML, вам, вероятно, понадобится модуль XPath, созданный для работы с HTML, HTML :: TreeBuilder :: XPath.

Сначала вам нужно проанализировать вашу строку с помощью методов HTML :: TreeBuilder. Предполагая, что содержимое вашей веб-страницы находится в переменной с именем $content, сделайте это следующим образом:

my $tree = HTML::TreeBuilder->new;
$tree->parse_file($file_name);

Теперь вы можете использовать выражения XPath для получения итераторов по интересующим вас узлам. Это первое выражение получает все td узлы, которые находятся в tr в table в body в элементе html:

my $tdNodes = $tree->findnodes('/html/body/table/tr/td');

Наконец, вы можете просто перебрать все узлы в цикле, чтобы найти то, что вам нужно:

foreach my $node ($tdNodes->get_nodelist) {
  my $data = $node->findvalue('.'); // the content of the node
  print "$data\n";
}

См. Документацию HTML :: TreeBuilder. для получения дополнительной информации о его методах и NodeSet документация по использованию объекта результата NodeSet. У w3schools есть сносное руководство по XPath, которое можно найти здесь.

При всем этом у вас должна быть возможность выполнять довольно надежный синтаксический анализ HTML, чтобы извлечь любой элемент, который вы хотите. Вы даже можете указать классы, идентификаторы и многое другое в своих запросах XPath, чтобы точно определить, какие узлы вам нужны. На мой взгляд, анализ HTML с использованием этой модифицированной библиотеки XPath намного быстрее и удобнее в обслуживании, чем работа с кучей одноразовых регулярных выражений.

person jasonmp85    schedule 21.05.2010

Поскольку это HTML, я думаю, это сработает для вас?

https://metacpan.org/pod/XML::XPath

XPath - это способ.

person dierre    schedule 21.05.2010
comment
Разве XPATH не ограничен XML (и, следовательно, только XHTML)? У меня очень ограниченный опыт работы с ним, но я никогда не видел, чтобы он использовался для обработки не-X HTML. - person DVK; 22.05.2010
comment
@DVK: Я бы не стал отказываться от модуля XPath, разработанного на Perl, чтобы быть немного умнее. - person Axeman; 22.05.2010
comment
Я всегда использовал библиотеку HTML :: TreeBuilder :: XPath при использовании XPath для запроса HTML-документов (search.cpan.org/~mirod/HTML-TreeBuilder-XPath-0.11/lib/HTML/). Насколько я могу судить, он был довольно надежным (с его помощью я извлек десятки тысяч офисов с определенных сайтов). - person jasonmp85; 22.05.2010
comment
Я хотел связать вам HTML :: TreeBuilder :: XPath, но я ошибся при копировании ссылки из Google. Мне жаль. - person dierre; 22.05.2010

Используйте модули синтаксического анализа HTML, как описано в ответах на этот вопрос - HTML :: TreeBuilder или HTML :: Parser.

Чисто теоретически вы можете попробовать сделать это с помощью регулярных выражений, чтобы сделать это, но, как отмечалось в ответах на связанный вопрос и бесчисленное количество раз на SO, синтаксический анализ HTML с помощью RegEx - плохая идея с заглавными буквами - слишком легко ошибиться, слишком сложно получить Что ж, и невозможно получить стопроцентное право, поскольку HTML не является обычным языком.

person DVK    schedule 21.05.2010
comment
Это может быть теоретически невозможно - HTML не является обычным языком. Если его запрос будет регулярным, это будет возможно. - person Paul Nathan; 22.05.2010

Вы можете попробовать этот модуль: HTML::TreeBuilder::XPath. В документе говорится:

Этот модуль добавляет в HTML :: TreeBuilder типичные методы XPath, чтобы упростить запрос документа.

person Axeman    schedule 21.05.2010