Add the product to cart using WWW::Mechanize - Perl - perl

I'm writing a script that selects a size and adds the product to cart here is where it is
http://store.nike.com/us/en_us/pd/free-4-flyknit-running-shoe/pid-1064825/pgid-1481072
use WWW::Mechanize::Firefox;
$mech = WWW::Mechanize::Firefox->new();
my $tconike = "http://store.nike.com/us/en_us/pd/free-4-flyknit-running-shoe/pid-1064825/pgid-1481072";
$mech->get($tconike);
print $mech->uri();
$mech->submit_form(
form_number=> 2,
fields => {
skuAndSize => $shoesize,
click => "ADD TO CART",
}
);
But here is the output
Uncaught exception from user code:
No form found to submit. at nikecartstandalone.pl line 25
at C:/Users/Brett/Documents/brett/Perl/perl/site/lib/WWW/Mechanize/Firefox.pm l
ine 2162
WWW::Mechanize::Firefox::signal_condition('WWW::Mechanize::Firefox=HASH(
0x2a54888)', 'No form found to submit.') called at C:/Users/Brett/Documents/bret
t/Perl/perl/site/lib/WWW/Mechanize/Firefox.pm line 3649
WWW::Mechanize::Firefox::submit_form('WWW::Mechanize::Firefox=HASH(0x2a5
4888)', 'form_number', 2, 'fields', 'HASH(0x3501328)') called at nikecartstandal
one.pl line 25
Anyone know what I did wrong, is it because I should have used something besisdes submit_form or is it something else?

As the error says it's not able to find the form, so try submitting form with with_fields where you can specify the fields which are there in the form you are going to submit, that'll be easier to search and submit.
Eg: $mech->form_with_fields('username');
will select the form that contain a field named username.

Related

Can't call method "header" on an undefined value at WWW/Mechanize.pm line 2566

I am just doing a testing using WWW::Mechanize module on Facebook, when I try to run the code below, it return me an error
Can't call method "header" on an undefined value at C:/Strawberry/perl/vendor/lib/WWW/Mechanize.pm line 2566.
#!/usr/bin/perl -w
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
# Connect to server
$mech->get( "https://www.facebook.com" );
$mech->success or die $mech->response->status_line;
# Log into server
$mech->field('email', 'xxx#xxx.com');
$mech->field('pass', 'xxxxxxx');
$mech->click_button(value => 'Log In');
Your page is opening in some other language other than English. That's why you are getting that error. If you will open the page in English forcefully then the error will disappear. Try below address:
$mech->get( "https://en-gb.facebook.com/" );
or, you may click directly on instance of HTML::Form::SubmitInput obtained using this:
$mech->current_form()->find_input( undef, 'submit');
or, as there is only one click button in the form you can use click with no arguments.
$mech->click()
or as suggested by #Borodin you can directly use(as the email and password field aren't translated):
$mech->submit_form( with_fields => {
email => 'xxx#xxx.com',
pass => 'xxxxxxx'
}
);

WWW::Mechanize follows a second redirect after six seconds

I am using Perl with the WWW::Mechanize module to submit a form to a webpage and save the result to a file. I know how to submit forms and save the data, but I can't save data after this six-second redirection.
After the form is submitted, the page is redirected to a page that says
Results should appear in this window in approximately 6 seconds...
and it is redirected again to the page with the result I want. My script can follow the first redirection, but not the second, and there is no link says something like "click here if not redirected".
Here is my script
use WWW::Mechanize;
my $mech = WWW::Mechanize->new(autocheck => 1);
$mech->get( "http://tempest.wellesley.edu/~btjaden/TargetRNA2/index.html");
$result = $mech->submit_form(
form_number => 1,
fields => {
text => 'Escherichia coli str. K-12 substr. MG1655',
sequence => '>RyhB' . "\n" .
'GCGATCAGGAAGACCCTCGCGGAGAACCTGAAAGCACGACATTGCTCACATTGCTTCCAGTATTACTTAGCCAGCCGGGTGCTGGCTTTT',
}
);
$mech->save_content(result);
What you need to do is extract the redirect URL and ran it manually:
Try this:
use WWW::Mechanize;
my $mech = WWW::Mechanize->new( autocheck => 1 );
$mech->get( "http://tempest.wellesley.edu/~btjaden/TargetRNA2/index.html");
$result = $mech->submit_form(
form_number => 1,
fields =>
{
text => 'Escherichia coli str. K-12 substr. MG1655',
sequence => '>RyhB GCGATCAGGAAGACCCTCGCGGAGAACCTGAAAGCACGACATTGCTCACATTGCTTCCAGTATTACTTAGCCAGCCGGGTGCTGGCTTTT',
}
);
my $content = $mech->content;
my $url1 = 'http://tempest.wellesley.edu/~btjaden/cgi-bin/';
my ($url2) = $content =~ /URL=(targetRNA2\.cgi?.+)?">/;
$mech->get($url1.$url2);
$mech->save_content(result);
WWW::Mechanize and meta refresh
Does the "6 seconds" contain something line the line below? [You may use save_content method of WWW::Machenize to save page to file]
<meta http-equiv="refresh" content="5; url=http://example.com/">
YES=>
Take a look at sources of WWW::Mechanize::Plugin::FollowMetaRedirect.
It shows how WWW::Mechanize may follow meta refresh with redirect.
It may quite likely solve your problem.

How to assign Action to a Button in perl cgi?

So I have a button in my CGI Perl. On clicking that button I need to assign a action in perl CGI, on clicking that button a New text-area should open with specified width in the same page with a submit button. Please help me on how I can proceed. Here is the code which is not really working for me. On clicking on submit button, I what to email the message to a email id
Here I print the button
print button('email',"email me","reqts()");
Here is the opentextarea subroutine
sub reqts {
print "<p><em>Enter your Message here</em><br>";
print textarea(-name=>'Comments',
-rows=>10,
-columns=>50);
print submit('Action','Send');
}
On clicking this button the subroutine is not getting called.
This button is on a html form in another subroutine
sub actions {
print
start_html(),
start_form(-action => 'com.pl'),
submit(-name => 'submit', -value => 'View com.pl'),
end_form,
print button('email',"email me","reqts()"), # this is the button
start_form(-action => 'about.pl'),
submit(-name => 'submit', -value => 'About Us');
end_form,
end_html;
}
The onClick attribute (the third argument to button) should be a JavaScript function, not Perl function. You should study how CGI and webpages work.

WWW::Mechanize get content from page

I've used WWW::Mechanize to login to the site.
Now that we are logged in, I want to make WWW::Mechanize script go to payments.php and then find the active user subscription (for example VIP Access) (class: <p class="description">).
From this I want to then read what that is, then select the correct action. For example if users package states VIP Small then print PKG: VIP Small and if users package states VIP Full then print PKG: VIP Full.
Does anyone know of a way to do this? Code used so far (being coded in my Ubuntu virtual machine):
#!/usr/bin/perl
use WWW::Mechanize;
my $forum = "http://localhost/forums/forum.php";
print "Username\r\n";
my $username = <>;
chomp($username);
print "Password\r\n";
my $password = <>;
# do login
my $mech = WWW::Mechanize->new(agentcheck => 1, agent => 'Perl WWW::Mechanize');
$mech->get($forum);
$mech->submit_form(form_number => 1, fields => { vb_login_username => $username, vb_login_password = $password });
print "this far";
$mech->follow_link(text => "Click here if your browser does not automatically redirect you.");
I think you need
$mech->get('http://localhost/forums/payments.php');
but I cannot help you get information from there without seeing the HTML of the page.
You need to parse result HTML file. I recommend to use HTML::TreeBuilder::XPath for such tasks:
my $tree = HTML::TreeBuilder::XPath->new_from_content( $mech->content() );
my ($description) = $tree->findvalues('//p[ #class = "description" ]');

WWW::Mechanize text field issue

I'm trying to submit a form by post method using WWW::Mechanize perl module.
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
...
$mech->get($url);
...
my $response = $mech->submit_form(
form_name => $name,
fields => {
$field_name => $field_value
},
button => 'Button'
);
$field_name is generally speaking a text field (though the type is not specified explicitly in the form), which has a preset value.
$field_name => $field_value in $mech->submit_form on whatever reason does not replace the value, instead $field_value is added into the form after the original value:
{submitted_field_value} = {original_value},{provided_value}
How to replace {original_value} with {provided_value} in the form to be submitted ?
What happens if you add this single line to your code before calling $mech->submit_form():
$mech->field( $name, [$field_value], 1 );
This makes sure that the first value is added, or overwritten if it already exists.
1 is the number parameter (or position index)
See the documentation of WWW::Mechanize:
$mech->field( $name, \#values, $number )
Given the name of a field, set its value to the value specified. [...]
The optional $number parameter is used to distinguish between two
fields with the same name. The fields are numbered from 1.
It's important to remember WWW::Mechanize is better thought of as a 'headless browser' as opposed to say LWP or curl, which only handle all the fiddly bits of http requests for you. Mech keeps its state as you do things.
You'll need to get the form by using $mech->forms or something similar (its best to decide from the documentation. I mean there so many ways to do it.), and then set the input field you want to change, using the field methods.
I guess the basic way to do this comes out as so:
$mech->form_name($name);
$mech->field($field_name, $field_value);
my $response = $mech->click('Button');
Should work. I believe it will also work if you get the field and directly use that (ie my $field = $mech->form_name($name); then use $field methods instead of $mech.
I managed to make it working at my will. Thanks Timbus and knb for your suggestions. Though my case may not be completely general (I know the preset value) but I'd share what I've found (by trails & errors).
my $mech = WWW::Mechanize->new();
$mech->get($url);
$mech->form_name( $name );
my $fields = $mech->form_name($name);
foreach my $k ( #{$fields->{inputs}}){
if ($k->{value} eq $default_value){
$k->{value}=$field_value;
}
}
my $response = $mech->click('Button_name');