我正在尝试从结构完美的网页中提取相当多的数据,并在Mojo::DOM
方法上苦苦挣扎。如果有人能指出我正确的方向,我将不胜感激。
带有有趣数据的截断 HTML 如下:
<div class="post" data-story-id="3964117" data-visited="false">//extracting story-id
<h2 class="post_title page_title"><a href="http://example.com/story/some_url" class="to-comments">header.</a></h2>
//useless data and tags
<a href="http://example.com/story/some_url" class="b-story__show-all">
<span>useless data</span>
</a>
<div class="post_tags">
<ul>
<li class="post_tag post_tag_strawberry hidden"><a href="http://example.com/search.php?n=32&r=3"> </a></li>
<li class="post_tag"><a href="http://example.com/tag/tag1/hot">tag1</a></li>
<li class="post_tag"><a href="http://example.com/tag/tag2/hot">tag2</a></li>
<li class="post_tag"><a href="http://example.com/tag/tag1/hot">tag3</a></li>
</ul>
</div>
<div class="post_actions_box">
<div class="post_rating_box">
<ul data-story-id="3964117" data-vote="0" data-can-vote="true">
<li><span class="post_rating post_rating_up control"> </span></li>
<li><span class="post_rating_count control label">1956</span></li> //1956 - interesting value
<li><span class="post_rating post_rating_down control"> </span></li>
</ul>
</div>
<div class="post_more_box">
<ul>
<li>
<span class="post_more control"> </span>
</li>
<li>
<a class="post_comments_count label to-comments" href="http://example.com/story/some_url#comments">132 <i> </i></a>
</li>
</ul>
</div>
</div>
</div>
我现在拥有的是
use strict;
use warnings;
use Data::Dumper;
use Mojo::DOM;
my $file = "index2.html";
local( $/, *FH ) ;
open( FH, $file ) or die "sudden flaming deathn";
my $text = <FH>;
my $dom = Mojo::DOM->new;
$dom->parse($text);
my $ids = $dom->find('div.post')
->each (sub {print $_->attr('data-story-id'), "n";});
$dom->find('a.to-comments')->each (sub {print $_->text, "n";});
这个混乱从 src 和标头值中提取data-story-id
(使用 href 值测试相同(,但我所有其他尝试都失败了。
3964117
Header
132
不提取"post_rating_count控件标签"。我可以通过搜索a.to-comments
并返回attr('href')
来获取第一个 href 值,但由于某种原因,它还在带有 class="post_comments_count label to-comments"
的段末尾返回链接的值。标头值提取也会发生同样的情况。
最后,我正在寻找一个具有以下字段的数据结构的数组:
- 故事ID(这是一个成功(
- href(不知何故,匹配的比需要的多。
- 标头(不知何故,匹配的比需要的更多。
- 字符串形式的标签列表(不知道该怎么做(
更重要的是,我觉得可以优化代码并使其看起来更好一点,但我的功夫没有那么强。
正如我在评论中所说,您的HTML格式不正确。我已经猜到了失踪的<div>
可能会去哪里,但我可能错了。我假设数据中的最后一个</div>
对应于第一个<div>
,因此整个块构成一个帖子
您遇到的主要问题是尝试在each
方法调用Mojo::Collection
对象中执行所有操作。使用 Perl 迭代每个集合要容易得多,就像这样
use strict;
use warnings;
use Mojo::DOM;
use constant HTML_FILE => 'index2.html';
my $html = do {
open my $fh, '<', HTML_FILE or die $!;
local $/;
<$fh>;
};
my $dom = Mojo::DOM->new($html);
for my $post ( $dom->find('div.post')->each ) {
printf "Post ID: %sn", $post->attr('data-story-id');
my $anchor = $post->at('h2.post_title > a');
printf "Post href: %sn", $anchor->attr('href');
printf "Post header: %sn", $anchor->text;
my @tags = $post->find('li.post_tag > a')->map('text')->each;
printf "Tags: %sn", join ', ', @tags;
print "n";
}
输出
Post ID: 3964117
Post href: http://example.com/story/some_url
Post header: Header
Tags: some_value, tag1, tag2, tag3