如何解决Mojo::DOM - 如何从 dom 对象中解析数据集?
我在 html 结果页面中有数据,我想从中迭代解析数据集。在一般的“结果页面”格式中,有一个主结果部分(div),其中包含一堆子部分(sub divs),这些子部分又包含带有结果数据的各种标签。
Faux,pseudo,not-real code
$file = Mojo::File->new('BigData.htm'); # Read in some file
$dom = Mojo::DOM->new($file->slurp); # Slurp the dom out of it
#
$rs = $dom->at('div.resultsSection'); # Find the beginning of the results section
#
for my $ss ($rs->at('div.subSection') { # Start looping through the subsections
#
$cs = $ss->find('p.coolStuff'); # Find correlating data
$is = $ss->find('div.importantStuff'); #
#
if(! defined $is) { # Make decisions based on data availability
$is = $ss->find('div.differentClass'); # and data quality
} #
push (@array,"$cs\t$is\n"); # Reformat it for my purposes
} #
很明显,上面的假的、伪的、非真实的代码在任何意义上都是完全虚假的,除了这个: 这是我正在尝试做的事情的逻辑表示。 "->at()" 应该返回一个 dom 对象,该对象以给定标记的第一次出现开始。 “->find()”返回匹配标签的集合。我理解使用 css 选择器(和其他方法)我可以将两种方法的结果限制为唯一的项目(我确实这样做了)。然而,我的知识就止步于此。
我可以一次找到一种类型的所有标签。但数据复杂,事后无法关联结果。
我也可以抓取单个小节,并收集我需要的数据集,但我不知道如何创建遍历所有小节的循环。
我的意思是不是全错了?
解决方法
我想出了一个有效的解决方案。我不知道这是否是最好的解决方案,但它直接而简单,这当然是正确的方向。
下面的 html 段从主要的“容器”开始,包含一个搜索结果行:(我应该把它包含在我原来的问题中 - 抱歉)
<div class="container">
<div class="row searchResultRow">
<div class="col-sm-12">
<div class="row">
<div class="col-md-12">
<p class="searchResultTitle">Some Data Here</p>
</div>
</div>
<div class="row">
<div class="col-sm-7 col-md-8">
<div class="row">
<div class="col-md-2">
<div class="clearfix"> <img alt="clearfixalt" class="searchResultImg" src='/images/image.png' /> </div>
<p> <a class="bodyLink" href="description.html">View Details</a> </p>
</div>
<div class="col-sm-5 col-md-4">
<p> <span class="gridTxtLbl br-responsive-sm">Type</span> <span class="gridDataItem br-responsive-sm">Organic</span> </p>
</div>
<div class="col-sm-3 col-md-3">
<p> <span class="gridTxtLbl br-responsive-sm">Year</span> <span class="gridDataItem br-responsive-sm">1955</span> </p>
</div>
<div class="col-sm-4 col-md-3"> </div>
</div>
<div class="row">
<div class="col-md-12"> </div>
</div>
</div>
<div class="col-sm-5 col-md-4">
<p class="gridTxtLbl">Origin</p>
<div class="">
<div class="mapIconDiv">
<a href="/Maps/ShowMap" id="res_thx-1138">
<span class="iconWithText">
<span class="fa fa-home" aria-hidden="true"></span>
<br />Map
</span>
</a>
<script>
$(function() {
$('#res_' + thx-1138).click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,success: function(html) {
$('#mapModal').html(html);
$('#mapModal').modal();
initialize(40.7856211,-76.5780298,'Secret Location<br/>Lincoln County,NV','2');
}
});
});
});
</script>
</div>
<div class="searchResultAddress">
<br />Lincoln County,NV</div>
</div>
</div>
</div>
</div>
</div>
下面的代码遍历数据并抓取什么:
use Mojo::UserAgent;
use Mojo::File;
use feature 'say';
$infile = 'searchResults.htm';
unless( -e $infile ) { # Did I already save this data?
$ua = Mojo::UserAgent->new; # No? Then go get it
$tx = $ua->get( 'https://www.someurl.com/BigDataResults.html' ); # URL hardcoded here to simplify this post
unless( $tx->result->is_success ) {
die "Doh!!! ",$tx->result->code
}
$tx->result->save_to( $searchResults.htm );
}
$data = Mojo::File->new( $infile )->slurp;
$dom = Mojo::DOM->new( $data );
$c = $dom->at('div.container'); # Return the dom from the beginning of the results data section
# in my case,this "div.class" is unique
for $row ($c->find('div.searchResultRow')->compact->each) # Return a collection of each subsection (row)
{ #
$data1 = $row->at('div > div > div > div > p')->text; # Use css direct child selectors to navigate paths into nested tag structures
$data2 = $row->at('div > div > div > div > div > div > script')->text; # <-- There was some lat/long data in this script I needed to parse out
$data3 = $row->at('div > div > div > p > span')->text; # <-- More data in another nested tag structure
#
# A Lot of massaging and formatting code was here #
push (@array,"$cs\t$is\n"); # wrap up the data for later
}
这是实际运行的代码,虽然我去掉了所有干扰主逻辑的东西。
给任何试图找到此问题答案的人的说明:
- 尽管直接子选择器 ">" 就像硬编码路径,因此是一个脆弱的解决方案,但对我而言,它的优势在于长 css 选择器路径是唯一的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。