in reply to Re^2: Mechanize cookie jar update?
in thread Mechanize cookie jar update?

Er, did you read the POD for HTTP::Cookies? I think you'll have to clear that cookie and put it back in the right way; i.e., not as a string but as an array of elements. That said, this turns out to not be so trivial as none of the cookie modules seems to parse strings correctly...? So unless someone has something more terse, this is what I'd do-

use WWW::Mechanize; use HTTP::Cookies; my $mech = WWW::Mechanize->new(); my $cookie_jar = HTTP::Cookies->new( autosave => 1, file => "/your/cookies.txt" ); # $cookie_jar->clear(); $mech->cookie_jar($cookie_jar); $mech->agent_alias('Windows IE 6'); $mech->get("http://www.amazon.com"); my $self_enclosed_callback = sub { my ( $version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard, $extra ) = @_; # Remove the currently iterating cookie from the jar. # NB: this might be dangerous! Seems to work though. $cookie_jar->clear( $domain, $path, $key ); # Now change domain, just for example. $domain =~ s/\.com\z/.org/; $cookie_jar->set_cookie( $version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard, $extra ); }; # Before our callback. print $cookie_jar->as_string, "\n"; $cookie_jar->scan( $self_enclosed_callback ); # After our callback. print $cookie_jar->as_string, "\n";

Replies are listed 'Best First'.
Re^4: Mechanize cookie jar update?
by AV-2 (Novice) on Apr 05, 2008 at 05:00 UTC
    It is quite interesting what the module does internally. Let's add Data::Dumper to see it:
    use Data::Dumper; (...) # Before our callback. print $cookie_jar->as_string, "\n"; print Dumper(\%{$cookie_jar}); $cookie_jar->scan( $self_enclosed_callback ); # After our callback. print $cookie_jar->as_string, "\n"; print Dumper(\%{$cookie_jar});
    When you change the domain it just copies the contents to a new hash key, empties the old one but never deletes it! Anyway, something more related to the problem. The module doesn't provide a lot of methods for modifying the cookies, so any other solution would require to mess directly with the hash. It would be straightforward to test all cookies and change a value, although not so much to change, say, a domain name.
    use WWW::Mechanize; use HTTP::Cookies; use Data::Dumper; my $mech = WWW::Mechanize->new(); my $cookie_jar = HTTP::Cookies->new( autosave => 1, file => "/your/cookies.txt" ); # $cookie_jar->clear(); $mech->cookie_jar($cookie_jar); $mech->agent_alias('Windows IE 6'); $mech->get("http://www.amazon.com"); my $self_enclosed_callback = sub { my ( $version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard, $extra ) = @_; # Remove the currently iterating cookie from the jar. # NB: this might be dangerous! Seems to work though. $cookie_jar->clear( $domain, $path, $key ); # Now change domain, just for example. $domain =~ s/\.com\z/.org/; $cookie_jar->set_cookie( $version, $key, $val, $path, $domain, $port, $path_spec, $secure, $expires, $discard, $extra ); }; # Original state. print $cookie_jar->as_string, "\n"; #First solution. foreach my $site (map( values(%{$_}), map( values(%{$_}),values %{$cookie_jar->{'COO +KIES'}}) )) { $site->[1] =~ s/no/yes/; $site->[1] =~ s/\d+/time/; $site->[1] =~ s/\d+/blarf/g; } print $cookie_jar->as_string, "\n"; #Second solution. my $cookies = $cookie_jar->{'COOKIES'}; foreach my $site (keys %{$cookies}) { foreach my $path (keys %{$cookies->{$site}}) { foreach my $value (keys %{$cookies->{$site}{$path}}) { $cookies->{$site}{$path}{$value}[1] =~ s/time-blarf-blarf/$sit +e/; $cookies->{$site}{$path}{$value}[1] =~ s/.*l/$path/; $cookies->{$site}{$path}{$value}[1] =~ s/yesskin/$value/g; } } } print $cookie_jar->as_string, "\n";
    The first solution would behave as you expected your code that prints with as_string and then re-inserts the cookie to behave. The second one provides you with the site, path and name of the cookie, at the cost of three nested loops. I think there is a solution in the middle of those two, more fancy and without so many nested functions, or loops, but I will leave that to the next poster. :)
Re^4: Mechanize cookie jar update?
by Anonymous Monk on Apr 07, 2008 at 13:34 UTC
    This works but every time I perform a get it retrieves the set of cookies from the browser...but I assume this is how it should perform correct?

      Yep, if I follow you. HTTP is stateless so the cookies generally go back and forth every time.