【问题标题】:Getting html content between specific <div> tag only仅在特定 <div> 标记之间获取 html 内容
【发布时间】:2012-12-20 00:23:12
【问题描述】:

我编写了以下代码来抓取 &lt;div id=aaa-bbb&gt; 和下一个 &lt;/div&gt; 标记之间的文本内容,但它只打印出整个 HTML 源代码。

use LWP::Simple;

$url = 'http://domain.com/?xxxxxxx';

my $content = get($url);

$data =~ m/<div id="aaa-bbb">(.*?)<\/div>/g;

if (is_success(getprint($url))) {
    print $_;
 }

# or using the following line directly without if statement
print $data;

我感兴趣的 HTML 片段如下所示:

<div id="aaa-bbb">
<p>text text text text text text text text text</p><p>text text text</p>
</div>

特定的div 标记ID 在整个HTML 文档中只出现一次。

我还希望去除 &lt;p&gt;&lt;/p&gt; 标记或通过换行符整理输出,以便以后存储为文本文件或重复使用。

在阅读了您宝贵的 cmets 后,我尝试使用 WWW::MechanizeWWW::Mechanize::TreeBuilder 相反,像这样

use strict;
use warnings;

use WWW::Mechanize; 
use WWW::Mechanize::TreeBuilder; 

my $mech = WWW::Mechanize->new; 
WWW::Mechanize::TreeBuilder->meta->apply($mech); 

$mech->get( 'domain.com/?xxxxxx' ); 

my @list = $mech->find('div id="aaa-bbb"'); # or <div id="aaa-bbb"> or "<div id="aaa-bbb">"
foreach (@list) { 
  print $_->as_text(); 
} 

它适用于简单的标签,但不能让它与&lt;div id="aaaa"&gt; 一起使用。它只是退出脚本而不打印任何内容。我使用了双引号和单引号,标签 id 中已经有双引号了。

【问题讨论】:

  • 不要为此使用正则表达式。获取一个 HTML 解析器(例如 HTML::TreeBuilder::XPath)。
  • 现在是 2013 年。使用 XML 解析器。
  • 你认为$data =~ m/&lt;div id="aaa-bbb"&gt;(.*?)&lt;\/div&gt;/g;在做什么?
  • 它是 HTML,不要使用 XML 解析器(除非它有 HTML 解析模式)。
  • htmlparsing.com/perl.html 提供了如何使用 Perl 正确解析 HTML 的示例。 htmlparsing.com/regexes.html 解释了为什么正则表达式是个坏主意。

标签: perl html-parsing


【解决方案1】:

这种类型的解析使用 DOM 解析器要容易得多。我选择的解析器是Mojo::DOM,它是Mojolicious 套件的一部分。

#!/usr/bin/env perl

use strict;
use warnings;

use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new;

my $dom = $ua->get( 'domain.com/?xxxxxx' )->res->dom; 

my $text = $dom->at('#aaa-bbb')->all_text;

at 方法是find 方法的特例,它查找所有实例; at 找到第一个(或仅在您的情况下)。 # 是 id 的 CSS 选择器语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2019-09-21
    • 1970-01-01
    • 2023-03-14
    • 2019-11-10
    相关资源
    最近更新 更多