Perl的WWW ::机械化 - 解析HTML为基础的报告

问题描述:

我有downlaods一个网页,然后脚本解析下来到 这样Perl的WWW ::机械化 - 解析HTML为基础的报告

<A HREF="wonk?IssuePage&SolutionId=8&RecordId=20193&Template=view&TableId=1023"><B>26165</B></A> 
<A HREF="wonk?IssuePage&SolutionId=8&RecordId=22163&Template=view&TableId=1023"><B>29327</B></A> 
<A HREF="wonk?IssuePage&SolutionId=8&RecordId=22216&Template=view&TableId=1023"><B>29416</B></A> 
<A HREF="wonk?IssuePage&SolutionId=8&RecordId=22238&Template=view&TableId=1023"><B>29450</B></A> 

的URL列表我进一步剥离下来,票网址加载到阵列@url_list然后提取从他们的一些信息

#!/usr/bin/perl 
use WWW::Mechanize; 
use LWP; 

my $username = 'casper'; 
my $password = 'casper'; 

my $mech = WWW::Mechanize->new(); 
$mech->cookie_jar(HTTP::Cookies->new()); 
$mech->get('http://ticketmaster/wonk.dll?ReportPage&Template=reports%2Flist&TableId=1023&Target=Query&QueryName=-6&SolutionId=8') || die "can't reach the website $!"; 
$mech->form_name('theform'); 
$mech->field('ttAuthUID' => $username); 
$mech->field('ttAuthPWD' => $password); 
$mech->click('Action'); 

print $mech->save_content(raw_teamtrack); 

open(my $webpage, "<", "raw_teamtrack") || die "cannot open up the out file $!"; 

while (<$webpage>) { 
    chomp; 
    $link = $_; 
    if ($link =~ /<A HREF=\"(wonk.dll\?IssuePage&SolutionId=8&RecordId.*)"/) { 
    push(@url_list, $1); 
    } 
} 

foreach $url (@url_list) { 
    use WWW::Mechanize; 
    use LWP; 
    my $username = 'casper'; 
    my $password = 'casper'; 

    my $mech = WWW::Mechanize->new(); 
    $mech->cookie_jar(HTTP::Cookies->new()); 
    $mech->get("http://ticketmaster/$url") 
     || die "cannot load the ticket page $!"; 
    $mech->form_name('theform'); 
    $mech->field('ttAuthUID' => $username); 
    $mech->field('ttAuthPWD' => $password); 
    $mech->click('Action'); 
    print $mech->save_content(raw_ticket); 
    open(my $ticketpage, "<", "raw_ticket") 
     || die "cannot open up the out file $!"; 

    while (<$ticketpage>) { 
    chomp; 
    if (/<B>Item\sId:\s+?<\/B>(\d{5})/) { 
     $Item_number = $1; 
    } 
    elsif (/<B>Owner:\s<\/B>(.*)<BR>/) { 
     $Owner = $1; 
    } 
    else { 
     $ticket_title =~ /<B>Title:\s<\/B>(.*)/; 
     print "$Item_number $Owner $ticket_title\n"; 
     sleep 1; 
    } 
    } 
} 

的问题是,它打印出仅项目编号和所有者字段;它不打印出票的标题。

此外,它会为每次迭代打印出一次信息 - 对于下载的票证中的每个HTML行。

这种情况一直发生在我身上:我通常必须将循环移出括号。这解决了它,但从基本的角度来看,我不明白为什么把它移到循环的外面可以修复它。为什么现在要打印出每一行HTML?

我也不明白为什么$owner不能打印出来。 else有什么问题吗?我应该使用另一个if声明吗?

26165 George Glass 
26165 George Glass 
26165 George Glass 
26165 George Glass 
26165 George Glass 
26165 George Glass 
26165 George Glass 
26165 George Glass 
29327 George Glass 
29327 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29450 Jimmy Jack 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 
29753 Herley Lee 

正则表达式很好。

bash-3.00$ cat /tmp/raw_ticket | perl -nle 'print /<B>Item\sId:\s+?<\/B>(\d{5})/' | sort -u 
29871 

bash-3.00$ cat /tmp/raw_ticket | perl -nle 'print /<B>Owner:\s<\/B>(.*)<BR>/' | sort -u 
Jimmy Jack 
bash-3.00$ 

bash-3.00$ cat /tmp/raw_ticket | perl -nle 'print /<B>Title:\s<\/B>(.*)/' | sort -u 
Trade Capture Prod Shadow - Install software on ushs2 - 11/15/13 
bash-3.00$ 

我不能追加,我试图打破在这里,因为它是HTML和未格式化请this pastebucket的HTML代码。

+0

没有看到您正在处理的确切输入,这很难提供帮助。在上一个代码块中,您使用文件测试了正则表达式;请发布该文件的内容,而不是一堆可能与您的真实问题无关的WWW :: Mechanize代码。如果你创建一个简单的,独立的例子,它将更容易调试,并且你可能会得到更快的答案(如果你没有在流程中找到它)。 – ThisSuitIsBlackNot

+1

我已经整理好了你的Perl代码,使它更具可读性,但请在程序开始时添加'use strict'和'use warnings',并修复从中得到的错误。当你没有使用Perl提供的基本工具时,期待他人的帮助是不公平的。 – Borodin

+0

您已经在'for'循环中复制了很多代码,包括'use'语句以及设置用户名和密码变量。应该清楚的是,这不需要多做一次,而且你的方法看起来更像猜测而非清晰的想法。 – Borodin

我怀疑它与if语句的模式匹配以及分配变量$ 1(代码中最后一个正则表达式检查/赋值错误)的方式。以下是一个例子的测试数据(所以票证标题至少要打印出来,不知道没有一组URL的循环)。

所以我会匹配这样的...

use strict; 
use warnings; # always use these at top 

....

my $Item_number; 
my $Owner; 
my $ticket_title; 

while (<$webpage>) { 
    my $line = $_; 
    chomp; 
    $line =~ /<B>Item\sId:\s+?<\/B>(\d{5})/ and $Item_number = $1; 
    $line =~ /<B>Owner:\s<\/B>(.*)<BR>/ and $Owner = $1; 
    $line =~ /<B>Title:\s<\/B>(.*)/ and $ticket_title = $1; 
} 
print "$Item_number $Owner $ticket_title\n"; 

有一个在代码中的很多其他问题,而只是试图孤立,我怀疑问题是。当你只做一个正则表达式来测试时,它会正常工作,所以正则表达式可以单独使用。当你将多个正则表达式依次组合时,它是不一致的。

为了阐明它的工作方式,'和'就像是一个快捷方式,因此只有在这种情况下正则表达式为真时才会执行赋值。

+0

嘿 - 谢谢这真的是我正在寻找 - 建议更好的形式。 – capser