FriendsOfPHP / Goutte

Goutte, a simple PHP Web Scraper
MIT License
9.26k stars 1.01k forks source link

submitting forms without submit button #44

Open niepi opened 12 years ago

niepi commented 12 years ago

I'm dealing with forms without a submit button, they are submitted with a link and javascript.

My approach would be to inject a submit button and then create the form object and submit it.

So would it make sense to auto inject a submit button into a form, if you create the form based on the form tag and it does not include a submit button already?

Best

Thomas

cocomo commented 11 years ago

I have a similar issue with an ajax-based form and still haven't found a solution to work around the missing submit. Did you make it to inject a button?

ssanders commented 10 years ago
$crawler = $client->request('GET', 'http://website.com/');

$html = $crawler->html();

$html = str_replace("action=\"", "action=\"http://website.com/", $html);
$html = str_replace("</form>", "<input name='__EVENTTARGET'><input type='submit' value='x'></form>", $html);

$crawler->add($html);

$form = $crawler->selectButton('x')->form();
$crawler = $client->submit($form, array('username' => 'ssanders', 'password' => 'love', '__EVENTTARGET' -> 'UserLogin'));
stof commented 10 years ago

Try the following code:

$crawler = $client->request('GET', 'http://website.com/');

$form = $crawler->filter('form')->form();
$crawler = $client->submit($form, array('username' => 'ssanders', 'password' => 'love'));

->form() does not need to be called on the submit button. It can also be called on the form itself.

ssanders commented 10 years ago
Fatal error: Class 'Symfony\Component\DomCrawler\FormFieldRegistry' not found in phar:///mnt/web/public_html/test/goutte.phar/vendor/symfony/dom-crawler/Symfony/Component/DomCrawler/Form.php on line 395
stof commented 10 years ago

hmm, looks like your phar is broken...

ssanders commented 10 years ago

My phar is fixed, so I tried your code on a similar form with this submit code:

$crawler = $client->submit($form, array('__EVENTTARGET' => '_ctl0:Main:PageNavigatorTop:ButtonPageNext'));

But I got the following. __EVENTTARGET is there but hidden; Goutte can’t find it?

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Unreachable field "__EVENTTARGET"'
njandreasson commented 9 years ago

My phar is fixed, so I tried your code on a similar form with this submit code:

$crawler = $client->submit($form, array('__EVENTTARGET' => '_ctl0:Main:PageNavigatorTop:ButtonPageNext')); But I got the following. __EVENTTARGET is there but hidden; Goutte can’t find it?

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Unreachable field "__EVENTTAR

I just stumbled upon the same error and found a work-around I thought I could share in case someone else might need it. Instead of specifying name and value in the submit I create a new hidden field, set it on the form and then submit, like this in your case:

$domDocument = new \DOMDocument;
$domInput = $domDocument->createElement('input');
$domInput->setAttribute('name', '__EVENTTARGET');
$domInput->setAttribute('value', '_ctl0:Main:PageNavigatorTop:ButtonPageNext');

$formInput = new \Symfony\Component\DomCrawler\Field\InputFormField($domInput);
$form->set($formInput);

$crawler = $client->submit($form);
quickshiftin commented 8 years ago

@njohansson You just saved my day bro!

purinda commented 8 years ago

@njohansson very clever! was stuck with the problem for few hours. Thanks

Emmanuellut commented 6 years ago

I spent 1 days ont it! thanks @njandreasson

Emmanuellut commented 6 years ago

$domDocument = new \DOMDocument; $domInput = $domDocument->createElement('input'); $domInput->setAttribute('name', '__EVENTTARGET'); $domInput->setAttribute('value', '_ctl0:Main:PageNavigatorTop:ButtonPageNext');

$formInput = new \Symfony\Component\DomCrawler\Field\InputFormField($domInput); $form->set($formInput);

$crawler = $client->submit($form);

change by this : $domDocument = new \DOMDocument; $domInput = $domDocument->createElement('input'); $dom = $domDocument->appendChild($domInput); (Added line) $dom->setAttribute('slug', 'bloc'); ... $crawler = $client->submit($form);