2

私は次のようなhtmlを持っています:

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body bgcolor="white">

<h1>foo.c</h1>

<form method="post" action=""
        enctype="application/x-www-form-urlencoded">
  Compare this file to the similar file: 
  <select name="file2">

    <option value="...">...</option>


  </select>
  <input type="hidden" name="file1" value="foo.c" /><br>
  Show the results in this format: 
</form>
<hr>

<p>
<pre>
some code
</pre>

input name='file'の値とHTMLpretagの内容を取得する必要があります。私はperl言語について知りません、グーグルでこの小さなプログラムを書きました(私は「エレガント」ではないと信じています):

#!/usr/bin/perl

package MyParser;
use base qw(HTML::Parser);

#Store the file name and contents obtaind from HTML Tags
my($filename, $file_contents);

#This value is set at start() calls
#and use in text() routine..
my($g_tagname, $g_attr);


#Process tag itself and its attributes
sub start {
    my ($self, $tagname, $attr, $attrseq, $origtext) = @_;

    $g_tagname = $tagname;
    $g_attr = $attr;
}

#Process HTML tag body
sub text {
    my ($self, $text) = @_;

    #Gets the filename
    if($g_tagname eq "input" and $g_attr->{'name'} eq "file1") {
    $filename = $attr->{'value'};
    }

    #Gets the filecontents
    if($g_tagname eq "pre") {
    $file_contents = $text;
    }
}

package main;

#read $filename file contents and returns
#note: it works only for text/plain files.
sub read_file {
    my($filename) = @_;
    open FILE, $filename or die $!;
    my ($buf, $data, $n);
    while((read FILE, $data, 256) != 0) {
    $buf .= $data;
    }
    return ($buf);
}


my $curr_filename = $ARGV[0];
my $curr_file_contents = read_file($curr_filename);

my $parser = MyParser->new;
$parser->parse($curr_file_contents);

print "filename: ",$filename,"file contents: ",$file_contents;

次に、を呼び出しますが、変数./foo.pl html.htmlから空の値を取得しています。$filename$file_contents

これを修正する方法は?

4

3 に答える 3

6

いつものように、それを行うには複数の方法があります。このタスクにMojoliciousのDOMパーサーを使用する方法は次のとおりです。

#!/usr/bin/env perl

use strict;
use warnings;
use Mojo::DOM;

# slurp all lines at once into the DOM parser
my $dom = Mojo::DOM->new(do { local $/; <> });

print $dom->at('input[name=file1]')->attr('value');
print $dom->at('pre')->text;

出力:

foo.c
some code
于 2012-11-18T10:12:50.507 に答える
5

HTML::TreeBuilder :: XPath モジュールの使用Perl(非常に数行):

#!/usr/bin/env perl
use strict; use warnings;
use HTML::TreeBuilder::XPath;

my $tree = HTML::TreeBuilder::XPath->new_from_content( <> );
print $tree->findvalue( '//input[@name="file1"]/@value' );
print $tree->findvalue( '//pre/text()' );

利用方法

./script.pl file.html

出力

foo.c
some code

ノート

  • HTML::TreeBuilder以前は、モジュールを使用してWebスクレイピングを行っていました。今、私は複雑さに戻ることはできません。便利なXpathHTML::TreeBuilder::XPathを使ってすべての魔法を実行します。
  • の代わりにメソッドを使用new_from_fileしてファイルまたはファイルハンドルを開くことができます。 (からメソッドを継承する)new_from_contentを参照してください。perldoc HTML::TreeBuilderHTML::TreeBuilder::XPathHTML::TreeBuilder
  • 特にこの方法で複数の行を読み取ることができるため、この方法での使用<>はここで許可されます。HTML::TreeBuilder::new_from_content()ほとんどのコンストラクターは、この使用を許可しません。代わりにスカラーを提供するか、別の方法を使用する必要があります。
于 2012-11-18T07:58:21.470 に答える
4

独自の解析モジュールを作成している場合や、一般的にトリッキーなことをしている場合を除いて、通常、プレーンなHTML::Parserは使用しません。この場合、 HTML ::ParserのサブクラスであるHTML::TreeBuilderが最も使いやすいです。

また、HTML :: Parserにはparse_fileメソッドがあることに注意してください(そしてHTML :: TreeBuilderはメソッドを使用するとさらに簡単になるため、このビジネスnew_from_fileのすべてを行う必要はありません(さらに、それを行うには、read_fileあなたが選んだもの、File::Slurpそして古いdo { local $/; <$handle> }トリックを含みます。

use HTML::TreeBuilder;

my $filename = $ARGV[0];
my $tree = HTML::TreeBuilder->new_from_file($filename);

my $filename = $tree->look_down(
    _tag => 'input',
    type => 'hidden',
    name => 'file1'
)->attr('value');

my $file_contents = $tree->look_down(_tag => 'pre')->as_trimmed_text;

print "filename: ",$filename,"file contents: ",$file_contents;

、、、およびについてはlook_downHTML::Elementのドキュメントを参照してください。HTML :: TreeBuilderはどちらも要素であり、要素と連携します。attras_trimmed_text

于 2012-11-18T06:45:42.630 に答える