我已经了解了正则表达式无法充分解析html之前的困难方法,然后才发布帖子。
我正在尝试从位于表格中的网页中提取未读取的PM。它是页面上唯一被请求的表,因此该部分很好。 每行是关于PM的一组列。 TR的类通知未读/读PM。 - 抓住我的是什么。
我尝试使用HTML :: TableExtract,几乎完美地工作,除了我无法弄清楚如何检查TR元素。
示例表结构:
<table>
<tr class="header">
<td></td>
<td>Subject</td>
<td>Sender</td>
<td>Date</td>
</tr>
<tr class="unread">
<td>checkbox for multi-edit stuff</td>
<td>Example of an unread PM</td>
<td>Me</td>
<td>Jul 30, 2011</td>
</tr>
<tr class="read">
....
</tr>
</table>
使用HTML :: TableExtract我能够获得除未读/读类之外的所有内容。 像这样:
$t = HTML::TableExtract->new(keep_html);
$t->parse($lwp_data);
foreach $t2 ($t->tables) {
foreach $row ($t2->rows) {
#Can't find a way to search for <tr class="unread". As
#Attribute data is stripped at this point by HTML::TableExtract
#This now shows EVERY PM in the list
print join(',', @$row), "\n";
}
}
我怎样才能解析出来,只获得带有class =“unread”的TR?
搜索导致过于复杂的答案或答案,但并未完全解决我的问题。
这是我用来获得我想要的最新方法(而且正在工作,我只是想知道如何更好地做到这一点):
while ($page =~ m/(unreadpm.*?\/tr)/sg) {
$data = $1;
if ($data =~ m(value="(\d+)".*?<a href="(inbox.php\?action=viewconv&id=\d+)">(.*?)</a>\n</strong>\s+</td>\n\s+<td>(.*?)</td>)sg) {
my ($id,$link,$subject,$user) = ($1, $2, $3, $4);
if ($user =~ m(user\.php\?id=\d+">(.*?)</a>)) {
$user = $1;
}
if (grep $_ eq $id, @ids) {
print "Message ID: $id already listed\n"
} else {
print "Emailing - Subject: $subject by $user. ID: $id Link: $link ...";
send_email($subject,$user,$link);
print "done.\n";
push @ids, $id;
}
}
}
答案 0 :(得分:1)
我可以推荐HTML::TreeBuilder与XML::LibXML一起完成这项工作。
my $tree = HTML::TreeBuilder->new_from_content( $html );
my $xml = $tree->as_XML;
my $doc = XML::LibXML->load_xml(string => $xml);
然后,您可以使用findvalue使用XPath表达式查找<tr>
个节点。
使用HTML::Selector::XPath,您甚至可以使用CSS选择器转到<tr>
。
答案 1 :(得分:-1)
如果我理解了这个问题,那么我会做一些事情:
@html_lines = (use curl or otherwise to retrieve the html)
$GET_LINE = 0;
foreach $line (@html_lines)
{
if ($line =~ /\<tr class="unread"\>/)
{
$GET_LINE = 1;
next;
}
if ( ($line =~ |\</tr\>|) && ($GET_LINE) )
{
$GET_LINE = 0;
next;
}
if ($GET_LINE)
{
#process the <td> lines
}
}
注意:我不保证语法是正确的,但你得到了图片......