⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form.pm

📁 1. 记录每个帖子的访问人情况
💻 PM
📖 第 1 页 / 共 2 页
字号:
package HTML::Form;use strict;use URI;use Carp ();use vars qw($VERSION);$VERSION='0.03';my %form_tags = map {$_ => 1} qw(input textarea button select option);my %type2class = ( text     => "TextInput", password => "TextInput", file     => "TextInput", hidden   => "TextInput", textarea => "TextInput", button   => "IgnoreInput", "reset"  => "IgnoreInput", radio    => "ListInput", checkbox => "ListInput", option   => "ListInput", submit   => "SubmitInput", image    => "ImageInput",);=head1 NAMEHTML::Form - Class that represents HTML forms=head1 SYNOPSIS use HTML::Form; $form = HTML::Form->parse($html, $base_uri); $form->value(query => "Perl"); use LWP; LWP::UserAgent->new->request($form->click);=head1 DESCRIPTIONObjects of the C<HTML::Form> class represents a single HTML <form>... </form> instance.  A form consist of a sequence of inputs thatusually have names, and which can take on various values.The following methods are available:=over 4=item $form = HTML::Form->new($method, $action_uri, [[$enctype], $input,...])The constructor takes a $method and a $uri as argument.  The $enctypeand and initial inputs are optional.  You will normally useHTML::Form->parse() to create new HTML::Form objects.=cutsub new {    my $class = shift;    my $self = bless {}, $class;    $self->{method} = uc(shift  || "GET");    $self->{action} = shift  || Carp::croak("No action defined");    $self->{enctype} = shift || "application/x-www-form-urlencoded";    $self->{inputs} = [@_];    $self;}=item @forms = HTML::Form->parse($html_document, $base_uri)The parse() class method will parse an HTML document and build upC<HTML::Form> objects for each <form> found.  If called in scalarcontext only returns the first <form>.  Returns an empty list if thereare no forms to be found.The $base_uri is (usually) the URI used to access the $html_document.It is needed to resolve relative action URIs.  For LWP this parameteris obtained from the $response->base() method.=cutsub parse{    my($class, $html, $base_uri) = @_;    require HTML::TokeParser;    my $p = HTML::TokeParser->new(\$html);    eval {	# optimization	$p->report_tags(qw(form input textarea select optgroup option));    };    my @forms;    my $f;  # current form    while (my $t = $p->get_tag) {	my($tag,$attr) = @$t;	if ($tag eq "form") {	    my $action = delete $attr->{'action'};	    $action = "" unless defined $action;	    $action = URI->new_abs($action, $base_uri);	    $f = $class->new(delete $attr->{'method'},			     $action,			     delete $attr->{'enctype'});	    $f->{extra_attr} = $attr;	    push(@forms, $f);	    while (my $t = $p->get_tag) {		my($tag, $attr) = @$t;		last if $tag eq "/form";		if ($tag eq "input") {		    my $type = delete $attr->{type} || "text";		    $f->push_input($type, $attr);		} elsif ($tag eq "textarea") {		    $attr->{textarea_value} = $attr->{value}		        if exists $attr->{value};		    my $text = $p->get_text("/textarea");		    $attr->{value} = $text;		    $f->push_input("textarea", $attr);		} elsif ($tag eq "select") {		    $attr->{select_value} = $attr->{value}		        if exists $attr->{value};		    while ($t = $p->get_tag) {			my $tag = shift @$t;			last if $tag eq "/select";			next if $tag =~ m,/?optgroup,;			next if $tag eq "/option";			if ($tag eq "option") {			    my %a = (%$attr, %{$t->[0]});			    $a{value} = $p->get_trimmed_text				unless defined $a{value};			    $f->push_input("option", \%a);			} else {			    Carp::carp("Bad <select> tag '$tag'") if $^W;			}		    }		}	    }	} elsif ($form_tags{$tag}) {	    Carp::carp("<$tag> outside <form>") if $^W;	}    }    for (@forms) {	$_->fixup;    }    wantarray ? @forms : $forms[0];}=item $form->push_input($type, \%attr)Adds a new input to the form.=cutsub push_input{    my($self, $type, $attr) = @_;    $type = lc $type;    my $class = $type2class{$type};    unless ($class) {	Carp::carp("Unknown input type '$type'") if $^W;	$class = "IgnoreInput";    }    $class = "IgnoreInput" if exists $attr->{disabled};    $class = "HTML::Form::$class";    my $input = $class->new(type => $type, %$attr);    $input->add_to_form($self);}=item $form->method( [$new] )=item $form->action( [$new] )=item $form->enctype( [$new] )These method can be used to get/set the corresponding attribute of theform.=cutBEGIN {    # Set up some accesor    for (qw(method action enctype)) {	my $m = $_;	no strict 'refs';	*{$m} = sub {	    my $self = shift;	    my $old = $self->{$m};	    $self->{$m} = shift if @_;	    $old;	};    }    *uri = \&action;  # alias}=item $form->inputsThis method returns the list of inputs in the form.=cutsub inputs{    my $self = shift;    @{$self->{'inputs'}};}=item $form->find_input($name, $type, $no)This method is used to locate some specific input within the form.  Atleast one of the arguments must be defined.  If no matching input isfound, C<undef> is returned.If $name is specified, then the input must have the indicated name.If $type is specified then the input must have the specified type.  Inaddition to the types possible for <input> HTML tags, we also have"textarea" and "option".  The $no is the sequence number of the inputwith the indicated $name and/or $type (where 1 is the first).=cutsub find_input{    my($self, $name, $type, $no) = @_;    $no ||= 1;    for (@{$self->{'inputs'}}) {	if (defined $name) {	    next unless exists $_->{name};	    next if $name ne $_->{name};	}	next if $type && $type ne $_->{type};	next if --$no;	return $_;    }    return;}sub fixup{    my $self = shift;    for (@{$self->{'inputs'}}) {	$_->fixup;    }}=item $form->value($name, [$value])The value() method can be used to get/set the value of some input.  Ifno input have the indicated name, then this method will croak.=cutsub value{    my $self = shift;    my $key  = shift;    my $input = $self->find_input($key);    Carp::croak("No such field '$key'") unless $input;    local $Carp::CarpLevel = 1;    $input->value(@_);}=item $form->try_others(\&callback)This method will iterate over all permutations of unvisited enumeratedvalues (<select>, <radio>, <checkbox>) and invoke the callback foreach.  The callback is passed the $form as argument.=cutsub try_others{    my($self, $cb) = @_;    my @try;    for (@{$self->{'inputs'}}) {	my @not_tried_yet = $_->other_possible_values;	next unless @not_tried_yet;	push(@try, [\@not_tried_yet, $_]);    }    return unless @try;    $self->_try($cb, \@try, 0);}sub _try{    my($self, $cb, $try, $i) = @_;    for (@{$try->[$i][0]}) {	$try->[$i][1]->value($_);	&$cb($self);	$self->_try($cb, $try, $i+1) if $i+1 < @$try;    }}=item $form->make_requestWill return a HTTP::Request object that reflects the current settingof the form.  You might want to use the click method instead.=cutsub make_request{    my $self = shift;    my $method  = uc $self->{'method'};    my $uri     = $self->{'action'};    my $enctype = $self->{'enctype'};    my @form    = $self->form;    if ($method eq "GET") {	require HTTP::Request;	$uri = URI->new($uri, "http");	$uri->query_form(@form);	return HTTP::Request->new(GET => $uri);    } elsif ($method eq "POST") {	require HTTP::Request::Common;	return HTTP::Request::Common::POST($uri, \@form,					   Content_Type => $enctype);    } else {	Carp::croak("Unknown method '$method'");    }}=item $form->click([$name], [$x, $y])Will click on the first clickable input (C<input/submit> orC<input/image>), with the indicated $name, if specified.  You canoptinally specify a coordinate clicked, which only makes a differenceif you clicked on an image.  The default coordinate is (1,1).=cutsub click{    my $self = shift;    my $name;    $name = shift if (@_ % 2) == 1;  # odd number of arguments    # try to find first submit button to activate    for (@{$self->{'inputs'}}) {        next unless $_->can("click");        next if $name && $_->name ne $name;	return $_->click($self, @_);    }    Carp::croak("No clickable input with name $name") if $name;    $self->make_request;}=item $form->formReturns the current setting as a sequence of key/value pairs.=cutsub form{    my $self = shift;    map {$_->form_name_value} @{$self->{'inputs'}};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -